抽象工厂模式(Abstract Factory Pattern):
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
AbstractFactory:抽象工厂。声明生成抽象产品的方法
ConcreteFactory:具体工厂。执行生成抽象产品的方法,生成一个具体的产品。
AbstractProduct:抽象产品。为一种产品声明接口。
Product:具体产品类。定义具体工厂生成的具体产品的对象,实现产品接口。
实例:
(1)大陆生态系统
把动物分成两类,一种食草,一种食肉。食肉动物吃食草动物。美洲狮属于食肉动物,野牛属于食草动物,
美洲狮猎吃野牛;非洲的狮子属于食肉动物,角马属于食草动物,狮子猎吃角马。
//食草动物--抽象产品类
public abstract class Herbivore
{
}
//食肉动物--抽象产品类
public abstract class Carnivore
{
//猎吃食草动物的方法
abstract public void Eat(Herbivore h);
}
//角马--具体产品类
public class Wildebeest : Herbivore
{
}
//狮子--具体产品类
public class Lion : Carnivore
{
public override void Eat(Herbivore h)
{
Console.WriteLine(this + " eats " + h);
}
}
//野牛--具体产品类
public class Bison : Herbivore
{
}
//狼----具体产品类
public class Wolf : Carnivore
{
public override void Eat(Herbivore h)
{
Console.WriteLine(this + " eats " + h);
}
}
//抽象工厂类--定义抽象创建产品类的接口
public abstract class ContinentFactory
{
abstract public Herbivore ConcreteHerBivore();
abstract public Carnivore ConcreteCarnivore();
}
//非洲大陆,有角马,狮子--具体的工厂类
public class AfricaFactory : ContinentFactory
{
public override Herbivore ConcreteHerBivore()
{
return new Wildebeest();
}
public override Carnivore ConcreteCarnivore()
{
return new Lion();
}
}
//美洲大陆,有狼,野牛--具体的工厂类
public class AmericaFactory : ContinentFactory
{
public override Herbivore ConcreteHerBivore()
{
return new Bison();
}
public override Carnivore ConcreteCarnivore()
{
return new Wolf();
}
}
public class AnimalWorld
{
private Herbivore _herbivore;
private Carnivore _carivore;
public AnimalWorld(ContinentFactory factory)
{
this._carivore = factory.ConcreteCarnivore();
this._herbivore = factory.ConcreteHerBivore();
}
public void RunFoodChain()
{
_carivore.Eat(_herbivore);
}
}
客户端调用
ContinentFactory africa = new AfricaFactory();
AnimalWorld world = new AnimalWorld(africa);
world.RunFoodChain();
ContinentFactory america = new AmericaFactory();
world = new AnimalWorld(america);
world.RunFoodChain();
(2)数据访问程序
//用户类
public 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; }
}
}
//抽象产品类--用于客户端访问,解除与具体数据库访问的耦合
public interface IUser
{
void Insert(User user);
User GetUser(int id);
}
//具体产品类--用于访问SQL Server的User
public class SqlServerUser : IUser
{
#region IUser 成员
public void Insert(User user)
{
Console.WriteLine("在Sql Server中给User表增加一条记录");
}
public User GetUser(int id)
{
Console.WriteLine("在Sql Server中根据ID得到User表一条记录");
return null;
}
#endregion
}
//具体产品类--用于访问Access的User
public class AccessUser : IUser
{
#region IUser 成员
public void Insert(User user)
{
Console.WriteLine("在Access中给User表增加一条记录");
}
public User GetUser(int id)
{
Console.WriteLine("在Access中根据ID得到User表一条记录");
return null;
}
#endregion
}
//部门类
public class DepartMent
{
private int _id;
public int Id
{
get { return _id; }
set { _id = value; }
}
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
}
//抽象产品类
public interface IDepartMent
{
void Insert(DepartMent department);
DepartMent GetDepartMent(int id);
}
//具体产品类
public class SqlServerDepartMent : IDepartMent
{
#region IDepartMent 成员
public void Insert(DepartMent department)
{
Console.WriteLine("在Sql Server中给DepartMent表增加一条记录");
}
public DepartMent GetDepartMent(int id)
{
Console.WriteLine("在Sql Server中根据ID得到DepartMent表一条记录");
return null;
}
#endregion
}
public class AccessDepartMent : IDepartMent
{
#region IDepartMent 成员
public void Insert(DepartMent department)
{
Console.WriteLine("在Access中给DepartMent表增加一条记录");
}
public DepartMent GetDepartMent(int id)
{
Console.WriteLine("在Access中根据ID得到DepartMent表一条记录");
return null;
}
#endregion
}
//抽象工厂--创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类
public interface IFactory
{
IUser CreateUser();
IDepartMent CreateDepartMent();
}
//具体工厂类--继承抽象工厂类,决定创建哪个子类
public class SqlServerFactory:IFactory
{
#region IFactory 成员
public IUser CreateUser()
{
return new SqlServerUser();
}
public IDepartMent CreateDepartMent()
{
return new SqlServerDepartMent();
}
#endregion
}
//具体工厂类--继承抽象工厂类,决定创建哪个子类
public class AccessFactory : IFactory
{
#region IFactory 成员
public IUser CreateUser()
{
return new AccessUser();
}
public IDepartMent CreateDepartMent()
{
return new AccessDepartMent();
}
#endregion
}
//引用--只需要抽象产品和抽象工厂类,与具体的产品类和具体工厂类无关
//减少耦合;使得细节与依赖抽象,抽象不依赖于细节(依赖倒转原则)
public class DataAccess
{
private IUser _iuser;
private IDepartMent _departMent;
private User user;
private DepartMent departMent;
public DataAccess(IFactory factory)
{
_iuser = factory.CreateUser();
_departMent = factory.CreateDepartMent();
user = new User();
departMent = new DepartMent();
}
public void RunUser(int id)
{
_iuser.Insert(user);
_iuser.GetUser(id);
}
public void RunDepartMent(int id)
{
_departMent.Insert(departMent);
_departMent.GetDepartMent(id);
}
}
客户端调用:
//数据访问程序
Console.WriteLine("SQL Server 访问:在客户端指定需要用什么来访问");
AbstractFactoryPattern.IFactory abstractfactory = new SqlServerFactory();
DataAccess dataaccess = new DataAccess(abstractfactory);
dataaccess.RunUser(1);
dataaccess.RunDepartMent(1);
Console.WriteLine();
Console.WriteLine("Access 访问:在客户端指定需要用什么来访问");
abstractfactory = new AccessFactory();
dataaccess = new DataAccess(abstractfactory);
dataaccess.RunUser(1);
dataaccess.RunDepartMent(1);
//用简单工厂来改进抽象工厂
//去除IFactory、SqlServerFactory、Accessfactory三个工厂类,用DataAccess2这个类代替
public class DataAccess2
{
//private static readonly string db = "SqlServer";
private static readonly string db = "Access";
public static IUser CreateUser()
{
IUser iuser=null;
switch(db)
{
case "SqlServer":
iuser=new SqlServerUser();
break;
case "Access":
iuser=new AccessUser();
break;
}
return iuser;
}
public static IDepartMent CreateDepartMent()
{
IDepartMent idepartment = null;
switch (db)
{
case "SqlServer":
idepartment = new SqlServerDepartMent();
break;
case "Access":
idepartment = new AccessDepartMent();
break;
}
return idepartment;
}
}
//用简单工厂来改进抽象工厂--引用
public class RunDataAccess2
{
private IUser _iuser;
private IDepartMent _departMent;
private User user;
private DepartMent departMent;
public RunDataAccess2()
{
_iuser = DataAccess2.CreateUser();
_departMent = DataAccess2.CreateDepartMent();
user = new User();
departMent = new DepartMent();
}
public void RunUser(int id)
{
_iuser.Insert(user);
_iuser.GetUser(id);
}
public void RunDepartMent(int id)
{
_departMent.Insert(departMent);
_departMent.GetDepartMent(id);
}
}
客户端调用:
Console.WriteLine("用简单工厂来改进抽象工厂,如果要换访问方式,只需修改简单工厂DataAccess2类");
RunDataAccess2 dataaccess2 = new RunDataAccess2();
dataaccess2.RunUser(1);
dataaccess2.RunDepartMent(1);
//用反射+抽象工厂
class ReflectionDataAccess
{
private static readonly string AssemblyName = "AbstractFactoryPattern";
private static readonly string db = "SqlServer";
public static IUser CreateUser()
{
string className = AssemblyName + "." + db + "User";
return (IUser)Assembly.Load(AssemblyName).CreateInstance(className);
}
public static IDepartMent CreateDepartMent()
{
string className = AssemblyName + "." + db + "DepartMent";
return (IDepartMent)Assembly.Load(AssemblyName).CreateInstance(className);
}
}
//用反射+抽象工厂--引用
public class RunReflectionDataAccess
{
private IUser _iuser;
private IDepartMent _departMent;
private User user;
private DepartMent departMent;
public RunReflectionDataAccess()
{
_iuser = ReflectionDataAccess.CreateUser();
_departMent = ReflectionDataAccess.CreateDepartMent();
user = new User();
departMent = new DepartMent();
}
public void RunUser(int id)
{
_iuser.Insert(user);
_iuser.GetUser(id);
}
public void RunDepartMent(int id)
{
_departMent.Insert(departMent);
_departMent.GetDepartMent(id);
}
}
客户端调用:
Console.WriteLine("用反射+抽象工厂,减少了Swith的判断,这样如果需要增加Oracle数据访问,不需要修改简单工厂类");
RunReflectionDataAccess reflectionDataAccess = new RunReflectionDataAccess();
reflectionDataAccess.RunUser(1);
reflectionDataAccess.RunDepartMent(1);