原型模式(设计模式详解)

描述

原型模式(Prototype Pattern)是一种创建型设计模式,它允许通过复制现有对象来创建新对象,而无需从头开始编写代码。

  • 在原型模式中,一个原型对象作为模板,新的对象通过克隆这个原型对象而创建。这样可以避免使用相同的代码来创建相似的对象,同时也可以提高创建对象的效率。通常情况下,原型模式会使用一个原型管理器来存储和管理原型对象,以便在需要的时候进行复制。

  • 原型模式适用于需要创建大量相似对象的场景,如图形编辑器中的图形对象、数据库中的数据对象、网络传输中的数据包等。通过使用原型模式,可以大大提高对象创建的效率和代码复用性。


实现


public class Client {
    public static void main(String[] args) {
        Car car = new Car("丰田", 140000);
        Prototype prototype = new Prototype();
        prototype.registerObj("丰田",car);
        Car cloneCar = prototype.clone("丰田");
        System.out.println(car == cloneCar);
        System.out.println(cloneCar);

    }
}

/**
 * 原型对象
 */
class Prototype {
    //存放实例的map
    private Map<String, Object> prototypeMap;

    public Prototype() {
        this.prototypeMap = new HashMap<>();
    }
    //注册对象
    public void registerObj(String name,Object o){
        prototypeMap.put(name,o);
    }

    public void unRegisterObj(String name){
        prototypeMap.remove(name);
    }

    public Car clone(String name){
        return ((Car)(prototypeMap.get(name))).clone();
    }
}

/**
 * Car继承Cloneable
 */
class Car implements Cloneable{
    private String carName;
    private int price;
    public Car(){

    }
    public Car(String carName, int price) {
        this.carName = carName;
        this.price = price;
    }
    public Car clone(){
        try {
            return (Car) super.clone();
        } catch (CloneNotSupportedException e) {
            return new Car(this.carName,this.price);
        }
    }

    @Override
    public String toString() {
        return "Car{" +
                "carName='" + carName + '\'' +
                ", price=" + price +
                '}';
    }
}

对于对象的拷贝是使用jdk自带的clone,那么就会有个问题,拷贝是属于深拷贝还是浅拷贝呢?

深拷贝:深拷贝(Deep Copy)是指在进行对象复制时,将被复制对象的所有成员变量都复制一份到新的对象中,而不是仅仅复制对象的引用。

浅拷贝:,浅拷贝(Shallow Copy)仅仅复制对象的引用,而不是对象本身的成员变量。因此,如果原对象发生变化,浅拷贝后的新对象也会受到影响。

我们来测试一下。我们把Car修改成以下代码

class Car implements Cloneable{
    private String carName;
    private int price;
    private Object from;
    public Car(){

    }
    public Car(String carName, int price,Object from) {
        this.carName = carName;
        this.price = price;
        this.from = from;
    }
    public Car clone(){
        try {
            return (Car) super.clone();
        } catch (CloneNotSupportedException e) {
            return new Car(this.carName,this.price,this.from);
        }
    }

    @Override
    public String toString() {
        return "Car{" +
                "carName='" + carName + '\'' +
                ", price=" + price +
                '}';
    }

    public String getCarName() {
        return carName;
    }

    public int getPrice() {
        return price;
    }

    public Object getFrom() {
        return from;
    }
}

当克隆后我们比对引用类型的属性

   Car car = new Car("丰田", 140000,new Object());
        Prototype prototype = new Prototype();
        prototype.registerObj("丰田",car);
        Car cloneCar = prototype.clone("丰田");
        System.out.println(cloneCar.getFrom() == car.getFrom());

在这里插入图片描述发现克隆的对象的引用属性和被克隆的对象引用属性的地址一致。

通过以上结论,我们可以知道,jdk的clone为浅拷贝。如果需要深拷贝,我们需要重新自己写一个克隆方法来进行深拷贝。


使用场景

  • 当需要创建的对象具有相同的属性和方法时,但其状态不同,例如游戏中的敌人,它们具有相同的属性和方法,但具有不同的血量、攻击力等状态。

  • 当创建对象的过程非常昂贵或复杂时,例如数据库连接对象、网络连接对象等。在这种情况下,通过复制现有对象,可以避免重复创建对象,从而提高性能。

  • 当需要避免构造函数被反复调用时,例如在某些系统中,构造函数可能会执行一些昂贵的计算或操作,通过使用原型模式,可以避免这些计算或操作被反复执行

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值