设计模式之原型模式
来源:互联网 发布:怎么查看淘宝注册日期 编辑:程序博客网 时间:2024/06/05 02:54
原型模式(Prototype):用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
一、原型模式
原型模式其实就是从一个对象再创建另一个对象,而且不需要知道详细的创建细节,其UML图如下:
原型模式由以下部分组成:
客户(Client)角色:客户类提出创建对象的请求。
抽象原型(Prototype)角色:这是一个抽象角色,通常由一个Java接口或Java抽象类实现。此角色给出所有的具体原型类所需的接口clone()。
具体原型(ConcretePrototype)角色:被复制的对象。此角色需要实现抽象的原型角色所要求的接口。
二、案例分析
在《西游记》中,孙悟空,拔一根毫毛,吹一口气,就能变出成千上万的小猴子,这是孙悟空的分身术,但其实除了孙悟空,哪吒、杨戬等好多神仙都会分身术,作者在定义神仙(Prototype)原型的时候,就想好了神仙可以拥有分身术(clone()),所以,在书中,孙悟空等各路神仙都会分身,这里面就隐含了一个原型模式,其UML图如下:
代码如下:
原型类–神仙:
abstract class Prototype{ private String name; public abstract Prototype Clone();}
具体原型类–大圣
class SunWuKong extends Prototype{ private String name; public Prototype clone{ return (Prototype)this.MemberwiseClone(); }}
具体原型类–哪吒
class NeZha extends Prototype{ private String name; public Prototype clone{ return (Prototype)this.MemberwiseClone(); }}
故事上演:
public class Story{ public static void main(String[] args) { SunWuKong suk = new SunWuKong (); suk.setName("我是孙大圣"); System.out.println(suk.getName()); SunWuKong monkey1 = (SUnWuKong)suk.clone(); monkey1 .setName("我是小猴子1"); System.out.println(monkey1.getName()); SunWuKong monkey2 = (SUnWuKong)suk.clone(); monkey2 .setName("我是小猴子2"); System.out.println(monkey2.getName()); } }
运行结果:
我是孙大圣我是小猴子1我是小猴子2
这样孙悟空就能变出好多猴子了。
三、浅复制和深复制
接着让我们还是以神仙的分身术为例,我们规定,每个神仙不仅有名字,还得有武器,扩展上面的类,名字就是一个Sring类型,而武器有名字和重量,作为一个类,扩展如下:
原型类–神仙:
abstract class Prototype{ private String name; private Weapon weapon; public void display(); public abstract Prototype Clone();}
武器类:
class Weapon(){ private String name; private String weight;}
具体原型类–大圣
class SunWuKong extends Prototype{ private String name; private Weapon weapon; public void display(name,weapon){ System.out.println("我是"+this.name+",我的武器是"+weapon.name+",重量有"+weapon.weight+"。"); }; public Prototype clone{ return (Prototype)this.MemberwiseClone(); }}
故事上演:
public class Story{ public static void main(String[] args) { SunWuKong suk = new SunWuKong (); suk.setName("孙悟空"); suk.setWeapon(new Weapon("如意金箍棒",“一万三千五百斤”)) SunWuKong monkey1 = (SUnWuKong)suk.clone(); monkey1 .setName("小猴子1"); monkey1 .setWeapon(new Weapon("木棒",“20斤”)) SunWuKong monkey2 = (SUnWuKong)suk.clone(); monkey2 .setName("小猴子2"); monkey2 .setWeapon(new Weapon("铁棒",“50斤”)) suk.display(); monkey1.display(); monkey2.display(); } }
运行结果如下:
我是孙悟空,我的武器是如意金箍棒,重量有一万三千五百斤。我是小猴子1,我的武器是如意金箍棒,重量有一万三千五百斤。我是小猴子2,我的武器是如意金箍棒,重量有一万三千五百斤。
这个结果不是我们想要的呀,一万三千五百斤的金箍棒早就把小猴子压死了。那为什么会出现上面的结果呢?一切是因为MemberwiseClone()这个方法:
MemberwiseClone():
创建当前对象的浅表副本,该方法用来创建一个新的对象,然后将当前对象的非静态字段复制到新对象,如果该字段是值类型的,则对该字段执行逐位复制,如果该字段是引用类型的,则复制引用但不复制引用的对象。这样的操作称之为“浅复制”。
这样看来,名字是一个String类型的,就会复制成功,而武器类,是一个引用类型的,复制的是其引用,指向了同一个对象。但我们希望出现下面的结果:
我是孙悟空,我的武器是如意金箍棒,重量有一万三千五百斤。我是小猴子1,我的武器是木棒,重量有20斤。我是小猴子2,我的武器是铁棒,重量有50斤。
那又该怎么实现呢? 孙悟空因为有了分身的方法,才可以变出很多小猴子,那我们为什么不让武器类也能够分身呢,这样岂不是就会出现我们想要的结果!
代码如下:
原型类–神仙:
abstract class Prototype{ private String name; private Weapon weapon; public void display(); public abstract Prototype Clone();}
武器类:
class Weapon implements ICloneable(){ private String name; private String weight; public Prototype clone{ return (Prototype)this.MemberwiseClone(); }}
具体原型类–大圣
class SunWuKong extends Prototype implements ICloneable{ private String name; private Weapon weapon; private SunWuKong (Weapon weapon ){ this.weapon = (Weapon)weapon.clone(); } public void display(name,weapon){ System.out.printLn("我是"+this.name+",我的武器是"+weapon.name+",重量有"+weapon.weight+"。"); }; public Prototype clone{ return (Prototype)this.MemberwiseClone(); }}
故事上演:
public class Story{ public static void main(String[] args) { SunWuKong suk = new SunWuKong (); suk.setName("孙悟空"); suk.setWeapon(new Weapon("如意金箍棒",“一万三千五百斤”)) SunWuKong monkey1 = (SUnWuKong)suk.clone(); monkey1.setName("小猴子1"); monkey1.setWeapon(new Weapon("木棒",“20斤”)) SunWuKong monkey2 = (SUnWuKong)suk.clone(); monkey2.setName("小猴子2"); monkey2.setWeapon(new Weapon("铁棒",“50斤”)) suk.display(); monkey1.display(); monkey2.display(); } }
运行结果如下:
我是孙悟空,我的武器是如意金箍棒,重量有一万三千五百斤。我是小猴子1,我的武器是木棒,重量有20斤。我是小猴子2,我的武器是铁棒,重量有50斤
武器类和孙悟空类都实现了ICloneable接口,实现了深复制的效果。
欢迎大家评论指正,点击查看其他设计模式。
- 设计模式之原型
- 设计模式之原型
- 设计模式 之 原型
- 设计模式之原型
- 设计模式之原型
- 设计模式之原型模式
- 设计模式之原型模式
- 设计模式之-原型模式
- 设计模式之 原型模式
- 设计模式之原型模式
- 设计模式之原型模式
- 设计模式之原型模式
- 设计模式之原型模式
- 设计模式之原型模式
- 设计模式之--原型模式
- 设计模式之原型模式
- 设计模式之原型模式
- 设计模式之原型模式
- 欢迎使用CSDN-markdown编辑器
- 软件工程导论第十二章
- asp.net如何定时执行任务
- 初学者---Android 沉浸式(透明)状态栏适配
- 【Scikit-Learn 中文文档】决策树
- 设计模式之原型模式
- 算法作业系列10——Unique Substrings in Wraparound String
- Linux USB U盘热插拔挂载和卸载
- 使用json绘制世界人口地图
- 使用Nodejs抓取<<文心雕龙>>
- 大数据WEB阶段(六)MySql详解(二)
- 重新编译ClassLoader记录被加载的类
- strlen与sizeof的区别
- 【Scikit-Learn 中文文档】决策树