抽象工厂模式
(Abstract Factory):提供一个创建一系列相关或相互依赖的接口,而无需指定它们具体的类。
IFactory
是一个抽象工厂接口,它里面应该包含所有的产品创建的抽象方法。
业务逻辑与数据解耦
IUser接口的对象user
事先不知道是在访问哪个数据库,在程序中创建维护一个用户User表
同样增加一个Department部门表
优点
- 便于交接产品系列,就本例如果要更改数据库访问就直接更改具体工厂
- 让具体的创建实例的过程与客户端分开,客户端是通过它们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中。
#include <iostream>
#include <User.h>
#include <Department.h>
#include <IFactory.h>
#include <IUser.h>
#include <IDepartment.h>
#include <AccessFactory.h>
#include <SqlServerFactory.h>
using namespace std;
int main()
{
User *user = new User();
Department *department = new Department();
IFactory *factory = new AccessFactory();
IUser *iu = factory->CreateUser();
iu->Insert(user);
iu->GetUser(1);
IDepartment *id = factory->CreateDepartment(); #与具体的数据库访问解除了依赖
id->Insert(department);
id->GetDepartment(1);
getchar();
}
由简单工厂改进抽象工厂
由于对具体的类声明是固定的,修改声明需要全局修改,同时要增加项目是需要增加的类和修改的类很多。
在CreateUser和CreateDpartment函数中对对应输入db字符串,来swithc选择new不同的数据库对象。但是同样存在简单工厂的缺点,需要改动类DataAccess类内部内容。
用反射+配置文件方式实现(Java)
- 头部加using System.Reflection来引用Reflection反射。
Assembly.Load("程序集名称").CreateInstance("命名空间.类名称")
- 设置配置文件
添加一个App.config文件,内容如下。
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<!--配置文件,可以换成 Access或 Oracle -->
<add key="DB" value="sqlserver"/>
</appsettings>
</configuration>
再添加引用System.configuration,并在程序开头增加using System.Configuration;,然后更改DataAccess类的字段DB的赋值代码。
private static readonly string db = ConfigurationManager.AppSettings ["DB"];
在使用简单工厂的地方,都可以考虑用反射技术来去除switch或if,解除分支判断带来的耦合。反射技术的确可以很好地解决。