设计模式 -- AbstractFactory(抽象工厂)
抽象工厂(Abstract Factory)
提供一个接口,让该接口负责创建一系列“性关系或相互依赖的对象”,无需指定他们的具体类。
在软件系统中,经常会面临着“一系列相互依赖的对象”的创建工作,同时由于需求的变化,往往存在着更多系列对象的创建工作。
假设需要写一个数据访问层,那么需要创建一系列对象,比如需要connection对象、command对象等等。同时在不同的数据库选择的时候,也存在变化的问题。所以以下代码是写死的代码,不能很好的适应未来变化。
原先
class SqlConnection {}
class SqlCommand {
public void setConnection(SqlConnection connection) {}
public SqlDataReader getSqlDataReader() {
return new SqlDataReader();
}
}
class SqlDataReader {
public boolean read() {
return true;
}
}
class EmployeeDAO{
void GetEmployees(){
SqlConnection connection =
new SqlConnection();
SqlCommand command =
new SqlCommand();
command.setConnection(connection);
SqlDataReader reader = command.getSqlDataReader();
while (reader.read()){
}
}
};
那么,为了应对数据库变化的情况,那么将数据库访问的一些对象进行向上抽象。
重构
//数据库访问有关的基类
interface IDBConnection {
void ConnectionString(String s);
};
interface IDBConnectionFactory {
IDBConnection CreateDBConnection();
};
interface IDBCommand {
};
interface IDBCommandFactory {
IDBCommand CreateDBCommand();
};
interface IDataReader {
};
interface IDataReaderFactory {
IDataReader CreateDataReader();
};
//支持SQL Server
class SqlConnection implements IDBConnection {
@Override
public void ConnectionString(String s) {
}
};
class SqlConnectionFactory implements IDBConnectionFactory {
@Override
public IDBConnection CreateDBConnection() {
return null;
}
};
class SqlCommand implements IDBCommand {
};
class SqlCommandFactory implements IDBCommandFactory {
@Override
public IDBCommand CreateDBCommand() {
return null;
}
};
class SqlDataReader implements IDataReader {
};
class SqlDataReaderFactory implements IDataReaderFactory {
@Override
public IDataReader CreateDataReader() {
return null;
}
};
//支持Oracle
class OracleConnection implements IDBConnection {
@Override
public void ConnectionString(String s) {
}
};
class OracleCommand implements IDBCommand {
};
class OracleDataReader implements IDataReader {
};
class EmployeeDAO {
public IDBConnectionFactory dbConnectionFactory;
public IDBCommandFactory dbCommandFactory;
public IDataReaderFactory dataReaderFactory;
public void GetEmployees() {
IDBConnection connection =
dbConnectionFactory.CreateDBConnection();
connection.ConnectionString("...");
IDBCommand command =
dbCommandFactory.CreateDBCommand();
}
};
对于上面的代码来说,把所有的数据库访问有关的对象都创建了基类,如果为了实现其他的数据库,只需要针对对应的基类派生出子类。那么,其实也就是每个对象的创建都使用了工厂模式。
现在已经能够很好的解决变化的问题,但是这时候存在一个新的问题,那就是,这一系列对象并不是彼此分隔的,比如MySQL的Connection对象对应着MySQL的Commend,如果使用错了,那么肯定会在运行时报错,无法完成我们想要达到的目的。那么这个问题该如何解决呢?
我们可以尝试把对应的一系列的对象放在同一个工厂类中,以此来避免出现这样的问题。
最终代码
//数据库访问有关的基类
interface IDBConnection{
};
interface IDBCommand{
};
interface IDataReader{
};
interface IDBFactory{
IDBConnection CreateDBConnection();
IDBCommand CreateDBCommand();
IDataReader CreateDataReader();
};
//支持SQL Server
class SqlConnection implements IDBConnection{
};
class SqlCommand implements IDBCommand{
};
class SqlDataReader implements IDataReader{
};
class SqlDBFactory implements IDBFactory{
public IDBConnection CreateDBConnection() {
return new SqlConnection();
}
public IDBCommand CreateDBCommand() {
return new SqlCommand();
}
public IDataReader CreateDataReader() {
return new SqlDataReader();
}
};
//支持Oracle
class OracleConnection implements IDBConnection{
};
class OracleCommand implements IDBCommand{
};
class OracleDataReader implements IDataReader{
};
class OracleDBFactory implements IDBFactory {
@Override
public IDBConnection CreateDBConnection() {
return new OracleConnection();
}
@Override
public IDBCommand CreateDBCommand() {
return new OracleCommand();
}
@Override
public IDataReader CreateDataReader() {
return new OracleDataReader();
}
}
class EmployeeDAO{
IDBFactory dbFactory;
void GetEmployees(){
IDBConnection connection =
dbFactory.CreateDBConnection();
IDBCommand command =
dbFactory.CreateDBCommand();
IDataReader reader = dbFactory.CreateDataReader(); //关联性
}
};
以上的代码不难看出,把对应的一套工厂封装在了一起,那么,这就是一种AbstractFactory的模式
总结
如果没有对应“多系列对象构建”的需求变化,则没有必要使用Abstract Factory 模式,这时候使用简单的工厂完全可以。
“系列对象”指的是在某一特定系列下的对象之间有相互依赖或作用关系。不同系列的对象之间不能相互依赖。
Abstract Factory 模式主要在于应对“新系列”的需求变动,其缺点在于难以应对“新对象”的需求变动。

浙公网安备 33010602011771号