抽象工厂模式(Abstract Factory),提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类。
小例子:
/// <summary> /// 用于客户端访问,解除与具体数据库访问的耦合 /// </summary> interface IDepartment { void Insert(Department department); Department GetDepartment(int id); }
部门表:
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; } } }
/// <summary> /// IFactory接口定义一个创建访问User表对象的抽象的工厂接口 /// </summary> interface IFactory { IUser CreateUser(); IDepartment CreateDepartment(); }
/// <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; } } }
interface IUser { void Insert(User user); User GetUser(int id); }
/// <summary> /// 用户访问SQL server的Department /// </summary> class SqlserverDepartment : IDepartment { public void Insert(Department department) { Console.WriteLine("在SQL Server中给Department表增加一条记录"); } public Department GetDepartment(int id) { Console.WriteLine("在SQL Server中根据ID得到Department表一条记录"); return null; } }
/// <summary> /// 实现IFactory接口实例化sqlserverUser和sqlDepartment /// </summary> class SqlServerFactory : IFactory { public IUser CreateUser() { return new SqlserverUser(); } public IDepartment CreateDepartment() { return new SqlserverDepartment(); } }
/// <summary> /// 用户访问sql server的User /// </summary> class SqlserverUser : IUser { public void Insert(User user) { Console.WriteLine("在SQL Server中给User表增加一条记录"); } public User GetUser(int id) { Console.WriteLine("在SQL Server中根据ID得到User表一条记录"); return null; } }
class Program { static void Main(string[] args) { User user = new User(); Department dept = new Department(); IFactory factory = new SqlServerFactory (); //IFactory factory = new AccessFactory(); IUser iu = factory.CreateUser(); iu.Insert(user); iu .GetUser (1); IDepartment id = factory.CreateDepartment(); id.Insert(dept ); id.GetDepartment(1); Console.Read(); } }
优点:
易于交换产品系列,由于具体工厂类,在一个应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同的产品配置。
让具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离。不会出现在客户端代码中。
缺点:
增加新的功能的时候很麻烦,需要修改抽象工厂和所有的具体工厂类,对“开闭原则”的支持呈现倾斜性!