由于blog各种垃圾评论太多,而且本人审核评论周期较长,所以懒得管理评论了,就把评论功能关闭,有问题可以直接qq骚扰我

设计模式—原型模式

JAVA 西门飞冰 525℃

定义

⽤⼀个已经创建的实例作为原型,通过复制该原型对象来创建⼀个和原型相同或相似的新对象。在这⾥,原型实例指定了要创建的对象的种类。⽤这种⽅式创建对象⾮常⾼效,根本⽆须知道对象创建的细节。

image-20220926110013723

优点

Java⾃带的原型模式基于内存⼆进制流的复制,在性能上⽐直接new⼀个对象更加优良。

可以使⽤深克隆⽅式保存对象的状态,使⽤原型模式将对象复制⼀份,并将其状态保存起来,简化了创建对象的过程,以便在需要的时候使⽤(例如恢复到历史某⼀状态),可辅助实现撤销操作。

缺点

需要为每⼀个类都配置⼀个 clone ⽅法

clone ⽅法位于类的内部,当对已有类进⾏改造的时候,需要修改代码,违背了开闭原则。

当实现深克隆时,需要编写较为复杂的代码,⽽且当对象之间存在多重嵌套引⽤时,为了实现深克隆,每⼀层对象对应的类都必须⽀持深克隆,实现起来会⽐较麻烦。因此,深克隆、浅克隆需要运⽤得当。

原型模式实现对象克隆有两种形式:浅克隆与深克隆

代码实现

浅克隆

浅克隆:创建⼀个新对象,新对象的属性和原来对象完全相同,对于⾮基本类型属性,仍指向原有属性所指向的对象的内存地址。

image-20220926121857813

汽车类:

public class Car {
    //定义车的车牌号属性
    public String number;

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }
}

员工类:

//被复制的对象需要实现Clonable接⼝与clone()⽅法
public class Employee implements Cloneable{
    private String name;
    private Car car;

    public String getName() {
        return name;
    }

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

    public Car getCar() {
        return car;
    }

    public void setCar(Car car) {
        this.car = car;
    }

    //重写clone方法
    @Override
    protected Object clone() throws CloneNotSupportedException {
        System.out.println("正在复制Employee对象");
        return super.clone();
    }
}

应用入口:

public class App {
    public static void main(String[] args) throws CloneNotSupportedException {
        Employee king = new Employee();
        king.setName("King");
        Car car = new Car();
        car.setNumber("FBW 381");
        // 将king和cat对象进行绑定
        king.setCar(car);
        // 进行clone操作
        Employee cloneKing = (Employee) king.clone();
        // 结果验证
        System.out.println("King == CloneKing:" + (king == cloneKing));
        System.out.println("King.car == CloneKing.car:" + (king.getCar() == cloneKing.getCar()));
    }
}

输出结果:

正在复制Employee对象
King == CloneKing:false			//通过clone方法在内存中创建了两个不同的对象,所以为false
King.car == CloneKing.car:true	//都指向了相同的一个car对象,所以为true

深克隆

深克隆:创建⼀个新对象,属性中引⽤的其他对象也会被克隆,不再指向原有对象地址。

image-20220926123001773

Car代码完全相同,省略

基于Json实现对象深度Clone,不再需要实现Clonable接⼝与clone()⽅法

public class Employee {
    private String name;
    private Car car;

    public String getName() {
        return name;
    }

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

    public Car getCar() {
        return car;
    }

    public void setCar(Car car) {
        this.car = car;
    }
    //基于JSON实现深度序列化
    public Employee deepClone(){
        Gson gson = new Gson();
        String json = gson.toJson(this);
        System.out.println(json);
        Employee cloneObject = gson.fromJson(json,Employee.class);
        return cloneObject;
    }
}

应用入口:

public class App {
    public static void main(String[] args) throws CloneNotSupportedException {
        Employee king = new Employee();
        king.setName("King");
        Car car = new Car();
        car.setNumber("FBW 381");
        // 将king和cat对象进行绑定
        king.setCar(car);
        // 进行clone操作
        Employee cloneKing = (Employee) king.deepClone();
        System.out.println("King == CloneKing:" + (king == cloneKing));
        System.out.println("King.car == CloneKing.car:" + (king.getCar() == cloneKing.getCar()));
    }
}

输出结果:

{"name":"King","car":{"number":"FBW 381"}}
King == CloneKing:false
King.car == CloneKing.car:false		//在内存中是完全独立切割开的

应用场景

对象之间相同或相似,即只是个别的⼏个属性不同的时候。

创建对象成本较⼤,例如初始化时间⻓,占⽤CPU太多,或者占⽤⽹络资源太多等,需要优化资源。

创建⼀个对象需要繁琐的数据准备或访问权限等,需要提⾼性能或者提⾼安全性。

系统中⼤量使⽤该类对象,且各个调⽤者都需要给它的属性重新赋值。

image-20220926123740985

转载请注明:西门飞冰的博客 » 设计模式—原型模式

喜欢 (0)or分享 (0)