JAVA设计模式之原型模式

原型模式是一个创建型的模式。原型二字表明了改模式应该有一个样板实例,用户从这个样板对象中复制一个内部属性一致的对象,这个过程也就是我们称的“克隆”。被复制的实例就是我们所称的“原型”,这个原型是可定制的。原型模式多用于创建复杂的或者构造耗时的实例,因为这种情况下,复制一个已经存在的实例可使程序运行更高效。
使用场合

1.类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等,通过原型拷贝避免这些消耗。
2.通过new产生的一个对象需要非常繁琐的数据准备或者权限,这时可以使用原型模式。
3.一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用,即保护性拷贝。
进行使用:
1.客户(Client)角色,客户类提出创建对象的请求。
2.抽象原型(Prototype)角色,这是一个抽象角色,通常有一个JAVA接口或JAVA抽象实现。此角色给出所有的具体原型类所需的接口。
3.具体原型(Concrete Prototype)角色:被复制的对象,此角色需要实现抽象原型所需的接口。
浅克隆和深克隆
在浅克隆中,如果原型对象的成员变量是值类型(八大基本类byte,short,int,long,char,double,float,boolean).那么就直接复制,如果是复杂的类型,(枚举,String,对象)就只复制对应的地址。
深克隆,我就不用多说了吧,就是什么都是单独的!全部复制,然后各自独立。你修改克隆对象对于原型对象没有丝毫影响。

一,通用源代码

public class PrototypeClass implements Cloneable{
    @Override
    public PrototypeClass clone() {
        PrototypeClass prototypeClass = null;
        try {
            prototypeClass = (PrototypeClass)super.clone(); 
        } catch (CloneNotSupportedException e) {
            //异常
        }
        return prototypeClass;
    }
}

浅克隆

public class Thing implements Cloneable{
    //定义一个私有变量
    private ArrayList<String> arrayList = new ArrayList<String>();
    @Override
    public Thing clone(){
            Thing thing=null;
            try {
                   thing = (Thing)super.clone();
            } catch (CloneNotSupportedException e) {
                   e.printStackTrace();
            }
            return thing;
    }
    //设置HashMap的值
    public void setValue(String value){
            this.arrayList.add(value);
    }
    //取得arrayList的值
    public ArrayList<String> getValue(){
            return this.arrayList;
    }
}
 
//测试类
public class Client {
    public static void main(String[] args) {
            //产生一个对象
            Thing thing = new Thing();
            //设置一个值
            thing.setValue("张三");
            //拷贝一个对象
            Thing cloneThing = thing.clone();
            cloneThing.setValue("李四");
            System.out.println(thing.getValue());
    }
}

深克隆
(1) 简单深克隆

public class Thing implements Cloneable{
    //定义一个私有变量
    private ArrayList<String> arrayList = new ArrayList<String>();
    @Override
    public Thing clone(){
            Thing thing=null;
            try {
                   thing = (Thing)super.clone();
                   thing.arrayList = (ArrayList<String>)this.arrayList.clone();
            } catch (CloneNotSupportedException e) {
                   e.printStackTrace();
            }
            return thing;
    }

(2) 一般深克隆

package prototypePattern;
 
import java.io.Serializable;
 
/**
 * 
* 

Title: Attachment

*

Description:附件类

* @author HAND_WEILI * @date 2018年9月2日 */
public class Attachment_2 implements Serializable { private String name; //附件名 public String getName() { return name; } public void setName(String name) { this.name = name; } public void download() { System.out.println("下载附件"+name); } package prototypePattern; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.io.Serializable; /** * *

Title: WeeklyLog

*

Description:周报类充当具体的原型类

* @author HAND_WEILI * @date 2018年9月2日 */
public class WeeklyLog_2 implements Serializable{ private Attachment_2 attachment; private String date; private String name; private String content; public Attachment_2 getAttachment() { return attachment; } public void setAttachment(Attachment_2 attachment) { this.attachment = attachment; } public String getDate() { return date; } public void setDate(String date) { this.date = date; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } //通过序列化进行深克隆 public WeeklyLog_2 deepclone() throws Exception { //将对象写入流中, ByteArrayOutputStream bao = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bao); oos.writeObject(this); //将对象取出来 ByteArrayInputStream bi = new ByteArrayInputStream(bao.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bi); return (WeeklyLog_2)ois.readObject(); }package prototypePattern; public class Client_2 { //测试类,客户端 public static void main(String[] args) { WeeklyLog_2 log_1,log_2=null; log_1 = new WeeklyLog_2(); //创建原型对象 Attachment_2 attachment = new Attachment_2(); //创建附件对象 log_1.setAttachment(attachment); //将附件添加到周报种去 try { log_2=log_1.deepclone(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } //克隆周报 System.out.println("周报对象是否相同"+(log_1==log_2)); System.out.println("附件对象是否相同"+(log_1.getAttachment()==log_2.getAttachment())); } }

你可能感兴趣的:(JAVA设计模式之原型模式)