设计模式 - (3)抽象工厂模式(创建型)
工厂方法模是定义一个勇于创建对象的接口,让子类决定实例化哪一个类。
抽象工厂模式(Abstract Factory),提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类
抽象工厂模式构成
抽象工厂角色(AbstractFactory):声明生成抽象产品的方法
具体工厂角色(ConcreteFactory):执行生成抽象产品的方法,生成一个具体的产品
抽象产品(AbstactProduct):为一种产品声明接口
具体产品(ConcreteProduct):定义具体工厂生成的具体产品的对象,实现产品接口
客户角色(Client):我们的应用程序,使用抽象产品和抽象工厂生成对象

以KFC为例阐述抽象工厂模式的应用,假设现在KFC的食品直接没有任何关联,不可以分类,各个Product相互独立。这样工厂方法模式就可以很好解决,定义一系列的简单工厂,用户没要求一种食品就
使用一个合适的简单工厂来生产相应的Product就可以。
但实际情况下,KFC的产品还可以进行套餐出售,假设KFC的产品可以分为食品Food和饮料Drink,Food和Drink分别构成了一个产品族,一个产品族就是一系列相似对象的抽象。KFC出售2种套餐,
一种是经济型,包括鸡翅和可乐;另一种是豪华型,
包括鸡腿和咖啡。用户只需要指出需要的套餐名即可获得相应的Food和Drink。这种情况下,工厂方法模式将不再适用,而采用抽象工厂模式进行实现。

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;
} } 第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();
} } 附件列表

浙公网安备 33010602011771号