下面以一个公司的员工和部门在数据库中的访问模式来举例:
Tables:
//用户类
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; }
}
}
客户端访问的接口://部门类 class Department { public int id { get; set; } public string name { get; set; } }
//访问用户接口 interface IUser { void Insert(User user); //插入用户 User GetUser(int id); //获取用户 }
在Access和SqlServer两个数据库中的访问操作://访问部门接口 interface IDepartment { void Insert(Department department); Department GetDepartment(int id); }
//访问Access数据库的用户类 class AccessUser : IUser { public User GetUser(int id) { Console.WriteLine("从Access数据库中获取User!"); return null; } public void Insert(User user) { Console.WriteLine("在Access数据库中加入User!"); } }
//访问SqlServer数据库的类 class SqlserverUser : IUser { public User GetUser(int id) { Console.WriteLine("从Sql Server数据库中获取User!"); return null; } public void Insert(User user) { Console.WriteLine("在Sql Server数据库中加入User!"); } }
class AccessDepartment : IDepartment { public Department GetDepartment(int id) { Console.WriteLine("在Access中根据id获取Department表一条记录!"); return null; } public void Insert(Department department) { Console.WriteLine("在Access中给Department表增加一条记录!"); } }
class SqlserverDepartment : IDepartment { public Department GetDepartment(int id) { Console.WriteLine("在Sql Server中根据id获得Department表一条记录!"); return null; } public void Insert(Department department) { Console.WriteLine("在Sql Server中给Department表增加一条记录!"); } }
抽象工厂的实现:
//工厂接口,定义一个创建访问表对象的抽象的工厂接口 interface IFactory { IUser CreateUser(); IDepartment CreateDepartment(); }
//操作Access的工厂 class AccessFactory : IFactory { public IDepartment CreateDepartment() { return new AccessDepartment(); } public IUser CreateUser() { return new AccessUser(); } }
客户端程序代码://操作SqlServer的工厂 class SqlServerFactory : IFactory { public IDepartment CreateDepartment() { return new SqlserverDepartment(); } public IUser CreateUser() { return new SqlserverUser(); } }
抽象工厂模式的优点:1.易于交换产品系列,由于具体工厂类在应用中只需要在初始化的时候出现一次,这就使得改变一个应用中的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同的产品配置。2.它让具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户端代码中。缺点:如果需求是增加功能Func操作,那么需要增加多个类:Func信息类,访问接口类IFunc,Func的具体工厂类,还需要改动抽象工厂接口类等。class MainProgram { public void Main() { User user = new User(); IFactory factory = new SqlServerFactory(); //创建对应的工厂 IUser iu = factory.CreateUser(); //调用工厂方法 iu.Insert(user); iu.GetUser(user.ID); Console.ReadKey(); } }
实际开发中,我们经常使用“ 依赖注入”和“ 反射”来实现抽象工厂模式,可以去除switch和if条件判断带来的耦合。我们也经常使用到“ 反射+配置文件”的方式来实现。具体的实现思路不在这里细说了。