博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
浅析设计模式(五)——原型模式
阅读量:6610 次
发布时间:2019-06-24

本文共 3849 字,大约阅读时间需要 12 分钟。

原型模式(Prototype,创建型模式)

本文的结构:

一、原型模式的定义

   定义:用原型实例指定创建对象的实例,并且通过拷贝这些原型创建新的对象。

  使用现有的对象,生成一个完全一样的拷贝(副本,内部属性值一样,而内存地址不一样),但是这个拷贝和原对象不共用任何内部属性元素,即实现了对象的深度克隆。这个“拷贝”的精确含义取决于该对象的类,一般含义是:

  1. 对任何的对象x,都有:x.clone()!=x。换言之,克隆对象与原对象不是同一个对象。
  2. 对任何的对象x,都有:x.clone().getClass() == x.getClass(),换言之,克隆对象与原对象的类型一样。
  3. 如果对象x的equals()方法定义其恰当的话,那么x.clone().equals(x)应当成立的。

二、原型模式的参与者及其角色

 1、Prototype

  • 声明一个克隆自身的接口。

2、ConcretePrototype

  • 实现一个克隆自身的操作。

3、Client

  • 让一个原型克隆自身从而创建一个新的对象。

 

三、原型模式的类图

 

 四、原型模式的示例

  Java中可以使用以下几种方式进行对象的深度克隆:

  1. 实现Cloneable接口,并重写Object类中的clone()方法
  2. 实现序列化哈反序列化实现对象的深度克隆,实现Serializable接口或者Externalizable接口。

 下面使用Cloneable进行说明:

1、Prototype

  使用Cloneable接口。

2、ConcretePrototype

  实现一个克隆自身的操作,这里是clone()方法,需要重新进行定义。

1 public class Name implements Cloneable{ 2     private String firstName; 3     private String lastName; 4     private Title title; 5     //Constructor with no arguments 6     public Name(){ 7          8     } 9     //Constructor with all arguments10     public Name(String firstName, String lastName, Title title) {11         super();12         this.firstName = firstName;13         this.lastName = lastName;14         this.title = title;15     }16     //all getters and setters17     public String getFirstName() {18         return firstName;19     }20     public void setFirstName(String firstName) {21         this.firstName = firstName;22     }23     public String getLastName() {24         return lastName;25     }26     public void setLastName(String lastName) {27         this.lastName = lastName;28     }29     30     public Title getTitle() {31         return title;32     }33     public void setTitle(Title title) {34         this.title = title;35     }36     @Override37     public Name clone() throws CloneNotSupportedException {38         Name nameClone = (Name)super.clone();39         nameClone.setFirstName(new String(this.getFirstName()));40         nameClone.setLastName(new String(this.getLastName()));41         nameClone.setTitle(this.getTitle().clone());42         return nameClone;43     }44 45 }

 

   这里要注意的是,若属性中有对象引用,同样需要进行深度克隆,而该属性也同样需要实现Cloneable,重写clone()方法。如上面的Title,如下:

1 public class Title implements Cloneable{ 2     private String pre; 3     private String title; 4     //Constructor with no arguments 5     public Title(){ 6          7     } 8     //Constructor with all arguments 9     public Title(String pre, String title) {10         super();11         this.pre = pre;12         this.title = title;13     }14     public String getPre() {15         return pre;16     }17     public void setPre(String pre) {18         this.pre = pre;19     }20     public String getTitle() {21         return title;22     }23     public void setTitle(String title) {24         this.title = title;25     }26     @Override27     public Title clone() throws CloneNotSupportedException {28         Title title = (Title)super.clone();29         title.setPre(new String(this.getPre()));30         title.setTitle(new String(this.getTitle()));31         return title;32     }33 }

 

3、Client

  创建原型对象,然后进行克隆。main方法中进行,输出结果均为false。

1 public class PrototypeTestApp { 2     public static void main(String[] args) throws CloneNotSupportedException { 3         Title title = new Title("Mr", "Doc"); 4         Name name = new Name("San", "Li", title); 5          6         Name nameClone = name.clone(); 7          8         System.out.println(nameClone.getFirstName() == name.getFirstName()); 9         System.out.println(nameClone.getLastName() == name.getLastName());10         System.out.println(nameClone.getTitle() == name.getTitle());11         System.out.println(nameClone.getTitle().getPre() == name.getTitle().getPre());12         System.out.println(nameClone.getTitle().getTitle() == name.getTitle().getTitle());13     }14 }

 

 

五、参考

 1、参考《Head First设计模式》和GoF《设计模式:可复用面向对象软件的基础》

2、代码可参考【】、UML类图参考【】

转载于:https://www.cnblogs.com/wpbxin/p/9439559.html

你可能感兴趣的文章
django之表单及模板渲染、全局钩子、局部钩子函数-67
查看>>
SQL总结(二)连表查询
查看>>
【转载】FPGA功耗的那些事儿
查看>>
delphi 获取可执行文件的当前路径
查看>>
求圆的面积
查看>>
自定义控件
查看>>
HDOJ-4006/(大连网赛1006)- The kth great number 剖析
查看>>
[Codeforces Round #452 (Div. 2)] Splitting in Teams
查看>>
leetcode 51: Generate Parentheses
查看>>
IE6 for WIN8
查看>>
Java gc机制
查看>>
python xml.etree ElementTree解析 编辑 xml
查看>>
复利计算5.0-----结对编程
查看>>
hdu 1255 覆盖的面积(求覆盖至少两次以上的面积)
查看>>
sb 讲解 (!(~+[])+{})[--[~+""][+[]]*[~+[]] + ~~!+[]]+({}+[])[[~!+[]]*~+[]]
查看>>
06-Linux RPM 命令参数使用详解
查看>>
Tone Mapping算法系列一:基于Fast Bilateral Filtering 算法的 High-Dynamic Range(HDR) 图像显示技术。...
查看>>
输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数
查看>>
[每日小结] 浅谈堆模拟费用流
查看>>
iOS7中的状态栏
查看>>