设计模式之Prototype的学习笔记

设计模式之Prototype的学习笔记
Prototype (原型模式)
抽象不应该依赖于实现细节,实现细节应该依赖于抽象。
 ------抽象A依赖于抽象B,实现细节b依赖于抽象B。
 动机(Motivation)
  在软件系统中,经常面临着“某些结构复杂的对象”的创建工作;由于需求的变化
 这些对象经常变量着剧烈的变化,但是它们却拥有比较稳定一致的接口。
 如何应对这种变化?如何向“客户程序(使用这些对象的程序)”隔离出
“这些易变对象”,从而使得“依赖这些易变对象的客户程序”不随着改变而
 改变?
 
 
 意图(Intent)
 使用原型实例指定创建对象的种类,然后通过拷贝这些原型来创建新的对象。
 先看一个例子:
 public  class GameSystem
  {
    public static void  Run()
      {
         //需要5个小兵
         NormalActor noramlActor1=new NormalActor();
         NormalActor noramlActor2=new NormalActor();
         NormalActor noramlActor3=new NormalActor();
  NormalActor noramlActor4=new NormalActor();
  NormalActor noramlActor5=new NormalActor();
        //需要两个飞人
        FlyActor flyActor1=new FlyActor();
        FlyActor flyActor2=new FlyActor();
       //需要潜水员
        WaterActor waterActor1=new WaterActor ();
        WaterActor waterActor2=new WaterActor ();
      }
  }

 上边的代码依赖关系很强,如果这个场景中就需要这么些类型的人
  整个场景都保持不变,ok上面的代码可以,没问题。
  但是需求往往需要变化的,比如我要6个小兵,或者再需要一类人。
 上边这种强依赖关系就不能满足要求了
 那又该如何来更改这个代码?
 再看一个例子:

  //抽象接口
  public abstract class NormalActor
  {
    public abstract NormalActor  Clone();
  }
  
  public abstract class FlyActor
  {
    public abstract FlyActor Clone();
  }
 
  
  public abstract  class WaterActor
  {
       public abstract WaterActor Clone();
  }
//具体实现
    public class NormalActorA:NormalActor
  {
          public override NormalActor Clone()
          {
             return (NormalActor)this.MemberwiseClone();
             }
  }
  
  public class FlyActorA:FlyActor
  {
      public override FlyActor Clone()
        {
             return (FlyActor)this.MemberwiseClone();
         }
  }
  
  public abstract class WaterActorA:WaterActor
  {
        public override WaterActor.Clone()
          {
             return (WaterActor)this.MemberwiseClone();
           }
  }
 
 

  public  class GameSystem
  {
    public static void  Run(NormalActor normalActor,
     FlyActor flyactor,
      WaterActor waterActor
    )//如果把参数定义成属性也可以的不影响设计模式的实现。
      {
         //需要5个小兵
         NormalActor noramlActor1=normalActor.Clone();//克隆
         NormalActor noramlActor2=normalActor.Clone();
         NormalActor noramlActor3=normalActor.Clone();
  NormalActor noramlActor4=normalActor.Clone();
  NormalActor noramlActor5=normalActor.Clone();
        //需要两个飞人
        FlyActor flyActor1=flyactor.Clone();
        FlyActor flyActor2=flyactor.Clone();
       //需要潜水员
        WaterActor waterActor1=waterActor.Clone();
        WaterActor waterActor2=waterActor.Clone();
      }
  }
 
 //客户程序
 class App
  {
      public static void Main()
     {
             GameSystem gamesystem=new GameSystem();
             gamesystem.Run(new NormalActorA(),
                             new FlyActorA(),
                             new WaterActorA())
 
     }
 }
 
 注意上边的代码中 MemberwiseClone 它是一个类的前拷贝。如类中的属性是
值类型比如说int a ,bety b, string s;这些属性定义的变量MemberwiseClone
克隆没有问题,如果类里面有一个数组 int [] a;MemberwiseClone 克隆的就是它
的地址了。这样克隆就会存在问题。

 如何解决这个问题?
 最差劲的做法就是先new 一个东西 然后一步步再把它们给复制过来。
 还有一种做法其实是蛮取巧的就是我们讲的那个用序列化的方式,其实序列化
就要求我们这样在这个类上声明这样一个标记,声明这样一个标记之后,可以
先将这样一个类序列化到这个内存流上然后再进行一个反序列化,那反序列化
得到的对象或原来的对象一定就是一个深拷贝关系

 Prototype 模式的几个要点
 Prototype 模式同样用于隔离类对象的使用者和具体类型(易变类)之间的耦合
关系,它同样要求这些易变类拥有稳定的接口。
prototype 模式对于“如何创建易变类的实体对象”采用“原型克隆”的方法
来做,他使得我们可以非常灵活地动态创建“拥有某些稳定接口”的新对象
---------所需工作仅仅是注册一个新类的对象(即原型),然后在任何
需要的地方不断地Clone。
prototype模式中的Clone 方法可以利用.net中的Object类的MemberwiseClone()
方法或者序列化来实现深拷贝。
 
有关创建型模式的讨论
 Singletion 模式解决的是实体对象个数的问题。出了Singletion
之外,其他创建型模式解决的都是new 的耦合关系。

Factory Method,Abstract Factory,Builder都需要一个额外的工厂类来
负责实例化“易变对象”,而Prototype则是通过一个原型(一个特殊的工厂类)
来克隆易变对象。
如果遇到“易变类”起初的设计通常从Factory Method开始,当遇到更多的复杂变化
时,再考虑重构为其他三种工厂模式(Abstract Factory,Builder,
Prototype)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值