介绍:
抽象工厂(Abstract Factory):提供了一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的 类。
结构图:
AbstractProductA和AbstractProductB是两个抽象的产品,之所以为抽象,是因为它们都有可能有两种不同的实现。而ProductA1、ProductA2和ProductB1、ProductB2就是对两个抽象产品的具体分类的实现。
IFactory是一个抽象工厂的接口,它里面应该包括所有产品创建的抽象方法。而ConcreteFactory 1和ConcreteFactory 2就是具体的工厂了。
通常在运行时刻再创建一个ConcreteFactory类的实例,这个具体的工厂再创建具有特定实现的产品对象,也就是说,为创建不同的产品对象,客户端使用不同的具体工厂。
以大话设计模式一书中的例子
因为客户的需求使用不同的数据库来存储,所以这里为了保证每次更换使用不同的数据库避免改动大规模的修改代码
代码结构图
用户类
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; }
}
}
IUser接口,用于客户端访问,解除与具体数据库访问的耦合
interface IUser
{
void Insert(User user);
User GetUser(int id);
}
SqlserverUser类,用于访问SQL Server的User
class SqlserverUser : IUser
{
public void Insert(User user)
{
Console.WriteLine("在Sqlserver中给User表增加一条记录");
}
public User GetUser(int id)
{
Console.WriteLine("在Sqlserver中根据ID得到User表一条记录");
return null;
}
}
AccessUser类,用于访问Access的User
class AccessUser : IUser
{
public void Insert(User user)
{
Console.WriteLine("在Access中给User表增加一条记录");
}
public User GetUser(int id)
{
Console.WriteLine("在Access中根据ID得到User表一条记录");
return null;
}
}
IDepartment接口,用于客户端访问,解除与具体数据访问的耦合
interface IDepartment
{
void Insert(Department department);
Department GetDepartment(int id);
}
SqlserverDepartment类,用于访问SQL Server的Department
class SqlserverDepartment : IDepartment
{
public void Insert(Department department)
{
Console.WriteLine("在Sqlserver中给Department表增加一条记录");
}
public Department GetDepartment(int id)
{
Console.WriteLine("在Sqlserver中根据ID得到Department表一条记录");
return null;
}
}
AccessDepartment类,用于访问Access的Departmen
class AccessDepartment : IDepartment
{
public void Insert(Department department)
{
Console.WriteLine("在Access中给Department表增加一条记录");
}
public Department GetDepartment(int id)
{
Console.WriteLine("在Access中根据ID得到Department表一条记录");
return null;
}
}
class DataAccess
{
private static readonly string AssemblyName = "抽象工厂模式";
private static readonly string db = ConfigurationManager.AppSettings["DB"];
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);
}
}
效果图
在vs中的类图如下
如何读者亲自实践的话,需要添加引用(右键属性--添加--选择红框中的。单击确定)
优点:
1、封装性,每个产品的实现类不是高层模块要关心的。
2、产品族内的约束为非公开状态。
缺点:
1、产品族扩展非常困难。
使用场景:
一个对象族或是一组没有任何关系的对象都有相同的约束,则可以使用抽象工厂模式。