原汁原味设计模式-原型prototype
来源:互联网 发布:android源码里编译apk 编辑:程序博客网 时间:2024/05/22 04:43
原创文章,转载请标明来源。
原型模式不等于克隆
背景介绍
原型模式是被大多数人忽略的一个模式,一提到原型模式,大多数人的概念就是clone方法,其实这是不对的。clone只是原型模式实现过程中的一小部分,更重要的是原型模式的设计思想,以及应用场景。
当前的设计模式书籍中,更多的强调了clone,强调了浅拷贝和深拷贝的区别,以及clone带来的性能优势,其实这个方向是错误的。原型模式其实是很有趣、很实用的一个模式,下面我带大家来领略一下原型模式的魅力。
GOF的原文中举的例子是这样的:设计一个乐谱编辑器,乐谱编辑器有很多面板,如音符面板,和休止符面板。我这里找了一个小巧的乐谱编辑器,并打开了两个面板:音符和标记,如下:
用户可以从面板上选择一个组件,然后把它拖到左边的五线谱上。
我们假设这些组件的基类叫Graphic,它有两个子类:MusicalNote和Symbol,分别代表音符和标记。
我们的framework需要支持不同的组件,那么就面临一个问题:如何生成这些组件?
最简单的一个方式,是根据点击的面板来创建不同的对象:
switch(pos){
case 1:
p = new HalfNote();//半音符,Musical的子类
break;
case 2:
p = new **Symbol();
break;
default:
break;
}
以上这段可以封装为简单工厂。
或者采用标准的工厂模式,提供GraphicTool类,由不同的子类来生成不同的对象:
上面的方式会带来两个问题:
1. 类膨胀,每一个Graphic的子类都要有一个GraphicTool的子类。
2. 强相关性。考虑如果Graphic不是由framework来实现,而是交给外部实现,那么framework根本不知道有哪些具体实现类,也就没办法来实例化了。
使用原型模式来解决
为了解决上面的两个问题,我们可以使用原型模式。
我们把Graphic**及它的子类**的实例称为原型。
在面板初始化好后,就直接生成全系列的实例,即生成全部原型。
当用户点击面板的时候,调用原型的clone方法,来生成一个新实例,用这个新实例来进行绘制。
伪码如下: p = getCurPrototype(pos);//根据位置拿到原型
np = p.clone();//克隆一个新实例
np.draw();
为什么要clone
看到这里可能会有个疑惑,我们为什么要克隆一个新实例出来呢,直接使用现有的实例不可以吗?
答案是我们会对这个实例进行调整,比如设置音符的音高。如果是改面板的实例,就会带来全局的影响。因此克隆一个新实例的做法更加恰当。
- 原汁原味设计模式-原型prototype
- 设计模式 原型Prototype
- prototype(原型设计模式)
- 设计模式--Prototype(原型)
- Prototype(原型)设计模式
- 设计模式-prototype原型
- 设计模式 原型设计 Prototype
- 设计模式--原型模式(ProtoType)
- [设计模式]Prototype原型模式
- 设计模式--Prototype(原型模式)
- 设计模式 -- 原型模式Prototype
- 设计模式-原型模式(Prototype)
- [设计模式] 原型模式(Prototype)
- 设计模式-原型模式(Prototype)
- 【设计模式】-原型模式-Prototype
- 设计模式 原型模式 Prototype
- 设计模式:原型模式-prototype
- 设计模式---原型模式(Prototype)
- mycat分布式mysql中间件(分片规则)
- CentOS7 Magento 链接Redis提示:Connection to Redis failed after 2 failures
- android studio 断开与SVN的连接
- C/C++中static关键字作用总结
- Dalvik虚拟机与JVM的区别
- 原汁原味设计模式-原型prototype
- Sql Server 2008 分页思路
- 自定义dialog
- Tomcat服务器使用
- CSS格式化之段落排版
- block
- list集合去重的一种方法
- 如何从京东商品里获取需要的信息
- C#实现知乎登录、点赞、关注、退出、评论(一)登录