- 建立型模式
- 简单工厂模式
- 工厂方法模式
- IOC与工厂方法模式的结合
- 泛型工厂
- 委托工厂
建立型模式
建立型模式能够隔离客户程序对须要实例化类型的依赖关系,这类模式通常经过将实例化具体对象的职责委托给第三方对象的方式,使得客户程序或者外部系统在得到所需的具体类型实例的同时,而没必要对其发生直接的引用。设计模式
建立型模式包括:markdown
- 工厂方法模式
- 单例模式
- 抽象工厂模式
- 建立者模式
- 原型模式
按照大多数设计模式书籍采用的顺序,首先从工厂方法模式开始。框架
简单工厂模式
简单工厂模式并无被纳入23种设计模式之列,但能够做为学习工厂方法模式前的预备。简单工厂模式在管理对象建立方面,提供的是最简单的方案,它仅仅简单的对不一样类对象的建立进行了一层薄薄的封装,客户程序在使用时,经过向简单工厂传递一个类型来指定要建立的对象,其UML类图以下: ide
Client须要的是具体的产品ConcreteProductA或者ConcreteProductB,若是直接new()就会依赖对象实例,引入简单工厂后,Client变成了依赖IProduct和SampleFactory。学习
代码示例:this
//产品接口 public interface IProduct { }; //具体产品 public class ConcreteProductA : IProduct { } public class ConcreteProductB : IProduct { } public enum Category { A, B } //简单工厂 public class SampleFactory { public IProduct Create(Category category) { switch (category) { case Category.A: return new ConcreteProductA(); case Category.B: return new ConcreteProductB(); default: throw new ArgumentOutOfRangeException(); } } }
调用:设计
[Test] public void SampleFactoryTest() { SampleFactory sampleFactory = new SampleFactory(); IProduct product = sampleFactory.Create(Category.A); Assert.AreEqual(product.GetType(), typeof(ConcreteProductA)); }
工厂方法模式
简单工厂模式中的工厂负责生产全部的产品类型,但若是工厂负责生产的产品只有一种,就能够进一步抽象了,这便出现了工厂模式。 GOF对工厂方法模式的描述是: Define an interface for creating an object, but let subclasses decide which class toinstantiate. Factory Method lets a class defer instantiation to subclasses.. — Design Patterns : Elements of Reusable Object-Oriented Software指针
工厂方法模式定义了一个抽象的工厂,它的子类实体工厂都有统一通用的工厂方法,用来生产具体的产品,这样就把类的实例化延迟到其子类。 工厂方法主要有四个角色:code
- 抽象产品类型(Product),工厂要加工的对象所具备的抽象特征实体。
- 具体产品类型(Concrete Product),实现客户程序所须要的抽象特质的类型,它就是工厂须要延迟实例的备选对象。
- 抽象工厂类型(IFactory),定义一个工厂方法的默认实现,它返回抽象产品类型。
- 具体工厂类型(Concrete Factory):从新定义了产品建立过程,返回具体产品类型。
UML类图 对象
代码示例:
//抽象产品类型 public interface IProduct { string Name { get; } //抽象产品所必须具备的特征 } //具体产品类型 public class ProductA : IProduct { public string Name { get { return "A"; } } } public class ProductB : IProduct { public string Name { get { return "B"; } } } //抽象工厂类型 public interface IFactory { IProduct Create(); //抽象的工厂描述 } //具体工厂类型 public class FactoryA : IFactory { public IProduct Create() { return new ProductA(); } } public class FactoryB : IFactory { public IProduct Create() { return new ProductB(); } }
调用:
public class Client1 { public void SomeMethod() { IFactory factory = new FactoryA(); IProduct product = factory.Create(); } }
客户程序须要使用IProduct的时候,只须要获取到IFactory,经过调用其统一制定的Create()方法就能够获取到具体的产品,具体须要哪一个产品由Factory决定。这样就隔离了客户程序对具体产品的依赖,但这里还有个问题是在获取IFactory的时候须要初始化具体的工厂,这样就对具体的工厂产生了依赖。
IOC与工厂方法模式的结合
为了解决上述问题,能够把IFactory做为客户程序的参数,而后采用依赖注入的方式将具体的工厂注入:
public class Client2 { private IFactory factory; public Client2(IFactory factory) { this.factory = factory; } public string SomeMethod() { IProduct product = factory.Create(); return product.Name; } }
这样客户程序就变成了真正地只依赖IFactory和IProduct了,但问题是不论采用哪一种依赖注入框架,都须要注册接口与实例的映射关系,那么这种方式就只是至关于把对具体产品的依赖“甩”到了“客户程序的客户程序”,怎么办呢,退无可退的时候,考虑把接口与实例的映射关系放到配置文件吧。
泛型工厂
上面的工厂方法模式中,每一个具体的工厂负责生产一种产品,且都实现了抽象工厂的Create()方法,因而借助泛型能够实现进一步的抽象:
public interface IFactory<T> { T Create(); //抽象的工厂描述 } public abstract class FactoryBase<T> : IFactory<T> where T : new() { public virtual T Create() { return new T(); } } public class ProductAFactory : FactoryBase<ProductA> { public override ProductA Create(){ return new ProductA(); } } public class ProductBFactory : FactoryBase<ProductB> { }
在抽象工厂和具体的工厂之间增长了支持泛型的FactoryBase,在这里实现了通用的Create()方法。若是某个具体工厂须要特殊的Create流程,只需重写虚方法便可。这样在工厂种类比较多而流程有大多相同的状况下,能够减小不少代码。
委托工厂
前面代码中的工厂生产的产品都是对象,若是须要生产的是方法呢,C#的委托机制能够方便地知足这种需求。 委托的本质是方法的指针,是对一类方法的抽象。因此委托自己就能够做为抽象产品的定义,而与委托签名一致的方法就是具体产品了。
代码示例:
public delegate int CalculateHandler(params int[] items); public class Calculator { public int Add(params int[] items) { int result = 0; foreach (var item in items) { result += item; } return result; } public int Multi(params int[] items) { int result = 1; foreach (var item in items) { result *= item; } return result; } } public class AddHandlerFactory : IFactory<CalculateHandler> { public CalculateHandler Create() { return new Calculator().Add; } } public class MultiHandlerFactory : IFactory<CalculateHandler> { public CalculateHandler Create() { return new Calculator().Multi; } }
调用:
[Test] public void CalculateHandlerTest() { CalculateHandler addHandler = new AddHandlerFactory().Create(); Assert.AreEqual(1 + 2 + 3, addHandler(1, 2, 3)); CalculateHandler multiHandler = new MultiHandlerFactory().Create(); Assert.AreEqual(1 * 2 * 3, multiHandler(1, 2, 3)); }
参考书籍: 王翔著 《设计模式——基于C#的工程化实现及扩展》