using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace 工厂方法模式
{
/*
* 工厂方法模式意图:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法是一个类的实例化延迟到其子类
* 工厂方法模式实现要点:1、工厂模式有两种情况:一是Creator类是一个抽象类且它不提供它所声明的工厂方法的实现;
* 二是Creator是一个具体类,且它提供一个工厂方法的缺省实现。
* 2、工厂方法模式可以带参数
* 3、工厂的作用并不仅仅只是创建一个对象,它还可以做对象的初始化,参数的设置等。
* 4、通过继承创建具体产品,很多时候,每一种具体产品对于一个具体的工厂来创建。
*
* 工厂方法模式优点:1、抽象模式使得类具有良好的封装性,代码结构清晰,一个对象创建是有条件约束的,
* 如一个调用则需要一个具体产品对象,只要知道这个具体类的工厂方法就可以,而不用知道创建对象的具体过程,
* 特别是当创建的是一个有多个对象或由比较复杂算法创建的时候,可以大大降低模块间的耦合
*
* 2、扩展性好,在增加新的产品或修改原有的产品时,只要创建新的工厂或适当修改原来的工厂类就可以实现功能扩展了,
* 而无需修改其他地方
*
* 3、屏蔽产品类,即产品类的实现如何变化,调用者都不需要关心,它需要关心的仅仅是产品的接口,
* 只要接口保持不变,系统的上层模块就不要发生变化
*
* 4、厂方法模式是典型的解耦框架,因为高层模块只需要知道产品的抽象类或接口,其具体实现并不需要关心,
* 符合迪米特法则,不需要的就不要去交流(具体实现)也符合依赖倒置原则,只依赖产品的抽象类或接口,
* 当然也符合里氏替换原则,使用产品子类替换产品父类,只要实现了接口,当然没问题。
*
* 工厂方法模式缺点:1、虽然此模式是new一个对象的替代品,所以在所有需要生成对象的地方都可以用,
* 但当需要慎重考虑是否要增加一个工厂类进行管理,增加代码的复杂度,即每增加一个新的产品时,
* 都要创建一个新的工厂类,这无形中就增加了代码的复杂度和维护难度。
*
* 2、当需要创建多个不相关的产品时,必须创建不同的且不相关的工厂。
* 如在下例中,若要添加业务逻辑和Product的业务逻辑不同的产品时,则必须创建相应的抽象工厂和具体工厂。
*
* 工厂方法模式使用场景:1、需要灵活的、可扩展的框架是,可以考虑工厂方法模式。
* 2、在异构项目中使用时,可以减少与外围的耦合。
* 3、可以使用在测试取得开发的框架下。
*
* 工厂方法模式使用效果:1、工厂方法不再将与特定应用有关的类绑定到你的代码中代码仅处理Product接口,
* 因此它可以与用户定义的任何具体产品类一起使用。
* 2、为子类提供挂钩(hook)用工厂方法在一个类的内部出创建对象通常比直接创建对象更灵活。
* 3、工厂方法模式提供了一种通过面向对象的手法,将所要创建具体的创建工作延迟到了子类,
* 从而提供了一种有效的扩展车旅,较好的解决了这种紧耦合的关系。
* 4、为平行的类层次提供了连接方法(当一个类将它的一些职责委托给一个独立的类的时候,就产生了平行类层次)
*
* 工厂方法模式扩展:1、将工厂方法静态化便是简单工厂模式了。
* 2、延迟初始化,即在创建对象时,将创建的对象保存到一个容器(一般为缓存或链表之类的机构容器)中,
* 在需要时通过容器调用已创建的对象既可。
*
* 工厂方法模式实际应用技巧:1、使用接口或抽象类,即抽象工厂角色和抽象产品角色都可以选择有接口或抽象类实现。
* 2、使用多个工厂方法,即抽象工厂角色可以规定出多余一个的工程方法,
* 从而使具体的工程角色实现这些不同的工厂方法,这些方法可以提供不同的商业逻辑,
* 以满足提供不同的产品对象的任务。
* 3、产品的循环使用,即工厂方法总是调用产品类的构造函数以创建一个新的产品实实例,
* 然后将这个实例提供给客户端,而是实际情形中,工厂方法所做的事情可以相当复杂,
* 如在工厂方法中实现原子对象的复合组合等。常见的负责逻辑就是循环使用产品对象,
* 工厂将已经创建的产品登记或保存到一个聚集或容器中,然后根据可请求的产品专题,
* 从聚集或容器中查询,如果有满足要求的产品对象,就直接将产品返回客户端,
* 若果聚集或容器没有这样的产品对象,那么就创建一个新的满足要求的对象,
* 然后将这个对象登记或保存的聚集中,再返还给客户端。而在asp.net 的Http通道中的请求就是最典型的例子。
*
*/
/// <summary>
/// 产品的公共抽象类,也可以用接口实现
/// </summary>
public abstract class Product
{
/// <summary>
/// 定义产品的抽象方法
/// </summary>
public abstract void DoSomething();
}
/// <summary>
/// 具体产品类A
/// </summary>
public class ProductA : Product
{
public override void DoSomething()
{
//产品A的方法
}
}
/// <summary>
/// 具体产品类B
/// </summary>
public class ProductB : Product
{
public override void DoSomething()
{
//产品B的方法
}
}
/// <summary>
/// 公共的创建类,抽象实现,也可以用接口,此为工厂方法的核心
/// </summary>
public abstract class CreatorFactory
{
/// <summary>
/// 需要实现的工厂方法
/// </summary>
/// <returns></returns>
public abstract Product Create();
}
/// <summary>
/// 具体产品A的工厂实现类
/// </summary>
public class ProductAFactory : CreatorFactory
{
/// <summary>
/// 产品A的工厂方法
/// </summary>
/// <returns></returns>
public override ProductA Create()
{
return new ProductA();
}
}
/// <summary>
/// 具体产品B的工厂实现类
/// </summary>
public class ProductBFactory : CreatorFactory
{
/// <summary>
/// 产品B的工厂方法
/// </summary>
/// <returns></returns>
public override ProductB Create()
{
return new ProductB();
}
}
public class AppClient
{
public static void Main(string[] args)
{
CreatorFactory factory = new ProductAFactory();
Product productA = factory.Create();
productA.DoSomething();//将会调用ProductA的DoSomething()方法
//若要创建新的产品则
/*
CreatorFactory factory = new ProductBFactory();
ProductB productB = factory.Create();
*/
}
}
}