原型模式详解

原型模式

定义: 用于创建重复的对象,同时又能保证性能。用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。

使用场景:

  • 资源优化
  • 性能和安全要求的场景
  • 通过 new 产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式
  • 一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用
  • 原型模式很少单独出现,一般和工厂方法模式配合使用,原型模式 clone 对象,工厂方法提供调用

使用条件:

  • 必须实现 Cloneable 接口。在 java 虚拟机中,只有实现了这个接口的类才可以被拷贝,否则在运行时会抛出 CloneNotSupportedException 异常。
  • 重写 Object 类中的 clone() 方法

注意事项:

  • 原型模式是通过拷贝一个现有对象生成新对象的,属于浅拷贝。只需要实现 Cloneable 接口,重写 Object 的 clone() 方法。深拷贝是通过实现 Serializable 读取二进制流。Object 类的 clone() 方法只会拷贝对象中的基本的数据类型,对于数组、对象等拷贝的是对象的地址(因此每个 clone 对象指向同一对象,无法做到数据隔离)。
  • 原型模式复制对象不会调用类的构造方法。因为对象的复制是通过 Object 的 clone() 方法来完成的。因此,构造方法的访问权限也会失效,与单例模式也会发生冲突。

实现

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WraYLkwH-1636188861057)(C:\Users\zhe\AppData\Roaming\Typora\typora-user-images\image-20211105134143786.png)]

原型类

/**
 * 原型类
 */
@Data
public abstract class Prototype implements Cloneable{
    protected  String name;

    public Prototype clone(){
        Prototype prototype = null;
        try{
            prototype = (Prototype)super.clone();
        }catch(CloneNotSupportedException e){
            e.printStackTrace();
        }
        return prototype;
    }

    public abstract void say(int i);
}

/**
 * 原型类子类 1
 */
public class PrototypeSubclass1 extends Prototype{
    public PrototypeSubclass1() {
        name = "子类1 无参构造";
    }

    public PrototypeSubclass1(int i) {
        name = "子类1 有参构造";
    }

    @Override
    public void say(int i) {
        System.out.println("创建了第 "+ i +" 个原型类子类1");
    }
}


/**
 * 原型类子类 2
 */
public class PrototypeSubclass2 extends Prototype{
    public PrototypeSubclass2() {
        name = "子类 2 无参构造";
    }

    public PrototypeSubclass2(int i) {
        name = "子类 2 有参构造";
    }

    @Override
    public void say(int i) {
        System.out.println("创建了第 "+ i +" 个原型类子类2");
    }
}

调用者(clone 对象)

public class CallPrototype {
    public static void main(String[] args){
        Prototype pt1 = new PrototypeSubclass1(1);
        for(int i=0; i< 2; i++){
            // clone 不会调用构造方法
            Prototype prototype = (Prototype)pt1.clone();
            prototype.say(i);
            System.out.println(prototype.getName());
        }
        Prototype pt2 = new PrototypeSubclass2();
        for(int i=0; i< 2; i++){
            Prototype prototype = (Prototype)pt2.clone();
            prototype.say(i);
            System.out.println(prototype.getName());
        }
    }
}
------------------------打印结果-----------------------
创建了第 0 个原型类子类1
子类1 有参构造
创建了第 1 个原型类子类1
子类1 有参构造
创建了第 0 个原型类子类2
子类 2 无参构造
创建了第 1 个原型类子类2
子类 2 无参构造
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值