粗糙分析设计模式-原型模式

Posted Sun_TTTT

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了粗糙分析设计模式-原型模式相关的知识,希望对你有一定的参考价值。

当我们new一个单位需要消耗极大地资源或者需要重新申请权限时,我们可以用原型模式来从一个已经创建好的样板对象中复制出一个内部属性一致的对象,这个过程也就是我们俗称的“克隆”,被复制的实例就是我们所称的“原型”。
什么时候使用原型模式呢?当我们new出一个对象消耗的代价很大的时候,或者一个对象需要提供给其他调用者访问并且各个调用者都需要修改这个对象的值得时候(保护性拷贝)。
实现的方式 我们可以通过Cloneable接口实现原型模式,也可以不用Cloneable接口实现原型模式。

下面用代码说明一下深拷贝、浅拷贝。



import java.util.ArrayList;

/**
 * Created by kaileen on 2017/3/20.
 */
public class PDF implements Cloneable 
    private String mText;
    private ArrayList<String> mImages = new ArrayList<String>();

    public PDF() 
        System.out.println("PDF constructor init");
    

    @Override
    protected PDF clone() 
        try 
            PDF mPDF = (PDF) super.clone();
            mPDF.setText(mText);
            mPDF.setImages(mImages);
            return mPDF;
         catch (Exception e) 

        
        return null;
    


    public void setText(String text) 
        this.mText = text;
    

    public String getText() 
        return this.mText;
    

    public void setImages(ArrayList<String> images) 
        this.mImages = images;
    

    public ArrayList<String> getImages() 
        return this.mImages;
    

    public void addImage(String image) 
        mImages.add(image);
    

    public void showPDF() 

        System.out.println("show PDF detail");
        System.out.println("Text is : " + mText);
        for (String image : mImages) 
            System.out.println("Image is : " + image);
        
    



import org.junit.Test;

import static org.junit.Assert.*;

/**
 * Created by kaileen on 2017/3/20.
 */
public class PDFTest 

    @Test
    public void PDFTest()
        PDF mPDF = new PDF();
        mPDF.setText("java");
        mPDF.addImage("test");
        mPDF.addImage("field");
        mPDF.addImage("constructor");
        mPDF.addImage("method");
        PDF mClonePDF = mPDF.clone()
        mPDF.showPDF();
        mClonePDF.showPDF();
    

下面是执行结果:

如果我们改成下面这样:


import org.junit.Test;

import static org.junit.Assert.*;

/**
 * Created by kaileen on 2017/3/20.
 */
public class PDFTest 

    @Test
    public void PDFTest()
        PDF mPDF = new PDF();
        mPDF.setText("java");
        mPDF.addImage("test");
        mPDF.addImage("field");
        mPDF.addImage("constructor");
        mPDF.addImage("method");
        PDF mClonePDF = mPDF.clone();
        mClonePDF.addImage("clone add image");//clone 添加了一个image
        mPDF.showPDF();
        mClonePDF.showPDF();
    

执行结果:

看到最后了没,因为指向同一个地址更改了mClonePDF 的同时也更改了mPDF,这就不能忍了,用原型模式为的是啥啊是不是。所以我们把引用类型也给处理一下:



import java.util.ArrayList;

/**
 * Created by kaileen on 2017/3/20.
 */
public class PDF implements Cloneable 
    private String mText;
    private ArrayList<String> mImages = new ArrayList<String>();

    public PDF() 
        System.out.println("PDF constructor init");
    

    @Override
    protected PDF clone() 
        try 
            PDF mPDF = (PDF) super.clone();
            mPDF.setText(mText);
            mPDF.setImages((ArrayList<String>) mImages.clone());//注意这里 !!!
            return mPDF;
         catch (Exception e) 

        
        return null;
    


    public void setText(String text) 
        this.mText = text;
    

    public String getText() 
        return this.mText;
    

    public void setImages(ArrayList<String> images) 
        this.mImages = images;
    

    public ArrayList<String> getImages() 
        return this.mImages;
    

    public void addImage(String image) 
        mImages.add(image);
    

    public void showPDF() 

        System.out.println("show PDF detail");
        System.out.println("Text is : " + mText);
        for (String image : mImages) 
            System.out.println("Image is : " + image);
        
    

执行一下test看一下结果

import org.junit.Test;

import static org.junit.Assert.*;

/**
 * Created by kaileen on 2017/3/20.
 */
public class PDFTest 

    @Test
    public void PDFTest()
        PDF mPDF = new PDF();
        mPDF.setText("java");
        mPDF.addImage("test");
        mPDF.addImage("field");
        mPDF.addImage("constructor");
        mPDF.addImage("method");
        PDF mClonePDF = mPDF.clone();
        mClonePDF.addImage("clone add image");//clone 添加了一个image
        mPDF.showPDF();
        mClonePDF.showPDF();
    

下面是结果:

看看 这个是不是就不改变了啊

同时我们也注意一件事情。当用clone的时候,并没有调用constructor。注意了啊 知识点。

以上是关于粗糙分析设计模式-原型模式的主要内容,如果未能解决你的问题,请参考以下文章

Android 设计模式 笔记 - 原型模式

设计模式 -- 原型模式 图解java对象克隆 引用拷贝浅拷贝深拷贝序列化拷贝

设计模式 -- 原型模式 图解java对象克隆 引用拷贝浅拷贝深拷贝序列化拷贝

设计模式 -- 原型模式 图解java对象克隆 引用拷贝浅拷贝深拷贝序列化拷贝

设计模式 -- 原型模式 图解java对象克隆 引用拷贝浅拷贝深拷贝序列化拷贝

粗糙分析设计模式——单例模式