文章目录

  • 1、 `原型模式`概述
    • 1.1、 核心组件
    • 1.2、 优点缺陷
  • 2、 `Java`实现
    • 2.1、 原型抽象
    • 2.2、 原型实现
    • 2.3、 原型对象管理器
    • 2.4、 消费者
    • 2.5、 `深、浅`拷贝
  • 3、 `Python`实现
  • 4、 `Go`实现

1、 原型模式概述

原型模式(Prototype)[GOF95]是一种对象的创建模式,通过给定一个参考的原型对象来指定要创建的对象的类型及数据,然后复制该对象创建更多的相同对象的方式完成对象的构建过程。

1.1、 核心组件

原型类作为一个原始的构建对象,JDK体系中默认所有对象都是直接或者间接继承自object,同时也就继承了默认的clone()方法,该方法就是原型类最基本的一个表现,通过克隆的方式产生当前对象的副本。但是当克隆对象增多时管理就会出现问题,所以通常情况下我们原型模式在设计时会附带一个对象管理器,对所有通过原型对象构建出来的副本对象进行统一管理。

  • 原型对象抽象类(Prototype):原型对象的模板规范接口/抽象类,和具体业务逻辑无关,只是可作为原型对象的规范标准定义。
  • 原型对象具体类(ConcretePrototype):具体原型对象的实现,通过继承/实现Prototype接口,规范实现方式。
  • 原型对象管理器(PrototypeManager):对原型对象产生的副本对象的管理,在实际设计时会有不同的实现方案,能对项目中所有的原型对象的声明周期进行管理
  • 消费者(Consumer):和业务紧密结合的处理类。

1.2、 优点缺陷

优点:

  • 隐藏创建过程的复杂度,直接获取对象

缺陷:

  • 对已有对象的改造不便
  • 原型模式中不能有final类型的对象

2、 Java实现

2.1、 原型抽象

package com.damu.prototype;/*** <p>项目文档: 原型类 接口规范</p>** @author <a href="https://github.com/laomu/laomu.github.io">大牧</a>* @version V1.0*/
public interface Prototype {void information();
}

2.2、 原型实现

package com.damu.prototype.impl;import com.damu.prototype.Prototype;
import lombok.Data;
import lombok.experimental.Accessors;import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;/*** <p>项目文档: 具体产品对象 </p>** @author <a href="https://github.com/laomu/laomu.github.io">大牧</a>* @version V1.0*/
@Data
@Accessors(chain = true)
public class ConcretePrototype implements Prototype {private Integer id;                                    //  编号private String name;                              //  名称private Date birthday;                                //  生日private List<String> liked = new ArrayList<>();      //  爱好@Overridepublic void information() {}public ConcretePrototype addLiked(String name) {this.liked.add(name);return this;}@Overridepublic synchronized ConcretePrototype clone() {ConcretePrototype prototype = null;try {prototype = (ConcretePrototype)super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();}return prototype;}}

2.3、 原型对象管理器

package com.damu.prototype;import java.util.Vector;/*** <p>项目文档: 原型类管理器 </p>** @author <a href="https://github.com/laomu/laomu.github.io">大牧</a>* @version V1.0*/
public class PrototypeManager {// 对象容器private Vector<Prototype> vector = new Vector<Prototype>();private static PrototypeManager pm = new PrototypeManager();private PrototypeManager() {}public static PrototypeManager getPrototypeManager() {return pm;}/*** 增加对象到管理器中* @param prototype 要添加的对象*/public Prototype add(Prototype prototype) {this.vector.add(prototype);return prototype;}/*** 获取指定位置的原型对象* @param index 位置索引* @return 对象*/public Prototype get(Integer index) {return this.vector.get(index);}/*** 获取原型对象的个数* @return 返回总数目*/public Integer size(){return this.vector.size();}
}

2.4、 消费者

package com.damu.prototype.com.damu.main;import com.damu.prototype.PrototypeManager;
import com.damu.prototype.impl.ConcretePrototype;import java.util.Date;/*** <p>项目文档: 消费者 </p>** @author <a href="https://github.com/laomu/laomu.github.io">大牧</a>* @version V1.0*/
public class Consumer {public static void main(String[] args) {// 创建对象ConcretePrototype cpt = new ConcretePrototype();cpt.setId(1).setName("大圣").setBirthday(new Date());cpt.addLiked("篮球").addLiked("足球");// 将对象添加到管理器中PrototypeManager.getPrototypeManager().add(cpt);// 通过管理器管理对象System.out.println(PrototypeManager.getPrototypeManager().size());System.out.println(PrototypeManager.getPrototypeManager().get(0));// 克隆新的对象并添加到管理器中ConcretePrototype cpt2 = cpt.clone();cpt2.setName("孙大圣").addLiked("LOL").addLiked("CP");PrototypeManager.getPrototypeManager().add(cpt2);// 这里的clone(),通过打印数据就会发现,是《浅拷贝》操作方式System.out.println(PrototypeManager.getPrototypeManager().size());System.out.println(PrototypeManager.getPrototypeManager().get(0));System.out.println(PrototypeManager.getPrototypeManager().get(1));}
}

2.5、 深、浅拷贝

Java中针对对象的复制方式,有三种不同级别的操作方式

  • 引用复制

    • 不创建对象,只是将当前对象的引用复制存储到另一个变量中,多个变量指向的是同一个对象
  • 浅拷贝
    • 创建新的对象,但是对象中如果包含引用属性,付出出来的多个对象中的引用属性,指向同一个对象
  • 深拷贝
    • 创建全新的对象,多个复制出来的对象互相独立
package com.damu.copy;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.experimental.Accessors;import java.io.*;
import java.util.ArrayList;
import java.util.List;/*** <p>项目文档: 对象复制 </p>** @author <a href="https://github.com/laomu/laomu.github.io">大牧</a>* @version V1.0*/
public class CopyMethod {public static void main(String[] args) {// 创建对象List<String> list = new ArrayList<>();list.add("战神");list.add("上神");ConcretePrototype pt = new ConcretePrototype(1, "九宬", list);// section 1: 引用复制ConcretePrototype pt1 = pt;System.out.println(pt);System.out.println(pt1);// section 2: 浅拷贝ConcretePrototype pt2 = pt.clone();pt2.addNickname("小九");System.out.println("copy: " + pt1);System.out.println("copy: " + pt2);// section 3: 深拷贝ConcretePrototype pt3 = pt.deepClone();pt3.addNickname("小宸");System.out.println("deep clone:" + pt1);System.out.println("deep clone:" + pt3);}
}interface Prototype extends Cloneable{Prototype clone();Prototype deepClone();
}/*** 原型对象*/
@Data
@Accessors(chain = true)
@AllArgsConstructor
class ConcretePrototype implements Prototype, Serializable {private Integer id;     // 编号private String name;    // 名称private List<String> nickname = new ArrayList<>();public ConcretePrototype addNickname(String nickname) {this.nickname.add(nickname);return this;}public ConcretePrototype clone() {ConcretePrototype pt = null;try {pt = (ConcretePrototype) super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();}return pt;}public ConcretePrototype deepClone() {ConcretePrototype pt = null;try {ByteArrayOutputStream bos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(bos);oos.writeObject(this);ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());ObjectInputStream ois = new ObjectInputStream(bis);pt = (ConcretePrototype) ois.readObject();} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}return pt;}
}

执行结果可以看到,不同的拷贝其内部的数据特征:

ConcretePrototype(id=1, name=九宬, nickname=[战神, 上神])
ConcretePrototype(id=1, name=九宬, nickname=[战神, 上神])copy: ConcretePrototype(id=1, name=九宬, nickname=[战神, 上神, 小九])
copy: ConcretePrototype(id=1, name=九宬, nickname=[战神, 上神, 小九])deep clone:ConcretePrototype(id=1, name=九宬, nickname=[战神, 上神, 小九])
deep clone:ConcretePrototype(id=1, name=九宬, nickname=[战神, 上神, 小九, 小宸])

3、 Python实现

Python的标准实现中,已经提供了针对原型模式需要多次复制兑现的实现,所以该模式在Python语言体系中是一个语法糖,直接按照需求进行功能设计即可

"""
原型模式
"""
import copyclass Product:"""产品类型"""passclass ProductManager:"""产品管理器:需要的话添加"""passif __name__ == "__main__":"""测试代码"""# 创建对象product = Product()# 引用赋值prod1 = product# 浅拷贝prod2 = copy.copy(product)# 深拷贝prod3 = copy.deepcopy(product)

4、 Go实现

Go语言体系中,主要通过结构体进行实现,通过指针和引用完成结构体的克隆

package mainimport ("fmt"
)type PersonalInfo struct {name stringsex  stringage  string
}type Address struct {province stringcompany  stringcity     string
}type Resume struct {PersonalInfoAddress
}func (this *Resume) SetPersonalInfo(name string, sex string, age string) {this.name = namethis.sex = sexthis.age = age
}func (this *Resume) SetWorkExperience(province string, company string, city string) {this.province = provincethis.company = companythis.city = city
}func (this *Resume) Display() {fmt.Println(this.name, this.sex, this.age)fmt.Println(this.province, this.company, this.city)
}func (this *Resume) Clone() *Resume {resume := *thisreturn &resume
}func main() {person_damu := &Resume{}person_damu.SetPersonalInfo("大牧", "男", "29")person_damu.SetWorkExperience("河南", "郑州", "金水区")person_copy := person_damu.Clone()person_copy.SetWorkExperience("甘肃", "天水", "秦安")person_damu.Display()person_copy.Display()
}

大牧絮叨设计模式:原型模式相关推荐

  1. 大牧絮叨设计模式:抽象工厂模式

    文章目录 1. 抽象工厂模式概述 1.1. 核心组件 1.2. 优点缺点 2. `Java`实现 2.1. 工厂及产品结构的定义 2.2. 具体工厂类的实现 3. `Python`实现 4. `Go` ...

  2. 大牧絮叨设计模式:简单工厂模式

    文章目录 1. 简单工厂模式概述 1.1.简单工厂模式核心组件 1.2.简单工厂模式优缺点 2.` Java`实现 公共父类定义 产品具体实现类 简单工厂定义 代码运行测试: 3. `Python`实 ...

  3. 大牧絮叨设计模式:建造者模式

    文章目录 1. `建造模式` 概述 1.1. 核心组件 1.2. 优点缺陷 2. `Java` 实现 2.1. 抽象建造者`Builder` 2.2. 内聚组件`Aggregation Product ...

  4. 大牧絮叨设计模式:工厂方法模式

    文章目录 1. 工厂方法模式概述 1.1. 工厂方法模式核心组件 1.2. 工厂方法模式优缺点 2. `Java`实现 (1) 核心工厂声明 (2) 核心产品声明 (3) 产品具体实现 (4) 工厂具 ...

  5. 大牧絮叨设计模式:适配器模式

    文章目录 1. `适配器模式`概述 1.1. 什么是适配器模式 1.2. 适配器模式的优点缺陷 2. `Java`实现 2.1. 目标类:`Power`接口 2.2. 消费类:`Alienware`类 ...

  6. 大牧絮叨设计模式:单例模式

    文章目录 1.单例模式概述 1.1. 核心组件 1.2. 优点缺陷 2. `Java`实现 2.1.饿汉式单例模式 2.2. 懒汉式单例模式 3. `Python`实现 3.1. 单实例操作 3.2. ...

  7. Java常用设计模式————原型模式(一)

    介绍 原型模式(Prototype Pattern):用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象. 原型模式用于创建重复的对象,同时又能保证性能.当直接创建对象的代价比较大时,则采用 ...

  8. 设计模式 原型模式_创新设计模式:原型模式

    设计模式 原型模式 原型模式用于创建对象的副本. 这种模式非常有用,特别是当从头开始创建对象的成本很高时. 与builder , factory和abstract factory模式相比,它不会从头开 ...

  9. 设计模式 原型模式_设计模式:原型

    设计模式 原型模式 创新设计模式之一是原型设计模式 . 尽管原型是创造模式,但它在概念上与其他模式有所区别. 我的意思是原型在某种意义上创造了自己. 我将在下面解释. 原型模式的所有魔力都基于Java ...

最新文章

  1. GitHub 重磅更新:无限私有仓库免费使用
  2. 最短JS判断是否为IE6(IE的写法)
  3. addeventlistener不支持ajax_十万个Web前端面试题之AJAX、axios、fetch的区别
  4. Android activity-alias 的使用
  5. RESTful---SpringMVC学习笔记(十三)
  6. OSG与opengl的shader结合
  7. python中history()_keras中的History对象用法
  8. 南宁研祥智谷远程预付费电能管理系统的应用
  9. 关于网狐游戏vs2003移植到vs2013
  10. java进销存系统--采购入库
  11. 用golang做繁简体转换
  12. 苹果微信更新不了最新版本_微信登录不了,微信提示版本过低,请升级最新版本的解决办法...
  13. 【Spring Cloud 基础设施搭建系列】Spring Cloud Demo项目 整合Spring Data JPA
  14. 【Android开发】微信精选,文章资讯类App开发记录总结
  15. P02014158 马帅(信息论课程作业)
  16. 最强旗舰手机功能曝光:大变活人、智能静音、拍照测肤……
  17. 华为云计算IE面试笔记-eBackup有哪几种备份组网方式,各备份组网方式主要的应用场景及备份流程?
  18. 云主机概念的简单介绍
  19. 使用jquery.validate.js,当onfocusout: true,同时focus验证失败元素时会导致$(#form).valid()总是返回true?...
  20. 企业邮箱哪个好,公司邮箱品牌如何选择?

热门文章

  1. 计算机电磁兼容性设计方法,一文看懂电磁兼容性原理与方法及设计
  2. baocms伪静态_baocms
  3. js打印完毕后关闭窗口
  4. SDK设计心得之接口设计
  5. win7计算机没有光驱图标不见了,关于如何解决Win7光驱图标消失的问题的讲解
  6. 电动机降压启动电路图全解
  7. 企业网络-小型企业网络搭建
  8. iOS App开发那些事:如何选择合适的人、规范和框架?
  9. 洛谷 P1498 南蛮图腾 分治递归过程详解
  10. 136 模型的操作3