Prototype原形(创建型模式)

mac2022-06-30  17

一、动机(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" />

四、代码(Code)

public   class  Game {   public static void Run()   {      NormalActor na1 = new NormalActor();      NormalActor na2 = new NormalActor();      NormalActor na3 = new NormalActor();      NormalActor na4 = new NormalActor();      NormalActor na5 = new NormalActor();      FlyActor fa1 = new FlyActor();      FlyActor fa2 = new FlyActor();   }  } // 步兵 public   class  NormalActor {} // 飞行兵 public   class  FlyActor {} // 重构1 public   abstract  AbstractNormalActor {} public   abstract  AbstractFlyActor {} public   class  Game {   public static void Run()   {      AbstractNormalActor na1 = new NormalActor();      AbstractNormalActor na2 = new NormalActor();      AbstractNormalActor na3 = new NormalActor();      AbstractNormalActor na4 = new NormalActor();      AbstractNormalActor na5 = new NormalActor();      AbstractFlyActor fa1 = new FlyActor();      AbstractFlyActor fa2 = new FlyActor();   }  } // 重构2 public   class  Game {   public static void Run(AbstractNormalActor na,AbstractFlyActor fa)   {      AbstractNormalActor na1 = na.clone();      AbstractNormalActor na2 = na.clone();      AbstractNormalActor na3 = na.clone();      AbstractNormalActor na4 = na.clone();      AbstractNormalActor na5 = na.clone();      AbstractFlyActor fa1 = fa.clone();      AbstractFlyActor fa2 = fa.clone();   }  } public   abstract  AbstractNormalActor {   public abstract AbstractNormalActor clone();} public   abstract  AbstractFlyActor {   public abstract AbstractFlyActor clone();} // 步兵 public   class  NormalActor {   public override AbstractNortalActor clone()   {      return (AbstractNortalActor)this.MemberwiseClone();   }} // 飞行兵 public   class  FlyActor {   public override AbstractFlyActor clone()   {      return (AbstractFlyActor)this.MemberwiseClone();   }} 现在Game仅仅依赖于抽象类而不依赖于具体实现类了 class  App {   void main()   {         AbstractNormalActor ana = new NormalActor();         AbstractFlyActor afa = new FlyActor();         Game.Run(ana,afa);   }}

注: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

相关资源:JAVA上百实例源码以及开源项目
最新回复(0)