试想一个应用,在开发时使用的是MySQL数据库,由于各种原因现在需要将底层的数据库更改为Oracle。由于数据库使用的命名空间不同,用到的方法不同,所以很难直接进行替换,往往需要大量的时间进行代码的修改。因此,考虑将DAO层的设计尽可能的降低耦合,一个数据库有多个表,对每个表的操作分别进行封装,抽象出一个对该表进行操作的接口,然后不同的数据库类型(myslq、oracle...),分别进行实现。结合工厂方法模式,由工厂对具体实现的实例进行创建。
抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类 。
为了方便引进抽象工厂模式,引进一个新概念:产品族(Product Family)。所谓产品族,是指位于不同产品等级结构,功能相关联的产品组成的家族。如下UML图所示,AbstractProductA和AbstractProductB是两个不同的产品等级结构,ProductA1和ProductB1是一个产品簇。
抽象工厂(
Abstract Factory
)角色:担任这个角色的是工厂方法模式的核心,它是与应用系统商业逻辑无关的。
具体工厂(
Concrete Factory
)角色:这个角色直接在客户端的调用下创建产品的实例。这个角色含有选择合适的产品对象的逻辑,而这个逻辑是与应用系统的商业逻辑紧密相关的。
抽象产品(
Abstract Product
)角色:担任这个角色的类是工厂方法模式所创建的对象的父类,或它们共同拥有的接口。
具体产品(
Concrete Product
)角色:抽象工厂模式所创建的任何产品对象都是某一个具体产品类的实例。这是客户端最终需要的东西,其内部一定充满了应用系统的商业逻辑。
使用抽象工厂模式的情形:
(1)希望一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节时,即希望一个系统只是知道产品的接口,而不关心实现的时候。
(2)一个系统有多于一个的产品族,而系统只消费其中某一产品族
AbstractFactory模式与Factory模式的区别:
AbstractFactory模式是为创建
一组(有多类)相关或依赖的对象提供创建接口。
Factory模式是为一类对象提供创建接口
代码实例:
1. 两个表User和Department的实体类
public class User {
private int id;
private String userName;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public User(int id, String userName) {
super();
this.id = id;
this.userName = userName;
}
public User() {
super();
// TODO Auto-generated constructor stub
}
@Override
public String toString() {
return "User [id=" + id + ", userName=" + userName + "]";
}
}
public class Department {
private int id;
private String deptName;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
public Department() {
super();
// TODO Auto-generated constructor stub
}
public Department(int id, String deptName) {
super();
this.id = id;
this.deptName = deptName;
}
@Override
public String toString() {
return "Department [deptName=" + deptName + ", id=" + id + "]";
}
}
public interface IUserDao {
abstract void insert(User user);
abstract User select(int id);
}
public interface IDepartmentDao {
abstract void insert(Department dept);
abstract Department select(int id);
}
public class UserMysqlImpl implements IUserDao {
@Override
public void insert(User user) {
// TODO Auto-generated method stub
System.out.println("User: MySQL实现插入一条记录:"+user.toString());
}
@Override
public User select(int id) {
// TODO Auto-generated method stub
System.out.println("User: MySQL实现查询 :id = "+id);
return null;
}
}
public class UserOracleImpl implements IUserDao {
@Override
public void insert(User user) {
// TODO Auto-generated method stub
System.out.println("User: Oracle实现插入一条记录:"+user.toString());
}
@Override
public User select(int id) {
// TODO Auto-generated method stub
System.out.println("User: Oracle实现查询 :id = "+id);
return null;
}
}
4. IDepartmentDao的Mysql实现和oracle实现
public class DepartmentMySqlImpl implements IDepartmentDao {
@Override
public void insert(Department dept) {
// TODO Auto-generated method stub
System.out.println("Department: MySQL实现插入一条记录." + dept.toString());
}
@Override
public Department select(int id) {
// TODO Auto-generated method stub
System.out.println("Department: MySQL查询记录 id = " + id);
return null;
}
}
public class DepartmentOracleImpl implements IDepartmentDao{
@Override
public void insert(Department dept) {
// TODO Auto-generated method stub
System.out.println("Department: Oracle实现插入一条记录." + dept.toString());
}
@Override
public Department select(int id) {
// TODO Auto-generated method stub
System.out.println("Department: Oracle实现查询一条记录 id = " + id);
return null;
}
}
5. 抽象工厂接口
public interface IFactory {
abstract IUserDao createUser();
abstract IDepartmentDao createDepartment();
}
6. IFactory的具体实现
public class FactoryMySqlImpl implements IFactory {
@Override
public IDepartmentDao createDepartment() {
// TODO Auto-generated method stub
return new DepartmentMySqlImpl();
}
@Override
public IUserDao createUser() {
// TODO Auto-generated method stub
return new UserMysqlImpl();
}
}
public class FactoryOracleImpl implements IFactory {
@Override
public IDepartmentDao createDepartment() {
// TODO Auto-generated method stub
return new DepartmentOracleImpl();
}
@Override
public IUserDao createUser() {
// TODO Auto-generated method stub
return new UserOracleImpl();
}
}
7. Client端代码
public class abstractFactoryTest {
@Test
public void test(){
IFactory factory = new FactoryMySqlImpl();
IUserDao userDao = factory.createUser();
IDepartmentDao deptDao = factory.createDepartment();
User user = new User(1, "pathfiner");
Department dept = new Department(1, "aaa");
userDao.insert(user);
deptDao.select(1);
}
}