设计模式之创建型模式(三)原型模式

105 阅读3分钟

有哪些创建型模式

1.单例模式 2.工厂模式 3.原型模式 4.建造者模式

接下来针对以上4种设计模式进行单独讲解

3 原型模式

3.1 定义

通过原型实例创建对象,并且通过克隆这些对象创建一个和原型对象一样但是是全新的对象的模式

3.2 应用场景

需要创建完全相同或者大部分都相同的对象,其中spring中的原型bean,Json.parseObject都是该模式的典型应用

3.3 UML图

image.png 从该UML中可以看出,Prototype作为原型类的抽象父类,提供clone方法供客户端调用,ConretePrototype作为原型类的具体实现类,负责具体对象的clone方法,客户端只需要调用抽象原型类指明具体实现即可

3.4 具体代码实现

interface Cloneable {  
    Object clone();  
}  
  
// 具体原型类  
class Complex implements Cloneable {  
    private double real;  
    private double imag;  
  
    public Complex(double real, double imag) {  
        this.real = real;  
        this.imag = imag;  
    }  
  
    public double getReal() {  
        return real;  
    }  
  
    public double getImag() {  
        return imag;  
    }  
  
    @Override  
    public Object clone() {  
        try {  
            // 通过调用super.clone()方法复制对象,并返回副本  
            return super.clone();  
        } catch (CloneNotSupportedException e) {  
            e.printStackTrace();  
            return null;  
        }  
    }  
}  
  
// 客户端代码  
public class Client {  
    public static void main(String[] args) {  
        // 创建原型对象  
        Complex prototype = new Complex(1.0, 2.0);  
  
        // 克隆原型对象得到一个新的对象  
        Complex newObject = (Complex) prototype.clone();  
  
        // 修改新对象的实部和虚部  
        newObject.real = 3.0;  
        newObject.imag = 4.0;  
  
        // 输出新对象的值  
        System.out.println("New Object: " + newObject.real + " + " + newObject.imag + "i");  
    }  
}

3.5 扩展

需注意深度clone和浅度clone的区别 深度clone是指当前对象的所有成员变量都会copy出一份,所有clone出来的成员变量都是独立的,比较该成员变量和原成员变量,内存地址不一样 浅度克隆是指当前对象的所有基本类型的变量都会copy出一份,而引用类型的成员变量知识copy了内存地址,也就是画了个指针指向了原对象,引用类型的成员变量内存地址一样

在java中一般深度克隆需要实现序列化接口,以下是一个简单的深度克隆案例

public class DeepCopy {  
  
    // 需要深度克隆的对象类  
    public static class MyObject implements Serializable {  
        private int value;  
        private MyObject child;  
  
        public MyObject(int value, MyObject child) {  
            this.value = value;  
            this.child = child;  
        }  
  
        public int getValue() {  
            return value;  
        }  
  
        public MyObject getChild() {  
            return child;  
        }  
    }  
  
    public static MyObject deepCopy(MyObject obj) {  
        try {  
            // 将对象写入到ByteArrayOutputStream中  
            ByteArrayOutputStream bos = new ByteArrayOutputStream();  
            ObjectOutputStream out = new ObjectOutputStream(bos);  
            out.writeObject(obj);  
            out.flush();  
            out.close();  
            bos.close();  
  
            // 从ByteArrayInputStream中读取对象  
            ByteArrayInputStream bin = new ByteArrayInputStream(bos.toByteArray());  
            ObjectInputStream in = new ObjectInputStream(bin);  
            return (MyObject) in.readObject();  
        } catch (Exception e) {  
            e.printStackTrace();  
            return null;  
        }  
    }  
  
    public static void main(String[] args) {  
        MyObject obj1 = new MyObject(1, new MyObject(2, null));  
        MyObject obj2 = deepCopy(obj1);  
  
        System.out.println("Original object value: " + obj1.getValue());  
        System.out.println("Copied object value: " + obj2.getValue());  
    }  
}

本段代码定义了一个需要深度克隆的对象类MyObject,它包含一个整数值和一个子对象。然后,定义了一个名为deepCopy的方法,该方法使用Java序列化和反序列化库来创建对象的深度拷贝。最后,main方法中创建了一个原始对象,并打印其值。然后对它进行深度克隆,并打印克隆后的值。

作者:qtlq
链接:juejin.cn/post/728941…
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。