你的位置:首页 > ASP.net教程

[ASP.net教程](3)抽象工厂模式


工厂方法模是定义一个勇于创建对象的接口,让子类决定实例化哪一个类。

 

抽象工厂模式(Abstract Factory),提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类

 

抽象工厂模式构成

抽象工厂角色(AbstractFactory):声明生成抽象产品的方法

具体工厂角色(ConcreteFactory):执行生成抽象产品的方法,生成一个具体的产品

抽象产品(AbstactProduct):为一种产品声明接口

具体产品(ConcreteProduct):定义具体工厂生成的具体产品的对象,实现产品接口

客户角色(Client):我们的应用程序,使用抽象产品和抽象工厂生成对象

image

 

以KFC为例阐述抽象工厂模式的应用,假设现在KFC的食品直接没有任何关联,不可以分类,各个Product相互独立。这样工厂方法模式就可以很好解决,定义一系列的简单工厂,用户没要求一种食品就

使用一个合适的简单工厂来生产相应的Product就可以。

但实际情况下,KFC的产品还可以进行套餐出售,假设KFC的产品可以分为食品Food和饮料Drink,Food和Drink分别构成了一个产品族,一个产品族就是一系列相似对象的抽象。KFC出售2种套餐,

一种是经济型,包括鸡翅和可乐;另一种是豪华型,

包括鸡腿和咖啡。用户只需要指出需要的套餐名即可获得相应的Food和Drink。这种情况下,工厂方法模式将不再适用,而采用抽象工厂模式进行实现。

image

KFCFood.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace 抽象工厂模式_KFC_
{
    /// <summary>
    /// 产品1,KFC食品
    /// </summary>
    abstract class KFCFood
    {
        public abstract void DisPlay();
    }
}

Chicken.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace 抽象工厂模式_KFC_
{
  class Chicken : KFCFood
  {
    public override void DisPlay()
    {
      Console.WriteLine("鸡腿+1");
    }
  }
} 

Wings.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace 抽象工厂模式_KFC_
{
  class Wings : KFCFood
  {
    public override void DisPlay()
    {
      Console.WriteLine("鸡翅+1");
    }
  }
} 

KFCDrink.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace 抽象工厂模式_KFC_
{
  abstract class KFCDrink
  {
    public abstract void Display();
  }
} 

Coke.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace 抽象工厂模式_KFC_
{
  class Coke : KFCDrink
  {
    public override void Display()
    {
      Console.WriteLine("可乐+1");
    }
  }
} 

Coffee.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace 抽象工厂模式_KFC_
{
  class Coffce : KFCDrink
  {
    public override void Display()
    {
      Console.WriteLine("咖啡+1");
    }
  }
} 

IKFCFactory.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace 抽象工厂模式_KFC_
{
  /// <summary>
  /// 抽象工厂,生产套餐
  /// </summary>
  interface IKFCFactory
  {
     KFCFood CreateFood();
     KFCDrink CreteDrink();
  }
} 

CheapPackageFactory.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace 抽象工厂模式_KFC_
{
  /// <summary>
  /// 经济型套餐:鸡翅和可乐
  /// </summary>
  class CheapPackageFactory : IKFCFactory
  {
    public KFCFood CreateFood()
    {
      return new Wings();
    }

    public KFCDrink CreteDrink()
    {
      return new Coke();
    }
  }
} 

LuxuryPackageFactory.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace 抽象工厂模式_KFC_
{
  /// <summary>
  /// 豪华型套餐:鸡腿和咖啡
  /// </summary>
  class LuxuryPackageFactory : IKFCFactory
  {
    public KFCFood CreateFood()
    {
      return new Chicken();
    }

    public KFCDrink CreteDrink()
    {
      return new Coffce();
    }
  }
} 

Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace 抽象工厂模式_KFC_
{
  class Program
  {
    static void Main(string[] args)
    {
      IKFCFactory factory1 = new CheapPackageFactory();
      KFCFood food = factory1.CreateFood();
      food.DisPlay();
      KFCDrink drink = factory1.CreteDrink();
      drink.Display();
      Console.Read();
    }
  }
} 

 


这个在初始化的时候出现一次,如果需求增加来自功能,比如新增一个套餐。

还有客户端程序不可能只有一个吗如果一百个客户端调用访问的类,就要修改100次 IKFCFactory factory1 = new CheapPackageFactory();


所以我们用简单工厂可以改进抽象工厂

  class Order
  {
    private static readonly string db = "CheapPackage";
    //private static readonly string db = "LuxuryPackage";

    public static KFCFood CreateFood()
    {
      KFCFood result = null;
      switch (db)
      {
        case "CheapPackage":
          result = new Wings();
          break;
        case "LuxuryPackage":
          result = new Chicken();
          break;
      }
      return result;
    }

    public static KFCDrink CreteDrink()
    {
      KFCDrink result = null;
      switch (db)
      {
        case "CheapPackage":
          result = new Coke();
          break;
        case "LuxuryPackage":
          result = new Coffce();
          break;
      }
      return result;
    }
  } 

 

         KFCFood food = Order.CreateFood();
            food.DisPlay();
            KFCDrink drink = Order.CreteDrink();
            drink.Display();  

第2例:

 

用了抽象工厂模式的数据访问程序:

Client:使用AbstractFactory和AbstractProduct类声明的接口

User 和 Department

 

  /// <summary>
  /// 用户类
  /// </summary>
  class User
  {
    private int _id;

    public int Id
    {
      get { return _id; }
      set { _id = value; }
    }
    private string _name;

    public string Name
    {
      get { return _name; }
      set { _name = value; }
    }
  }

 

  class Department
  {
    private int _id;

    public int Id
    {
      get { return _id; }
      set { _id = value; }
    }
    private string _deptName;

    public string DeptName
    {
      get { return _deptName; }
      set { _deptName = value; }
    }
  } 

AbstractProduct:声明一类产品对象接口

IUser 和 IDepartment

  interface IUser
  {
    void Insert(User user);
    User GetUser(int id);
  } 
  interface IDepartment
  {
    void Insert(Department department);
    Department GetDepartment(int id);
  } 

 

Product:
定义一个被相应具体工厂创建的产品对象
实现AbstractProduct接口

SqlserverUser  AccessUser. SqlserverDepartment  AccessDepartment

  class SqlserverUser : IUser
  {
    public void Insert(User user)
    {
      Console.WriteLine("在 SQL SERVER 2008 中给User表增加一条记录");
    }

    public User GetUser(int id)
    {
      Console.WriteLine("在 SQL SERVER 2008 中根据ID得到User表一条记录");
      return null;
    }
  } 
  class AccessUser : IUser
  {
    public void Insert(User user)
    {
      Console.WriteLine("在 Access 中给User表增加一条记录");
    }

    public User GetUser(int id)
    {
      Console.WriteLine("在 Access 中根据ID得到User表一条记录");
      return null;
    }
  } 
  class SqlserverDepartment : IDepartment
  {
    public void Insert(Department department)
    {
      Console.WriteLine("在 SQLSERVER 2008中给Department 表增加一条记录");
    }
    public Department GetDepartment(int id)
    {
      Console.WriteLine("在 SQLSERVER 2008中根据ID得到 Department 表一条记录");
      return null;
    }
  } 
  class AccessDepartment : IDepartment
  {
    public void Insert(Department department)
    {
      Console.WriteLine("在 Access 中给Department 表增加一条记录");
    }
    public Department GetDepartment(int id)
    {
      Console.WriteLine("在 Access 中根据ID得到 Department 表一条记录");
      return null;
    }
  } 

 

AbstactFactory:声明一个创建抽象产品对象的操作接口

IFactory

  interface IFactory
  {
    IUser CreateUser();

    IDepartment CreateDepartment();
  } 

 

ConcreteFactory:实现创建具体产品对象的操作

SqlserverFactory、AccessFactory

  class SqlserverFactory : IFactory
  {
    public IUser CreateUser()
    {
      return new SqlserverUser();
    }

    public IDepartment CreateDepartment()
    {
      return new SqlserverDepartment();
    }
  } 
  class AccessFatory:IFactory
  {
    public IUser CreateUser()
    {
      return new AccessUser();
    }

    public IDepartment CreateDepartment()
    {
      return new AccessDepartment();
    }
  } 

 

        static void Main(string[] args)
        {
            User user = new User();
            Department dept = new Department();

            //IFactory factory = new SqlserverFactory(); //创建SQLSERVER
            IFactory factory = new AccessFatory();  //创建Access
            IUser iu = factory.CreateUser();

            iu.Insert(user);
            iu.GetUser(1);

            Console.WriteLine();

            IDepartment idpt = factory.CreateDepartment();
            idpt.Insert(dept);
            idpt.GetDepartment(1);

            Console.Read();
        }

 

 

 

 

 

 

 

 



来自为知笔记(Wiz)


附件列表