.NET简谈设计模式之(抽象工厂模式)

来源:互联网 发布:图片跟随鼠标晃动的js 编辑:程序博客网 时间:2024/06/06 12:49

简单工厂介绍:简单工厂就是将对象的实例化提取出来形成专门负责创建对象的独立的对象,我们称之为简单工厂。

抽象工厂:抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象

  这样的定义可能对熟悉抽象工厂的朋友来说一目了然,初学者可能迷糊。我们还是用图来形象的表示吧;

  这幅图的大概意思是:水果贩子有很多种,每种贩子都想批发自己要卖的水果。我们重点放在工厂这边,这里有好多工厂分别生产不同的水果。我们要对工厂进行抽象,似乎已经引导我们去提取抽象工厂的概念,工厂是具体的类,是专门负责生产某一种类型的水果,遵循设计模式所提倡的原则,我们要将变化的部分抽象出来。所以我们要对具体工厂进行抽象形成抽象工厂,抽象工厂定义统一的获取水果的接口,任何客户贩子都用这统一的接口进行批发水果。

  所有的客户通过抽象工厂定义的接口获取水果,我们下面用代码来进行讲解。

抽象工厂代码:

  • using System;  
  • using System.Collections.Generic;  
  • using System.Text;  
  • namespace ConsoleApplication1  
  • {  
  •     /// <summary>  
  •     /// 水果抽象工厂  
  •     /// </summary>  
  •     public abstract class FruitAbstractFactory  
  •     {  
  •         /// <summary>  
  •         /// 水果名称,表示哪种水果如:苹果、香蕉、橘子 
  •         /// </summary>  
  •         public string FruitName { getset; }  
  •         /// <summary>  
  •         /// 抽象方法,获取要批发水果的  
  •         /// </summary>  
  •         /// <returns>要批发的水果</returns> 
  •         public abstract string GetCurrentFruit();  
  •     }  
  • }
  • 苹果工厂代码:

  • using System;  
  • using System.Collections.Generic;  
  • using System.Text;  
  • namespace ConsoleApplication1  
  • {  
  •     /// <summary> 
  •     /// 苹果工厂  
  •     /// </summary> 
  •     public class AppleFactory : FruitAbstractFactory  
  •     {  
  •         public AppleFactory()  
  •         {  
  •             FruitName = "苹果";  
  •         }  
  •         /// <summary> 
  •         /// 重写基类的获取水果方法 
  •         /// </summary> 
  •         /// <returns>要批发的水果</returns> 
  •         public override string GetCurrentFruit()  
  •         {  
  •             return "给你:" + base.FruitName;  
  •         }  
  •     }  
  • }
  • 香蕉工厂代码:

  • using System;  
  • using System.Collections.Generic;  
  • using System.Text;  
  • namespace ConsoleApplication1  
  • {  
  •     /// <summary> 
  •     /// 香蕉工厂  
  •     /// </summary> 
  •     public class BananaFactory : FruitAbstractFactory  
  •     {  
  •         public BananaFactory()  
  •         {  
  •             FruitName = "香蕉";  
  •         }  
  •         public override string GetCurrentFruit()  
  •         {  
  •             return "给你:" + base.FruitName;  
  •         }  
  •     }  
  • }
  • 橘子工厂代码:

  • using System;  
  • using System.Collections.Generic;  
  • using System.Text;  
  • namespace ConsoleApplication1  
  • {  
  •     /// <summary>  
  •     /// 橘子工厂  
  •     /// </summary>  
  •     public class TangerineFactory : FruitAbstractFactory  
  •     {  
  •         public TangerineFactory()  
  •         {  
  •             FruitName = "橘子";  
  •         }  
  •         public override string GetCurrentFruit()  
  •         {  
  •             return "给你:" + base.FruitName;  
  •         }  
  •     }  
  • }
  • 模拟调用代码:

  • using System;  
  • using System.Collections.Generic;  
  • using System.Text;  
  • namespace ConsoleApplication1  
  • {  
  •     class Program  
  •     {  
  •         static void Main(string[] args)  
  •         {  
  •             FruitAbstractFactory fruitfactory = new AppleFactory();//苹果工厂 
  •             Console.WriteLine(fruitfactory.GetCurrentFruit());  
  •             Console.ReadLine();  
  •             fruitfactory = new BananaFactory();//香蕉工厂 
  •             Console.WriteLine(fruitfactory.GetCurrentFruit());  
  •             Console.ReadLine();  
  •             fruitfactory = new TangerineFactory();//橘子工厂 
  •             Console.WriteLine(fruitfactory.GetCurrentFruit());  
  •             Console.ReadLine();  
  •         }  
  •     }  
  • }
  • 实现要点

    l         抽象工厂将产品对象的创建延迟到它的具体工厂的子类。

    l         如果没有应对“多系列对象创建”的需求变化,则没有必要使用抽象工厂模式,这时候使用简单的静态工厂完全可以。

    l         系列对象指的是这些对象之间有相互依赖、或作用的关系,例如游戏开发场景中的“道路”与“房屋”的依赖,“道路”与“地道”的依赖。

    l         抽象工厂模式经常和工厂方法模式共同组合来应对“对象创建”的需求变化。

    l         通常在运行时刻创建一个具体工厂类的实例,这一具体工厂的创建具有特定实现的产品对象,为创建不同的产品对象,客户应使用不同的具体工厂。

    l         把工厂作为单件,一个应用中一般每个产品系列只需一个具体工厂的实例,因此,工厂通常最好实现为一个单件模式。

    l         创建产品,抽象工厂仅声明一个创建产品的接口,真正创建产品是由具体产品类创建的,最通常的一个办法是为每一个产品定义一个工厂方法,一个具体的工厂将为每个产品重定义该工厂方法以指定产品,虽然这样的实现很简单,但它确要求每个产品系列都要有一个新的具体工厂子类,即使这些产品系列的差别很小。

    优点

    l         分离了具体的类。抽象工厂模式帮助你控制一个应用创建的对象的类,因为一个工厂封装创建产品对象的责任和过程。它将客户和类的实现分离,客户通过他们的抽象接口操纵实例,产品的类名也在具体工厂的实现中被分离,它们不出现在客户代码中。

    l         它使得易于交换产品系列。一个具体工厂类在一个应用中仅出现一次——即在它初始化的时候。这使得改变一个应用的具体工厂变得很容易。它只需改变具体的工厂即可使用不同的产品配置,这是因为一个抽象工厂创建了一个完整的产品系列,所以整个产品系列会立刻改变。

    l         它有利于产品的一致性。当一个系列的产品对象被设计成一起工作时,一个应用一次只能使用同一个系列中的对象,这一点很重要,而抽象工厂很容易实现这一点。

    缺点

    l         难以支持新种类的产品。难以扩展抽象工厂以生产新种类的产品。这是因为抽象工厂几口确定了可以被创建的产品集合,支持新种类的产品就需要扩展该工厂接口,这将涉及抽象工厂类及其所有子类的改变。

    适用性

    在以下情况下应当考虑使用抽象工厂模式:

    l         一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有形态的工厂模式都是重要的。

    l         这个系统有多于一个的产品族,而系统只消费其中某一产品族。

    l         同属于同一个产品族的产品是在一起使用的,这一约束必须在系统的设计中体现出来。

    l         系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于实现。



    工厂只不过是对一个产品的封装

    而抽象工厂是对一系列相关产品的封装

     

     

    [王清培版权所有,转载请给出署名]