惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

罗磊的独立博客
Cisco Talos Blog
Cisco Talos Blog
C
Check Point Blog
博客园_首页
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Martin Fowler
Martin Fowler
Recorded Future
Recorded Future
S
Security @ Cisco Blogs
L
LINUX DO - 最新话题
博客园 - 司徒正美
P
Privacy International News Feed
G
Google Developers Blog
I
Intezer
Hacker News - Newest:
Hacker News - Newest: "LLM"
博客园 - 聂微东
The GitHub Blog
The GitHub Blog
C
Cybersecurity and Infrastructure Security Agency CISA
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Scott Helme
Scott Helme
K
Kaspersky official blog
I
InfoQ
Y
Y Combinator Blog
T
The Blog of Author Tim Ferriss
Webroot Blog
Webroot Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
大猫的无限游戏
大猫的无限游戏
D
Docker
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
W
WeLiveSecurity
Microsoft Azure Blog
Microsoft Azure Blog
Spread Privacy
Spread Privacy
量子位
H
Hacker News: Front Page
Simon Willison's Weblog
Simon Willison's Weblog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
SecWiki News
SecWiki News
S
Security Affairs
Latest news
Latest news
人人都是产品经理
人人都是产品经理
C
CERT Recently Published Vulnerability Notes
S
Security Archives - TechRepublic
V
Visual Studio Blog
T
Troy Hunt's Blog
S
Secure Thoughts
F
Fortinet All Blogs
V
V2EX
The Register - Security
The Register - Security
J
Java Code Geeks
MongoDB | Blog
MongoDB | Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO

博客园 - FrankFei

创采人力资源管理软件--产品简介 创采e-HR荣获江苏省高新技术产品认定 个人经典收藏网址 创采人事档案管理系统(ASP.NET+ExtJS) 创采应用框架开发平台--CFrame 创采人事管理软件--分布式的人力资源管理解决方案 创采e-HR合作经营 创采人事管理软件 创采人力资源管理系统 使用.Net和ExtJS技术开发的人力资源管理系统 ObjectBuilder中WeakRefDictionary使用模式浅析 ObjectBuilder应用之TypeMappingPolicy、SingletonPolicy ObjectBuilder中IBuilderPolicy和IBuilderStrategy之区别 ObjectBuilder模式浅析 NHibernate连接多数据库字符定义问题 优化GridView的查询、翻页性能 名言警句 折叠内容 [转]NUnit2.0详细使用方法
设计模式--Prototype
FrankFei · 2007-03-13 · via 博客园 - FrankFei

                                                                          FrankFei,2007年3月13日


一、引言
在商品房销售系统中,房屋信息是基础信息。在系统运行前必须输入房屋的各种信息到系统中,这是一项枯燥的重复劳动。如果让用户重复输入房间的类型、面积和卫生间样式,这个系统肯定尚未运行就夭折了。实际上,一个小区楼盘的样式并不多,不同的只是楼号。另外,楼盘中的房间类型也非常有限,从而为解决输入问题提供了启示。楼盘的逻辑结构如图所示。

一个小区包含多个楼盘,一个楼盘包括多层,一层包括多个房间。楼盘和房间都有自己的样式(这个模型忽略高档住宅和别墅),要解决的问题是如何创建这些类的实例,这些实例内部的数据基本相同。
方案一:手工输入,根据录入的数据实例化对象。
这个方案在增加用户痛苦的同时,并未给程序员带来更多的好处,不予考虑。
方案二:由用户输入一些基本信息和规则,由程序来实例化对象。
系统执行过程如下。
1、用户选择新增一个楼盘,系统创建楼盘实例。
2、用户输入一个房间的基本信息和需要自动生成的楼层,系统实例化这些信息,
然后增加到楼盘中。
3、用户重复第2步,直到输入整个楼盘的数据。
这个方案中的用户操作已经减少了很多,但仍有问题,如果一个小区的各个楼盘结构完全一样,那么如何自动生成?为此在用户界面上需要增加生成楼盘组,然后输入需要生成的数量及房间信息等,这样使得系统变得非常不灵活,无法扩充。例如,需要建立一个基本类似的小区。并且也很难去掉某些功能,例如不需要自动生成楼盘组。如果自动生成出现问题,例如房号的规则输入错误,则必须销毁对象后重新处理。虽然系统中已经存在一个现成的楼盘(例如一幢已经销售完成的楼盘与新楼盘结构一样),但是却无法使用。
从程序角度更是难以维护,每新增一级输入,都需要改动创建对象的工厂方法。
不幸的是,这种方案在重复输入信息的系统中经常被采用,从而导致系统变得难以维护。
方案三:拷贝/粘贴。
从用户的角度看,系统最好支持拷贝/粘贴。例如复制一个现成的楼盘,粘贴后只要修改楼号即可,或者复制多个楼层粘贴后自动增加到楼层中,这样用户的交互过程要简单很多。

二、概述

在软件系统中,有时候面临的产品类是动态变化的,而且这个产品类具有一定的等级结构。这时如果用工厂模式,则与产品类等级结构平行的工厂方法类也要随着这种变化而变化,显然不大合适。那么如何封装这种动态的变化?从而使依赖于这些易变对象的客户程序不随着产品类变化?

三、意图

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

四、Portotype模式的结构

Prototype:声明一个克隆自身的接口。
ConcretePrototype:实现一个克隆自身的操作。
Client:让一个原型克隆自身从而创建一个新的对象。

五、举例

例子一:个人觉得吕震宇老师的例子很容易理解,故直接引用如下:

例子二:

1、在运行时增加或删除产品:只要通过客户原型实例即可将新产品类型增加到系统中,例如组态软件中工具箱中的每个工具可以对应一个注册的原型对象,可以通过增加原形对象扩展工具箱。
2、很容易地创建复杂的对象:在图形编辑和组态等软件中,经常需要创建复杂的图元。这些图元是由简单图元组成的,采用原型模式可以很容易地将复杂图元作为一般图元来使用,使软件的工具箱具有自扩展功能。
3、减少工厂的层次:由于在.NET中可以使用反射工厂,因此这个优势并不明显。

七、缺点

1、在有些情况下克隆功能不容易实现,特别是遇到对象的循环引用时。

八、适用性

1、当一个系统应该独立于它的产品创建,构成和表示时;
2、当要实例化的类是在运行时刻指定时,例如,通过动态装载;
3、为了避免创建一个与产品类层次平行的工厂类层次时;
4、当一个类的实例只能有几个不同状态组合中的一种时。建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。

九、实现要点
1、使用原型管理器,体现在一个系统中原型数目不固定时,可以动态的创建和销毁,如上面的举的调色板的例子。
2、实现克隆操作,在.NET中可以使用Object类的MemberwiseClone()方法来实现对象的浅表拷贝或通 过序列化的方式来实现深拷贝。
3、Prototype模式同样用于隔离类对象的使用者和具体类型(易变类)之间的耦合关系,它同样要求这些“易变类”拥有稳定的接口。

十、使用场合

当一个系统应该独立于产品的创建、构成和表示时,可以使用原型模式。在原型模式中,产品的创建和初始化在类的Clone方法中完成。在使用时,我们可以用一些列原型对象来代替生成相应对象的工厂对象,并且可以使拷贝、粘贴等操作独立于需要复制的对象。

十一、.Net Framework中的应用

.NET中的很多类支持原型模式。例如我们希望获得一个与现有数据集结构相同的数据集,即可采用克隆的方法:
DataSet dsNew=ds.Clone()
注意,与数据相关的类还有一个方法Copy。与克隆不同,该方法不仅复制对象的结构,还复制对象中包含的数据,例如,我们希望复制现有数据集的结构和数据,则采用该方法:
Dsnew=ds.Copy()
使用Clone时,需要注意是深复制还是浅复制。.NET中实现IClone接口的类基本上都采用浅复制的策略,需要深复制的场合需要开发人员根据需要实现。

十二、总结

Prototype模式同工厂模式,同样对客户隐藏了对象的创建工作,但是,与通过对一个类进行实例化来构造新对象不同的是,原型模式是通过拷贝一个现有对象生成新对象的,达到了“隔离类对象的使用者和具体类型(易变类)之间的耦合关系”的目的。

参考文献
《敏捷软件开发-原则、模式与实践》 Robert C. Martin
《.Net与设计模式》 甄镭
《Java与模式》 阎宏
“网络资源”