设计模式7-抽象工厂

抽象工厂模式Abstract Factory, 解决的是一系列相互依赖对象的创建.

动机

在软件系统中,经常面临着"一系列相互依赖的对象"的创建工作; 同时由于需求的变化,往往存在更多系列对象的创建工作.
抽象工厂,提供一个接口,让该接口负责创建一系列相互依赖对象的创建工作,无需指定他们具体的类.

实例

考虑一个数据库员工数据输出的类,

class EmployeeDataBaseOutput{
 public:
    vector<Employee> GetAllEmployees() {
        SqlConnection* connection = new SqlConnection();
        connection->ConnectionString = "...";
        SqlCommand* command = new SqlCommand();
        command->CommandText = "...";
        command->SetConnection(connection);
        SqlDataReader* reader = command->ExecuteReader();
        while(reader->Read()) {          
        }   
    }
};

目前只支持sql数据库的访问操作,考虑对其他数据库访问的支持,我们需要可以考虑继承的方法,定义基类,

class DataBaseConnctionInterface {

};
class DataBaseCommandInterface {

};
class DataBaseDataReaderInterface {

};
class SqlConnection : public DataBaseConnctionInterface {

};
class OracleConnection : public DataBaseConnctionInterface {

};
class SqlCommand:public DataBaseCommandInterface {

};
class OracleCommand : public DataBaseCommandInterface {
};
class SqlDataReader : public DataBaseDataReaderInterface {

};
class OracleDataReader : public DataBaseDataReaderInterface {

};

然后把类EmployeeDataBaseOutput::GetAllEmployees中的指针全部变为基类的指针.

class EmployeeDataBaseOutput{

 public:
    vector<Employee> GetAllEmployees() {
        DataBaseConnctionInterface* connection = new SqlConnection();
        connection->ConnectionString("...");
        DataBaseCommandInterface* command = new SqlCommand();
        command->CommandText("...");
        command->SetConnection(connection);
        DataBaseDataReaderInterface* reader = command->ExecuteReader();
        while(reader->Read()) {          
        }   
    }
};

同时考虑将new对象的操作替换掉,如果按照工厂模式的做法,需要定义工厂基类,然后派生出生成具体对象的工厂.

class DataBaseConnectionFactoryInterface {
 public: 
    virtual DataBaseConnctionInterface* CreatDataBaseConnection() = 0;
    ~DataBaseConnectionFactoryInterface() { }
};
class SqlConnectionFactory : public DataBaseConnectionFactoryInterface {
 public:
    virtual DataBaseConnctionInterface* CreatDataBaseConnection() {
        return new  SqlConnection();
    }
};
class OracleConnectionFactory : public DataBaseConnectionFactoryInterface {
 public:
    virtual DataBaseConnctionInterface* CreatDataBaseConnection() {
        return new OracleConnection();
    }
};
class DataBaseCommandFactoryInterface {
 public:
    virtual DataBaseCommandInterface* CreatDataBaseCommand()=0;
};
class SqlCommnadFactoryFactory : public DataBaseCommandFactoryInterface {
 public: 
    virtual DataBaseCommandInterface* CreatDataBaseCommand() {
        return new SqlCommand();
    }
};
class OracleCommandFactory : public DataBaseCommandFactoryInterface {
 public: 
     virtual DataBaseCommandInterface* CreatDataBaseCommand() {
        return new OracleCommand();
    }    
};

基于工厂,去掉EmployeeDataBaseOutput::GetAllEmployees中的new.

class EmployeeDataBaseOutput{
 private:
    DataBaseConnectionFactoryInterface* connect_factory_;
    DataBaseCommandFactoryInterface* command_factory_;

 public:
 EmployeeDataBaseOutput(DataBaseConnectionFactoryInterface* connect_factory,DataBaseCommandFactoryInterface* command_factory) : 
    connect_factory_(connect_factory),command_factory_(command_factory) { }
    
    vector<Employee> GetAllEmployees() {
        DataBaseConnctionInterface* connection = connect_factory_->CreatDataBaseConnection();
        connection->ConnectionString("...");
        DataBaseCommandInterface* command = command_factory_->CreatDataBaseCommand();
        command->CommandText("...");
        command->SetConnection(connection);
        DataBaseDataReaderInterface* reader = command->ExecuteReader();
        while(reader->Read()) {          
        }   
    }
};

但是这里我们需要注意的是,DataBaseConnectionFactoryInterface* connect_factory_; DataBaseCommandFactoryInterface* command_factory_;是有关联的,他们两个应该是相同类型的数据库,我们不能让connectionsqlcommandoracle.他们两个应该是统一的.
所以我们应该考虑.用一个同一个工厂来产生ConectCommand .我们现在把工厂进行一下修改.

class DataBaseFactoryInterface {
 public: 
    virtual DataBaseConnctionInterface* CreatDataBaseConnection() = 0;
    virtual DataBaseCommandInterface* CreatDataBaseCommand()=0;
    ~DataBaseFactoryInterface() { }
};

class SqlFactory : public DataBaseFactoryInterface {
 public:
    virtual DataBaseConnctionInterface* CreatDataBaseConnection() {
        return new  SqlConnection();
    }
    virtual DataBaseCommandInterface* CreatDataBaseCommand() {
        return new SqlCommand();
    }
};

class OracleFactory : public DataBaseFactoryInterface {
 public:
    virtual DataBaseConnctionInterface* CreatDataBaseConnection() {
        return new OracleConnection();
    }
    virtual DataBaseCommandInterface* CreatDataBaseCommand() {
        return new OracleCommand();
    }
};

继续更改EmployeeDataBaseOutput

class EmployeeDataBaseOutput{
 private:
    DataBaseFactoryInterface* data_base_factory_;

 public:
 EmployeeDataBaseOutput(DataBaseFactoryInterface* data_base_factory) : data_base_factory_(data_base_factory) { }
    
    vector<Employee> GetAllEmployees() {
        DataBaseConnctionInterface* connection = data_base_factory_->CreatDataBaseConnection();
        connection->ConnectionString("...");
        DataBaseCommandInterface* command = data_base_factory_->CreatDataBaseCommand();
        command->CommandText("...");
        command->SetConnection(connection);
        DataBaseDataReaderInterface* reader = command->ExecuteReader();
        while(reader->Read()) {          
        }   
    }
};

类图

在这里插入图片描述

总结

  • 如果没有应对多系列对象构建的需求变化,则没有必要使用AbstractFactory 模式,这时候使用简单工厂就可以
  • "系列对象"指的是在某一特定系列下的对象之间有相互依赖,或相互作用关系.
  • Abstract Factory 主要在于应对"新系列"的需求变动,难于应对新对象的需求变动.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值