• 原型模式(Prototype Pattern)


    原型模式(Prototype Pattern)

    定义

    原型模式用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

    调用者不需要知道任何创建细节,不调用构造函数

    属于创建型模式

    适用场景

    • 对象的创建成本较高:
      如果创建对象的过程比较复杂或者耗时较长,可以使用原型模式通过复制一个现有对象的属性和方法来创建新对象,从而避免了昂贵的创建过程。
    • 需要创建大量相似的对象:
      如果需要创建大量相似的对象,可以先创建一个原型对象,然后通过复制原型对象来创建新对象,从而提高对象创建的效率和性能。
    • 对象的修改频繁:
      如果对象的属性需要经常变化,而且每次变化都需要创建一个新的对象,可以使用原型模式,通过复制原型对象来创建新对象并修改其属性,而不需要每次都重新创建新对象。

    标准示例

    在这里插入图片描述

    • Prototype 抽象原型角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体原型类所需的接口。在Java中,通常实现了Cloneable接口。
    • ConcretePrototype 具体原型角色:被复制的对象。此角色需要实现抽象的原型角色所要求的接口。
    • PrototypeManager 原型管理器角色(可选):创建具体原型类的对象,并记录每一个被创建的对象。
    • ClientTest 客户角色:客户端类向原型管理器提出创建对象的请求。
    public interface Prototype extends Cloneable {
        Prototype deepClone();
    }
    
    import com.alibaba.fastjson2.JSONObject;
    import lombok.Data;
    
    import java.util.List;
    
    @Data
    public class ConcretePrototype implements Prototype{
    
        private String name;
        private int age;
        private List skill;
    
        public ConcretePrototype(){}
        public ConcretePrototype(String name,int age,List skill){
            this.age = age;
            this.name = name;
            this.skill = skill;
        }
        public Prototype deepClone(){
            String jsonStr = JSONObject.toJSONString(this);
            ConcretePrototype deepCopy = JSONObject.parseObject(jsonStr,ConcretePrototype.class);
            return deepCopy;
        }
        public Object clone() {
            try {
                return super.clone();
            } catch (CloneNotSupportedException e) {
                throw new RuntimeException(e);
            }
        }
    }
    
    public class PrototypeManager {
        public static Prototype copy(ConcretePrototype concretePrototype){
            return (Prototype) concretePrototype.clone();
        }
    
        public static Prototype deepCopy(ConcretePrototype concretePrototype){
            return concretePrototype.deepClone();
        }
    }
    
    public class ClientTest {
        public static void main(String[] args) {
            //ConcretePrototype 中的 List类型的属性 skill
            List<String> skill = new ArrayList<String>(Arrays.asList("cook","code","run"));
            //创建一个ConcretePrototype对象
            ConcretePrototype concretePrototype = new ConcretePrototype("Tomas",40,skill);
            System.out.println("concretePrototype:"+concretePrototype);
            //浅克隆
            Prototype shallowCopy = PrototypeManager.copy(concretePrototype);
            //深克隆
            Prototype deepCopy = PrototypeManager.deepCopy(concretePrototype);
    
            //改变 skill内容,增加一项 dream
            skill.add(3,"dream");
            System.out.println("after add 'dream'");
            System.out.println("shallowCopy:"+shallowCopy);
            System.out.println("deepCopy:"+deepCopy);
    
        }
    }
    

    输出结果为:

    concretePrototype:ConcretePrototype(name=Tomas, age=40, skill=[cook, code, run])
    after add 'dream'
    shallowCopy:ConcretePrototype(name=Tomas, age=40, skill=[cook, code, run, dream])
    deepCopy:ConcretePrototype(name=Tomas, age=40, skill=[cook, code, run])
    

    从结果可以看出,原对象中的引用变量内容改变,对浅克隆对象有影响;对深克隆对象无影响。


    以上就是原型模式全部内容,感谢阅读!

  • 相关阅读:
    Ubuntu添加非root用户到Docker用户组
    在C#中进行单元测试
    适用于初学者的 .NET MAUI
    Sentinel-限流降级
    [附源码]Python计算机毕业设计高校餐厅评价系统
    软考 系统架构设计师系列知识点之设计模式(9)
    Jetpack Compose学习(9)——Compose中的列表控件(LazyRow和LazyColumn)
    运算符——“MySQL数据库”
    CF821 A. Consecutive Sum
    王道考研——操作系统(第二章 进程管理)(进程;线程)
  • 原文地址:https://blog.csdn.net/yuiezt/article/details/140321918