抽象工厂模式
抽象工厂模式在工厂方法模式的基础上进行了改进,它提供了一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
使用抽象工厂模式实现数据库切换例子如下:
首先定义两个对象的接口和它的多个具体的实现
public interface IUser
{
void Insert(string name);
IUser GetUser(int id);
}
public interface IDepartment
{
void Insert(string name);
IDepartment GetDept(int id);
}
public class SQLServerUser : IUser
{
#region IUser 成员
public void Insert(string name)
{
Console.WriteLine("Insert sqlserver user");
}
public IUser GetUser(int id)
{
Console.WriteLine("Get sqlserver user");
return null;
}
#endregion
}
public class AccessUser : IUser
{
#region IUser 成员
public void Insert(string name)
{
Console.WriteLine("Insert access user");
}
public IUser GetUser(int id)
{
Console.WriteLine("Get access user");
return null;
}
#endregion
}
public class SQLServerDepartment : IDepartment
{
#region IDepartment 成员
public void Insert(string name)
{
Console.WriteLine("Insert sqlserver department");
}
public IDepartment GetDept(int id)
{
Console.WriteLine("Get sqlserver department");
return null;
}
#endregion
}
public class AccessDepartment : IDepartment
{
#region IDepartment 成员
public void Insert(string name)
{
Console.WriteLine("Insert access department");
}
public IDepartment GetDept(int id)
{
Console.WriteLine("Get access department");
return null;
}
#endregion
}
然后定义抽象工厂接口,和具体的工厂,具体的工厂负责创建一系列相关的对象
public interface IFactory
{
IUser UserData();
IDepartment DeptData();
}
public class SQLServerFactory : IFactory
{
#region IFactory 成员
public IUser UserData()
{
return new SQLServerUser();
}
public IDepartment DeptData()
{
return new SQLServerDepartment();
}
#endregion
}
public class AccessFactory : IFactory
{
#region IFactory 成员
public IUser UserData()
{
return new AccessUser();
}
public IDepartment DeptData()
{
return new AccessDepartment();
}
#endregion
}
客户端使用不同的工厂实例,完成一系列产品对象的创建
//实例化Sqlserver数据库访问对象
//IFactory factory = new SQLServerFactory();
//实例化Access数据库访问对象, 两个工厂对象二选一
IFactory factory = new AccessFactory();
IUser userData = factory.UserData();
userData.Insert("test");
userData.GetUser(1);
IDepartment deptData = factory.DeptData();
deptData.Insert("test");
deptData.GetDept(1);
抽象工厂方法的优点是便于交换产品系列,由于具体工厂类在一个应用中只需要在初始化的时候出现一次,所以改变一个应用的具体工厂变得非常容易,只需要改变具体工厂即可。
另外,由于它让具体的创建实例过程与客户端分离,客户端是通过抽象借口操纵实例的,产品的具体类名也被具体工厂的实现分离,不会出现在客户端代码中。
但是抽象工厂方法在需要初始化很多次的时候则是不便使用的,这是则可以使用简单工厂加配置和反射。
下面将抽象工厂改为简单工厂加配置和反射完成
/// <summary>
/// 简单工厂模式结合反射,使用反射避免了switch case 的判断
/// </summary>
public class SimplyFactory
{
private static string assemblyName = "AbstractFactoryModel";
//该字符串可以使用配置文件
private static string dbType = "SQLServer";
public IUser UserData()
{
IUser userData = (IUser)Assembly.Load(assemblyName).CreateInstance(assemblyName + "." + dbType + "User");
return userData;
}
public IDepartment DeptData()
{
IDepartment deptData = (IDepartment)Assembly.Load(assemblyName).CreateInstance(assemblyName + "." + dbType + "Department");
return deptData;
}
}
在需要更改实例化的对象时,不需要修改代码,而只需要修改配置文件即可,客户端的使用如下:
//实例化时无需制定任何类型,全部由工厂根据配置实现
SimplyFactory factory = new SimplyFactory();
IUser userData = factory.UserData();
IDepartment deptData = factory.DeptData();
userData.Insert("test");
userData.GetUser(1);
deptData.Insert("test");
deptData.GetDept(1);
这样,客户端在需要实例化多个工厂的时候,只需要修改配置文件,不需要修改每一个实例化代码。

浙公网安备 33010602011771号