Prototype原形(创建型模式)

一、动机(Motivation)问题域
在软件系统中,经常面临着“某些结构复杂的对象”的创建工作;由于需求的变化,这些对象经常面临着剧烈的变化,但是它们却拥有比较稳定一致的接口。
如何应对这种变化?如何向“客户程序(使用这些对象的程序)”隔离出“这些易变对象”,从而使得“依赖这些易变对象的客户程序”不随着需求改变而改变?
二、意图(Intent)      解决方案
使用原型实例指定创建对象的种类,然后通过拷贝这些原型来创建新的对象。
三、结构(Structure)UML
<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />PIC076.jpg

四、代码(Code)

None.gif public   class  Game
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif   
public static void Run()
ExpandedSubBlockStart.gifContractedSubBlock.gif   
dot.gif{
InBlock.gif      NormalActor na1 
= new NormalActor();
InBlock.gif      NormalActor na2 
= new NormalActor();
InBlock.gif      NormalActor na3 
= new NormalActor();
InBlock.gif      NormalActor na4 
= new NormalActor();
InBlock.gif      NormalActor na5 
= new NormalActor();
InBlock.gif
InBlock.gif      FlyActor fa1 
= new FlyActor();
InBlock.gif      FlyActor fa2 
= new FlyActor();
ExpandedSubBlockEnd.gif   }
  
ExpandedBlockEnd.gif}

None.gif
// 步兵
None.gif
public   class  NormalActor
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedBlockEnd.gif}

None.gif
// 飞行兵
None.gif
public   class  FlyActor
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedBlockEnd.gif}

None.gif
// 重构1
None.gif
public   abstract  AbstractNormalActor
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedBlockEnd.gif}

None.gif
public   abstract  AbstractFlyActor
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedBlockEnd.gif}

None.gif
public   class  Game
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif   
public static void Run()
ExpandedSubBlockStart.gifContractedSubBlock.gif   
dot.gif{
InBlock.gif      AbstractNormalActor na1 
= new NormalActor();
InBlock.gif      AbstractNormalActor na2 
= new NormalActor();
InBlock.gif      AbstractNormalActor na3 
= new NormalActor();
InBlock.gif      AbstractNormalActor na4 
= new NormalActor();
InBlock.gif      AbstractNormalActor na5 
= new NormalActor();
InBlock.gif
InBlock.gif      AbstractFlyActor fa1 
= new FlyActor();
InBlock.gif      AbstractFlyActor fa2 
= new FlyActor();
ExpandedSubBlockEnd.gif   }
  
ExpandedBlockEnd.gif}

None.gif
// 重构2
None.gif
public   class  Game
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif   
public static void Run(AbstractNormalActor na,AbstractFlyActor fa)
ExpandedSubBlockStart.gifContractedSubBlock.gif   
dot.gif{
InBlock.gif      AbstractNormalActor na1 
= na.clone();
InBlock.gif      AbstractNormalActor na2 
= na.clone();
InBlock.gif      AbstractNormalActor na3 
= na.clone();
InBlock.gif      AbstractNormalActor na4 
= na.clone();
InBlock.gif      AbstractNormalActor na5 
= na.clone();
InBlock.gif
InBlock.gif      AbstractFlyActor fa1 
= fa.clone();
InBlock.gif      AbstractFlyActor fa2 
= fa.clone();
ExpandedSubBlockEnd.gif   }
  
ExpandedBlockEnd.gif}

None.gif
public   abstract  AbstractNormalActor
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif   
public abstract AbstractNormalActor clone();
ExpandedBlockEnd.gif}

None.gif
public   abstract  AbstractFlyActor
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif   
public abstract AbstractFlyActor clone();
ExpandedBlockEnd.gif}

None.gif
// 步兵
None.gif
public   class  NormalActor
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif   
public override AbstractNortalActor clone()
ExpandedSubBlockStart.gifContractedSubBlock.gif   
dot.gif{
InBlock.gif      
return (AbstractNortalActor)this.MemberwiseClone();
ExpandedSubBlockEnd.gif   }

ExpandedBlockEnd.gif}

None.gif
// 飞行兵
None.gif
public   class  FlyActor
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif   
public override AbstractFlyActor clone()
ExpandedSubBlockStart.gifContractedSubBlock.gif   
dot.gif{
InBlock.gif      
return (AbstractFlyActor)this.MemberwiseClone();
ExpandedSubBlockEnd.gif   }

ExpandedBlockEnd.gif}

None.gif现在Game仅仅依赖于抽象类而不依赖于具体实现类了
None.gif
class  App
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif   
void main()
ExpandedSubBlockStart.gifContractedSubBlock.gif   
dot.gif{
InBlock.gif         AbstractNormalActor ana 
= new NormalActor();
InBlock.gif         AbstractFlyActor afa 
= new FlyActor();
InBlock.gif         Game.Run(ana,afa);
ExpandedSubBlockEnd.gif   }

ExpandedBlockEnd.gif}

注:MemberwiseClone()方法是.net framework默认实现,是浅拷贝。对于值类型没有问题,但对于引用类型就会出现两个对象共用一个引用值的问题了,因为它们是克隆了引用类型的地址。所以引用类型的值相同。
解决这个问题之一是实现深度拷贝,如new一个对象,把当前对象的字段值一个一个赋给新的new对象。或者通过序列化的方式来做,这是一个取巧的过程。
我们假设上面的AbstractNormalActor和AbstractFlyActor不可以进行抽象了,是不同的对象。
五、Prototype模式的要点
Prototype模式同样用于隔离类对象的使用者和具体类型(易变类)之间的耦合关系,它同样要求这些“易变类”拥有“稳定的接口”。
Prototype模式对于“如何创建易变类的实体对象”采用“原型克隆”的方法来做,它使得我们可以非灵活地动态创建“拥有某些稳定接口”的新对象------所需工作仅仅是注册一个新类的对象(即原型),然后在任何需要的地方不断地Clone。
Prototype模式中的Clone方法可以利用.net中的Object类的MemberwiseClone()方法或者序列化来实现深拷贝。
六、创建型模式的总结
1.Singleton模式解决的是实体对象个数的问题。除了Singleton之外,其他创建型模式解决的都是New所带来的耦合关系。
2.Factory Method,Abstract Factory,Builder都需要一个额外的工厂类来负责实例化易变对象,而Prototype则是通过原型(一个特殊的工厂类)来克隆易变对象。
3.如果遇到“易变类”,起初的设计通过从Factory Method开始,当遇到更多的复杂变化时,再考虑重构为其它三种工厂模式(Abstract Factory,Builder,Prototype)。
有关更多的Factory Method,Abstract Factory,Builder之间的区别请看Builder模式一讲,原则上来讲Abstract Factory,Prototype可以相互替换,但如果用Prototype替换Abstract Factory,那么需要创建的对象应该是很容易克隆才行,最好是能用MemberwiseClone()方法,否则显示太复杂,不划算,但理论上是可行的。

转载于:https://www.cnblogs.com/hotsoho.net/articles/348069.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值