设计模式之创建型模式总结
创建型模式在软件工程中,是处理物件创建机制的设计模式。此类型模式试图根据适合的情况来决定建立物件。单纯的物件创建常会导致一些设计问题或增加设计的复杂度。创建型模式则借由控制物件的生成方式来解决这问题。
简单说创建型模式就是用来创建对象的的模式,抽象了实例化的过程。它帮助了一个系统如何独立的创建、组合和表示它的对象。
在《大话设计模式》中一共有5种创建型模式,它们分别是单例模式、工厂方法模式、抽象工厂模式、建造者模式和原型模式。
1. 单例模式
l 定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
l 单例模式的代码结构:
/// <summary> /// 描述:双重锁定单例模式 /// 作者:孙继鹏 /// 日期:2012年5月24日 /// </summary> public class DoubleLockSingleton { #region 字段 /// <summary> /// 静态实例 /// </summary> private static DoubleLockSingleton instance; /// <summary> /// 程序运行时辅助对象 /// </summary> private static readonly object syncRoot = new object(); #endregion #region 构造与析构 /// <summary> /// 私有构造函数 /// </summary> private DoubleLockSingleton() { } #endregion #region 方法 /// <summary> /// 获取唯一实例 /// </summary> /// <returns>唯一实例</returns> public static DoubleLockSingleton GetInstance() { //首先判断实例是否存在,不存在再加锁处理 if (instance == null) { lock (syncRoot) { if (instance == null) { instance = new DoubleLockSingleton(); } } } return instance; } #endregion }
l 单例模式的适用场景:
当在一个系统中某个类,只希望在同一时刻存在一个对象实例时,此时使用单例模式,能有效控制外部类对该对象实例的访问权限。
2. 工厂方法模式
l 定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类,使一个类的实例化延迟到子类中。
l 工厂方法模式的代码结构:
/// <summary> /// 描述:客户端使用工厂模式 /// 作者:孙继鹏 /// 日期:2012年5月24日 /// </summary> public class Client { public static void Operation() { IFactory operfactory = new ConcreteCreatorOne(); operfactory.FactoryMethod(); } } /// <summary> /// 描述:创建模式之二,工厂方法模式 /// 定义:定义一个创建对象的接口,让子类决定实例化哪一个类,使一个类的实例 化延迟到子类 /// 作者:孙继鹏 /// 日期:2012年5月24日 /// </summary> public class ConcreteCreatorOne:IFactory { #region 实现IFactory public void FactoryMethod() { Console.WriteLine("this is Product one"); } #endregion } /// <summary> /// 描述:创建模式之二,工厂方法模式 具体生产者 /// 定义:定义一个创建对象的接口,让子类决定实例化哪一个类,使一个类的实例化延迟到子类 /// 作者:孙继鹏 /// 日期:2012年5月24日 /// </summary> public class ConcreteCreatorTwo:IFactory { #region 实现IFactory public void FactoryMethod() { Console.WriteLine("this is Product Two"); } #endregion } /// <summary> /// 描述:同一的Product对象的接口 /// 作者:孙继鹏 /// 日期:2012年5月24日 /// </summary> interface IFactory { #region 方法 /// <summary> /// 统一的操作方式 /// </summary> void FactoryMethod(); #endregion }
l 工厂方法模式优点:
<1>它克服了简单工厂模式违背开放—封闭原则的缺点,又保持了封装对象的创建过程的优点。
<2>工厂类中包含了最大的逻辑判断,根据客户端的选择动态的创建所需的对象实例。
l 工厂方法模式缺点:
<1>因为动态创建还是牵涉到选择创建对象实例,所以选择问题还是未得到进一步的完善,最好与其他模式结合使用。
l 工厂方法模式适用场景:
<1>在软件系统中,经常面临着“某个对象”的创建工作,由于需求的变化,这个对象的具体实现经常面临着剧烈的变化,但是它却拥有比较稳定的接口,这时候提供一种封装机制来隔离出“这个易变对象”的变化,从而保持系统中“其他依赖该对象的对象”不随着需求的改变而改变。
<2>当一个类的创建需要委托其他的类实现,从而达到封装创建对象的行为时候.
3. 抽象工厂方法模式
l 定义: 提供创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类。
l 抽象工厂方法模式优点:
<1>实现了对接口编程,而不是对具体类编程目的。
<2>实现了依赖倒置的编程原则。
4. 建造者模式
l 定义:将一个复杂对象的构建和它的表示分离开,使得同样的构建过程可以创建不同的表示。
l 建造者模式代码结构:
/// <summary> /// 创建型模式之四:建造者模式 /// 描述:建造者抽象类,为各个具体建造者提供具体方法 /// 建造者模式定义:将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不 /// 同的表示 /// 作者:孙继鹏 /// 日期:2012年5月24日 /// </summary> public abstract class Builder { #region 方法 public abstract void BuildPartA(); public abstract void BuildPartB(); public abstract Product GetResult(); #endregion } /// <summary> /// 描述:具体建造者二,用于装配个部件 /// 作者:孙继鹏 /// 日期:2012年5月24日 /// </summary> public class ConcreteBuilderOne:Builder { #region 字段 private Product product = new Product(); #endregion #region 实现Builder方法 public override void BuildPartA() { product.Add("部件A"); } public override void BuildPartB() { product.Add("部件B"); } public override Product GetResult() { return product; } #endregion } /// <summary> /// 描述:具体建造者二,用于装配个部件 /// 作者:孙继鹏 /// 日期:2012年5月24日 /// </summary> public class ConcreteBuilderTwo:Builder { #region 字段 private Product product = new Product(); #endregion #region 实现Builder方法 public override void BuildPartA() { product.Add("部件C"); } public override void BuildPartB() { product.Add("部件D"); } public override Product GetResult() { return product; } #endregion } /// <summary> /// 描述:指挥者,构建一个使用Builder接口的对象 /// 作者:孙继鹏 /// 日期:2012年5月24日 /// </summary> public class Director { public void Constructor(Builder builder) { builder.BuildPartA(); builder.BuildPartB(); } } /// <summary> /// 描述:成品类,由多个部件组成 /// 作者:孙继鹏 /// 日期:2012年5月24日 /// </summary> public class Product { #region 字段 /// <summary> /// 用于存储部件集合 /// </summary> IList<string> parts = new List<string>(); #endregion #region 方法 /// <summary> /// 增加部件 /// </summary> /// <param name="part">部件</param> public void Add(string part) { parts.Add(part); } /// <summary> /// 显示 /// </summary> public void show() { foreach (string item in parts) { Console.WriteLine(item); } } #endregion }
l 建造者模式优点:
<1>更好的封装了对象实例的创建过程,只需要知道创建类型就行。
l 建造者模式的适用场景:
<1>当创建复杂对象的算法应该独立于该对象的组成部分以及他们的装配方式的时候
5. 原型模式
l 定义:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的实例。
l 原型模式的结构图:
l 原型模式的代码结构:
/// <summary> /// 描述:客户端调用类 /// 作者:孙继鹏 /// 日期:2012年5月24日 /// </summary> public class Client { public void Run() { ConcretePrototypeOne p1 = new ConcretePrototypeOne("i"); ConcretePrototypeOne c1 = (ConcretePrototypeOne)p1.Clone(); } } /// <summary> /// 描述:实现原型的具体模型类 /// 作者:孙继鹏 /// 日期:2012年5月24日 /// </summary> public class ConcretePrototypeOne:Prototype { #region 构造与析构 public ConcretePrototypeOne(string id) : base(id) { } #endregion #region 实现Prototype方法 public override Prototype Clone() { return (Prototype)this.MemberwiseClone(); } #endregion } /// <summary> /// 描述:创建型模式之五:原型模型的抽象类 /// 作者:孙继鹏 /// 日期:2012年5月24日 /// </summary> public abstract class Prototype { #region 构造与析构 public Prototype(string id) { this.ID = id; } #endregion #region 属性 public string ID { get; set; } #endregion #region 方法 public abstract Prototype Clone(); #endregion }
l 原型结构优点:
<1> Prototype模式允许客户只通过注册原型实例就可以将一个具体产品 类并入到系统中,客户可以在运行时刻建立和删除原型。
<2> Portotype模式具有给一个应用软件动态加载新功能的能力
l 原型模式适用场景:
<1>当一个系统应该独立于它的产品创建、构成和表示
<2>当在运行时动态加载实例化类的时候。
<3>当一个类实例只能有几种不同的状态组合中的一种时。
所有的创建型模式都具备两个主要规律:
一 它们都将系统使用哪些具体类的信息封装起来;
实现了面向对象设计中的封装性,使得实现不对外开发。
二 它们隐藏了这些类的实例是如何被创建和组织的。
外界对于这些对象只知道它们共同的接口,而不清楚其具体的实现细节。正因为如此,创建型模式在创建什么(what),由谁(who)来创建,以及何时(when)创建这些方面,都为软件设计者提供了尽可能大的灵活性。