Java设计模式:原型模式

2020.07.31 23:07:27
22
阅读约 2 分钟

原型模式 #

是指原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象。
主要适用于以下场景:

  1. 类初始化消耗资源较多
  2. 使用new生成一个对象需要非常繁琐的过程
  3. 构造函数比较复杂
  4. 在循环体中产生大量对象

浅克隆 #

一个标准的原型模式应该是这样设计的,先创建原型prototype接口:

  interface Prototype{
    Prototype clone(); 
}

创建具体需要克隆的类 ConcretePrototypeA

class  ConcretePrototypeA implements Prototype{
    private int age;
    private String name;
    private List hobbies;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List getHobbies() {
        return hobbies;
    }

    public void setHobbies(List hobbies) {
        this.hobbies = hobbies;
    }

    @Override
    public Prototype clone() {
        ConcretePrototypeA concretePrototypeA = new ConcretePrototypeA();
        concretePrototypeA.setAge(this.age);
        concretePrototypeA.setHobbies(this.hobbies);
        concretePrototypeA.setName(this.name);
        return concretePrototypeA;
    }
}

创建一个client类

class Client{
    private Prototype prototype;
    public Client(Prototype prototype){
        this.prototype =prototype;
    }

    public Prototype startClone(Prototype concretePrototype){
        return concretePrototype.clone();
    }
}

在main函数中测试

public class main {
    public static void main(String[] args) {
        ConcretePrototypeA concretePrototypeA = new ConcretePrototypeA();
        concretePrototypeA.setName("jeddy");
        concretePrototypeA.setAge(18);
        List<String> objects = new ArrayList<>();
        concretePrototypeA.setHobbies(objects);


        // 创建client对象
        Client client = new Client(concretePrototypeA);
      ConcretePrototypeA concretePrototypeA1=  (ConcretePrototypeA) client.startClone(concretePrototypeA);
        System.out.println(concretePrototypeA1);
        System.out.println("对象地址比较"+(concretePrototypeA==concretePrototypeA1));
        System.out.println("对象内地址比较"+(concretePrototypeA.getHobbies()==concretePrototypeA1.getHobbies()));
    }
}

img
可以看到,对象内的hobbes引用的地址是相同的,意味着复制的是引用地址,但对象并没有复制,这就是我们常说的浅克隆。

深克隆 #

我们换一个场景,大家都知道齐天大圣,不管它七十二变如何变化,它本身并没有变化,这就是一个经典的体现。

创建原型猴子类:

class  Monkey{
    public int height;
    public int weight;
    public Date birthday;
}

创建引用对象金箍棒类:

class JinGuBnag implements Serializable{
    public float h=100;
    public float d=100;
    public void big(){
        this.d*=2;
        this.h*=2;
    }
    public void small(){
        this.d/=2;
        this.h/=2;
    } 
    
}

创建具体的对象齐天大圣类

class QiTianDaSheng extends Monkey implements Cloneable,Serializable{
    public JinGuBnag jinGuBnag;
    public QiTianDaSheng(){
        this.birthday= new Date();
        this.jinGuBnag = new JinGuBnag();
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return this.deepClone();
    }

    private Object deepClone() {
        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(this);

            ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bis);
          QiTianDaSheng copy =   (QiTianDaSheng)  ois.readObject();
            copy.birthday = new Date();
            return copy;

        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
            return  null;
        }
    }

    public QiTianDaSheng shallowClone(QiTianDaSheng target){
        QiTianDaSheng qiTianDaSheng = new QiTianDaSheng();
        qiTianDaSheng.height =target.height;
        qiTianDaSheng.weight=target.weight;
        qiTianDaSheng.jinGuBnag=target.jinGuBnag;
        qiTianDaSheng.birthday=new Date();
        return qiTianDaSheng;
    }

主函数测试

public class main {
    public static void main(String[] args) {
        QiTianDaSheng qiTianDaSheng = new QiTianDaSheng();
        try {
            QiTianDaSheng clone = (QiTianDaSheng) qiTianDaSheng.clone();
            System.out.println("深克隆:"+(qiTianDaSheng.jinGuBnag==clone.jinGuBnag));
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }

        QiTianDaSheng qiTianDaSheng1 = new QiTianDaSheng();
        QiTianDaSheng n = qiTianDaSheng.shallowClone(qiTianDaSheng1);
        System.out.println("浅克隆:"+(qiTianDaSheng1.jinGuBnag==n.jinGuBnag));
    }

}

img

阅读:22 . 字数:341 发布于 4 个月前
Copyright 2018-2020 Siques