我读设计模式之抽象工厂模式(Abstract Factory)
大多时候,学习新的知识,只是看理论知识是很难理解的,如果这个时候,看两个实例,并同时自己动手去尝试做一下,效果会好很多~
在上次笔记中,用工厂方法模式实现了运行时对多数据库的切换。例子中的不同的数据库的数据访问类实现了统一的数据访问接口。但是,可以设想一下,在实际开发中,我们经常把数据访问类根据一定的情况划分为多个类(比如按照系统模块,每个模块设计一个自己的数据访问类)。而利用工厂方法模式的设计,我们这个时候就不得不为每个类设计抽象,设计工厂,这个工作量可想而知。对于这种一系列相关对象的创建,再使用工厂方法模式就不是很恰当了。
抽象工厂的目的是要提供一个创建一系列相关或相互依赖对象的接口。之前,在工厂方法模式中,我们的工厂接口只定义了一个返回数据访问接口的方法,现在我们利用抽象工厂模式创建一系列相关的对象创建方法(在工厂方法中每个工厂负责创建一个产品,在抽象工厂中每个工厂创建一系列产品)。
多说无益,现在仍然对多数据库访问进行扩展和抽象:把数据访问拆分为两个“模块”(user,department),这样user,department就是产品类,我们的多数据库对这个产品类进行实现,形成一个产品结构(关于这个概念的讲述,参照
http://www.cnblogs.com/Terrylee/archive/2005/12/13/295965.html)。
UML实现:
代码结构
{
class User //实体类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 //实体类Department
{
private int _deptid;
public int Deptid
{
get { return _deptid; }
set { _deptid = value; }
}
private string deptname;
public string Deptname
{
get { return deptname; }
set { deptname = value; }
}
}
interface Iuser ////抽象数据操作user
{
User GetUserInfor(int id);
void InsertUser(User user);
}
class SqlServerUser:Iuser //user具体类实现
{
public User GetUserInfor(int id)
{
Console.WriteLine("Get user infor from sql server by id");
return null;
}
public void InsertUser(User user)
{
Console.WriteLine("Insert into Sql server by user");
}
}
class OracleUser:Iuser //user具体类实现
{
public User GetUserInfor(int id)
{
Console.WriteLine("get user infor from oracle by id");
return null;
}
public void InsertUser(User user)
{
Console.WriteLine("Insert into Oracle By user");
}
}
interface Idepartment //抽象数据操作department
{
Department GetDeptInfor(int id);
void InsertDept(Department dept);
}
class SqlServerDept:Idepartment //department具体类实现
{
public Department GetDeptInfor(int id)
{
Console.WriteLine("Get Dept infor from sql server by id");
return null;
}
public void InsertDept(Department dept)
{
Console.WriteLine("insert into sql server by department");
}
}
class OracleDept:Idepartment //department具体类实现
{
public Department GetDeptInfor(int id)
{
Console.WriteLine("Get Dept infor from oracle by id");
return null;
}
public void InsertDept(Department dept)
{
Console.WriteLine("Insert into oracle by dept");
}
}
interface Ifactory //抽象工厂
{
Iuser GetUser();
Idepartment GetDept();
}
class OracleFactory:Ifactory //具体工厂类
{
public Iuser GetUser()
{
return new OracleUser();
}
public Idepartment GetDept()
{
return new OracleDept();
}
}
class SqlServerFactory:Ifactory //具体工厂类
{
public Iuser GetUser()
{
return new SqlServerUser();
}
public Idepartment GetDept()
{
return new SqlServerDept();
}
}
static void Main(string[] args) //程序入口
{
string factoryname = ConfigurationManager.AppSettings[0].ToString();
Ifactory factory = Assembly.Load("Demo2").CreateInstance("Demo2."+factoryname) as Ifactory;
Iuser u = factory.GetUser();
u.GetUserInfor(1);
Department dt = new Department();
Idepartment d = factory.GetDept();
d.InsertDept(dt);
}
}
<configuration>
<appSettings >
<add key ="factoryname" value ="OracleFactory"/>
</appSettings>
</configuration>
通过这样的设计,如果我们要扩充数据库(access),所做的工作仅为添加相应的数据访问类accessuser,accessdept
同时增加相应的工厂类accessfactory即可。
UML参考:
同时,可以看到,抽象工厂模式对于”产品“的扩展(比如说添加一个数据访问模块:manager),显得有点无能为力,我们不得不修改接口,修改工厂类....显然很不理想。
参考文章:
http://www.cnblogs.com/hobe/archive/2005/11/07/271026.html
http://www.cnblogs.com/bit-sand/archive/2008/01/31/1059270.html
http://www.cnblogs.com/Terrylee/archive/2005/12/13/295965.html
大话设计模式:抽象工厂模式