创建型模式摘记

    xiaoxiao2023-12-29  162

    系统的演化应当依赖于组合,而不是继承;这就提出了将类的实例化委托给一个对象的要求,因此创建型模式将变的越来越重要。 创建型模式属于对象创建模型。所谓对象创建模型就是说将实例化的工作委托给另一个对象来做。与之相对应的是类创建模型,这是一种通过继承改变被实例化的类。        创建型模式有两个重要的特点: 1) 客户不知道创建的具体类是什么(除非看源代码) 2) 隐藏了类的实例是如何被创建和放在一起的 一。抽象工厂模式 1.意图:提供一个创建 一系列相关或相互依赖对象的接口,而无需指定它们的具体的类。 2.适用场景: 1)一个系统要独立于它的产品的创建、组合和表示时 2)一个系统要由多个产品系列中的一个来配置时 3)当你要强调一系列相关的产品对象的设计以便进行联合使用时 4)当你提供一个产品类库,而只想显示它们的接口而不是实现时 3.UML图——结构 4.效果: 1)分离了具体的类,通过抽象接口将客户与具体的类分离 2)易于交换产品系列 3)有利于产品的一致性 4)难以支持新种类的产品,比如我们现在有一个ProductC产品,我们需要增加类AbstractProductC,增加AbstractFactory:: CreanteProductC方法,并且两个产品系列的实际创建者ConCreateFactory1、ConCreateFactor2都要实现该方 法。 可以通过给方法加参数的方式来指明创建的是什么产品,这样客户代码就无需改变,只要传递不同的参数。AbstractFactory类只需要提供一个CreateProduct(const string& name)方法即可。 5.代码实现,以《深入浅出设计模式(java C#)》的动物工厂为例: using  System; namespace  AnimalWorld {      //  抽象大陆工厂      abstract   class  ContinentFactory     {          abstract   public  Herbivore CreateHerbivore();          abstract   public  Carnivore CreateCarnivore();     }      // 非洲大陆,有角马,狮子      class  AfricaFactory : ContinentFactory     {          override   public  Herbivore CreateHerbivore()         {              return   new  Wildebeest();         }          override   public  Carnivore CreateCarnivore()         {              return   new  Lion();         }     }      //  美洲大陆,有狼,野牛      class  AmericaFactory : ContinentFactory     {          override   public  Herbivore CreateHerbivore()         {              return   new  Bison();         }          override   public  Carnivore CreateCarnivore()         {              return   new  Wolf();         }     }      // 食草动物"      abstract   class  Herbivore     {     }      // 肉食动物"      abstract   class  Carnivore     {          // 猎食食草动物的方法          abstract   public   void  Eat( Herbivore h );     }      // 角马      class  Wildebeest : Herbivore     {     }      // 狮子"      class  Lion : Carnivore     {          // 重载猎食食草动物的方法          override   public   void  Eat( Herbivore h )         {             Console.WriteLine(  this   +   "  eats  "   +  h );         }     }      // 野牛      class  Bison : Herbivore     {     }      //      class  Wolf : Carnivore     {          // 重载猎食食草动物的方法          override   public   void  Eat( Herbivore h )         {             Console.WriteLine(  this   +   "  eats  "   +  h );         }     }      // 动物世界类      class  AnimalWorld     {          private  Herbivore herbivore;          private  Carnivore carnivore;          //  创建两种动物分类          public  AnimalWorld( ContinentFactory factory )         {             carnivore  =  factory.CreateCarnivore();             herbivore  =  factory.CreateHerbivore();         }          // 运行食物链          public   void  RunFoodChain()         {              // 肉食动物猎食食草动物             carnivore.Eat( herbivore );         }     }      ///   <summary>      ///  抽象工厂模式客户应用测试      ///   </summary>      class  GameApp     {         [STAThread]          static   void  Main( string [] args)         {              // 创造并运行非洲动物世界             ContinentFactory africa  =   new  AfricaFactory();             AnimalWorld world  =   new  AnimalWorld( africa );             world.RunFoodChain();              // 创造并运行美洲动物世界             ContinentFactory america  =   new  AmericaFactory();             world  =   new  AnimalWorld( america );             world.RunFoodChain();             Console.Read();         }     } } 二。Builder模式 1.意图:将一个 复杂对象的构建与它的表示相分离,使得同样的构建过程可以创建不同的表示(或者说产品) 2.适用场景: 1)当创建复杂对象的算法应该独立于改对象的组成部分以及它们的装配方式时 2)当构造过程必须允许被构造的对象有不同的表示时 3.UML图——结构 Director接受一个Builder子类对象,完成创建过程,并通知Builder对象返回以及构造好的产品。 4.效果: 1)可以使你改变一个对象的内部表示 2)构造代码和表示代码分开 3)可以对构造过程进行更精细的控制 5。实现:以一个车辆建造过程为例(C#) using  System; namespace  CarShop {      using  System;      using  System.Collections;      // 指挥者,Director      class  Shop{          public   void  Construct( VehicleBuilder vehicleBuilder ){             vehicleBuilder.BuildFrame();             vehicleBuilder.BuildEngine();             vehicleBuilder.BuildWheels();             vehicleBuilder.BuildDoors();         }     }      /*  "Builder 建造者",Builder     抽象建造者具有四种方法     装配框架     装配发动机     装配轮子     装配车门      */      abstract   class  VehicleBuilder     {          protected  Vehicle vehicle;          // 返回建造完成的车辆          public  Vehicle Vehicle{              get return  vehicle; }         }          abstract   public   void  BuildFrame();          abstract   public   void  BuildEngine();          abstract   public   void  BuildWheels();          abstract   public   void  BuildDoors();     }      // 具体建造者-摩托车车间      class  MotorCycleBuilder : VehicleBuilder     {          override   public   void  BuildFrame(){             vehicle  =   new  Vehicle(  " 摩托车 "  );             vehicle[  " frame "  ]  =   " MotorCycle Frame " ;         }          override   public   void  BuildEngine(){             vehicle[  " engine "  ]  =   " 500 cc " ;         }          override   public   void  BuildWheels(){             vehicle[  " wheels "  ]  =   " 2 " ;         }          override   public   void  BuildDoors(){             vehicle[  " doors "  ]  =   " 0 " ;         }     }      // 具体建造者-轿车车间      class  CarBuilder : VehicleBuilder     {          override   public   void  BuildFrame(){             vehicle  =   new  Vehicle(  " 轿车 "  );             vehicle[  " frame "  ]  =   " Car Frame " ;         }          override   public   void  BuildEngine(){             vehicle[  " engine "  ]  =   " 2500 cc " ;         }          override   public   void  BuildWheels(){             vehicle[  " wheels "  ]  =   " 4 " ;         }          override   public   void  BuildDoors(){             vehicle[  " doors "  ]  =   " 4 " ;         }     }      //  具体建造者-单脚滑行车车间      class  ScooterBuilder : VehicleBuilder     {          override   public   void  BuildFrame(){             vehicle  =   new  Vehicle(  " 单脚滑行车 "  );             vehicle[  " frame "  ]  =   " Scooter Frame " ;         }          override   public   void  BuildEngine(){             vehicle[  " engine "  ]  =   " none " ;         }          override   public   void  BuildWheels(){             vehicle[  " wheels "  ]  =   " 2 " ;         }          override   public   void  BuildDoors(){             vehicle[  " doors "  ]  =   " 0 " ;         }     }      // 车辆产品类      class  Vehicle     {          private   string  type;          private  Hashtable parts  =   new  Hashtable();          // 筑构函数,决定类型          public  Vehicle(  string  type ){              this .type  =  type;         }          // 索引          public   object   this string  key ]{              get return  parts[ key ]; }              set { parts[ key ]  =  value; }         }          // 显示方法          public   void  Show()         {             Console.WriteLine(  " \n--------------------------- " );             Console.WriteLine(  " 车辆类类型:  " +  type );             Console.WriteLine(  "  框架 :  "   +  parts[  " frame "  ] );             Console.WriteLine(  "  发动机 :  " +  parts[  " engine " ] );             Console.WriteLine(  "  #轮子数:  " +  parts[  " wheels " ] );             Console.WriteLine(  "  #车门数 :  " +  parts[  " doors "  ] );         }     }      ///   <summary>      ///  建造者模式应用测试      ///   </summary>       class  CarShop     {         [STAThread]          static   void  Main( string [] args)         {              //  创造车间及车辆建造者             Shop shop  =   new  Shop();             VehicleBuilder b1  =   new  ScooterBuilder();             VehicleBuilder b2  =   new  CarBuilder();             VehicleBuilder b3  =   new  MotorCycleBuilder();              //  筑构并显示车辆             shop.Construct( b1 );             b1.Vehicle.Show();             shop.Construct( b2 );             b2.Vehicle.Show();             shop.Construct( b3 );             b3.Vehicle.Show();             Console.Read();         }     } } 三。Factory Method模式 1.意图:定义一个用于创建对象的接口,让子类决定实例化具体的哪一个类。 2.适用场景: 1)当一个类不知道它所必须创建的对象的类的时候,让子类来决定 2)当一个类希望由它的子类来决定它所创建的对象的时候 3。UML图——结构: 4.效果: 1)为子类提供回调函数 2)连接平行的类层次 3) 创建函数可以接收参数来决定创建什么产品 4)Factory Method容易导致创建过多的Creator的子类以对应不同的产品,这个方法可以通过模板技术来解决 6.实现,手机工厂,产品可能是Nokia,也可能是Motorola using  System; using  System.Collections.Generic; using  System.Text; namespace  HandPhone {      // 手机接口      interface  Mobile     {           void  call();     }      // 手机工厂接口      interface  MobileFactory     {           Mobile createMobile();     }      // Nokia      class  Nokia:Mobile     {          public   void  call()         {             Console.WriteLine( " This is a {0} phone " this .GetType().Name);         }     }      // Motorola      class  Motorola : Mobile     {          public   void  call()         {             Console.WriteLine( " This is a {0} phone " this .GetType().Name);         }     }      // Motorola工厂      class  MotorolaFactory : MobileFactory     {           public  Mobile createMobile()         {              return   new  Motorola();         }     }      // Nokia工厂      class  NokiaFactroy : MobileFactory     {          public  Mobile createMobile()         {              return   new  Nokia();         }     }      public   class  Client     {          static   void  Main(String []args)         {             MobileFactory factory = null ;             Mobile mobile = null ;             factory = new  NokiaFactroy();             mobile = factory.createMobile();             mobile.call();             factory = new  MotorolaFactory();             mobile = factory.createMobile();             mobile.call();                      }     } } 四。Prototype模式 1.意图:通过原型实例指定创建对象的种类,并通过拷贝这些原型来创建新的对象 2.适用场景: 1)要实例化的类是在运行时刻指定的,比如动态装载 2)为了避免创建一个与产品层次平行的工厂类层次 3)当一个类的实例只能有几个不同的状态组合中的一种时,建立相应数目的原型并克隆它们可能比每次用合适的状态手工化该类更方便一些。 3.UML图——结构: 4.效果: 1)运行时动态增加或者删除产品 2)减少子类的构造数目 3)用类动态配置应用 4)动态指定新的对象,通过改变结构或者值 5)缺陷在于每一个Prototype的子类都需要实现clone操作 5。实现,无论java还是C#都从语言层次内置了对prototype模式的支持。具体不再详述。 五。singleton模式 1。意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点 2.适用场景: 1)当需要类只有一个实例,并且客户只能通过一个全局点去访问它 2)当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用扩展的实例 3.UML图:略 4.效果: 1)对唯一实例的受控访问 2)缩小命名空间 3)允许对操作和表示的细化 4)允许可变数目的实例 5实现,关于singleton在java多线程环境下的实现,请见讨论《 当Singleton遇到multi-threading》,C#对singleton多线程环境下的能够正确实现Double-checked模式: public   sealed   class  Singleton {      private   static   volatile  Singleton instance;      private   static   object  syncRoot  =   new  Object();      private  Singleton() {}      public   static  Singleton Instance     {          get           {              if  (instance  ==   null )              {                  lock  (syncRoot)                  {                      if  (instance  ==   null )                          instance  =   new  Singleton();                 }             }              return  instance;         }     } } 本文仅作速查记忆用,摘记于《设计模式——可复用面向对象软件基础》和《深入浅出设计模式(java C#)》两书 文章转自庄周梦蝶  ,原文发布时间5.17 相关资源:敏捷开发V1.0.pptx
    最新回复(0)