zoukankan      html  css  js  c++  java
  • c++ 设计模式9 (Abstract Factory 抽象工厂模式)

    5.2 抽象工厂模式

    动机:在软件系统中,经常面临着“一系列相互依赖的对象”的创建工作;同时,由于需求的变化,往往存在更多系列对象的创建工作。

    代码示例:

    实现利用数据库的业务逻辑,支持多数据库(Sql,Oracle等),有连接、命令、读取等功能。

    其中命令,连接功能之间有相互联系。

    方法一(使用工厂方法):

    每个功能类有一个创建的工厂,如IDBConnection与IDBConnectionFactory

    复制代码
     1 //数据库访问有关的基类
     2 class IDBConnection{
     3     
     4 };
     5 class IDBConnectionFactory{
     6 public:
     7     virtual IDBConnection* CreateDBConnection()=0;
     8 };
     9 
    10 
    11 class IDBCommand{
    12     
    13 };
    14 class IDBCommandFactory{
    15 public:
    16     virtual IDBCommand* CreateDBCommand()=0;
    17 };
    18 
    19 
    20 class IDataReader{
    21     
    22 };
    23 class IDataReaderFactory{
    24 public:
    25     virtual IDataReader* CreateDataReader()=0;
    26 };
    27 
    28 
    29 //支持SQL Server
    30 class SqlConnection: public IDBConnection{
    31     
    32 };
    33 class SqlConnectionFactory:public IDBConnectionFactory{
    34     
    35 };
    36 
    37 
    38 class SqlCommand: public IDBCommand{
    39     
    40 };
    41 class SqlCommandFactory:public IDBCommandFactory{
    42     
    43 };
    44 
    45 
    46 class SqlDataReader: public IDataReader{
    47     
    48 };
    49 class SqlDataReaderFactory:public IDataReaderFactory{
    50     
    51 };
    52 
    53 //支持Oracle
    54 class OracleConnection: public IDBConnection{
    55     
    56 };
    57 
    58 class OracleCommand: public IDBCommand{
    59     
    60 };
    61 
    62 class OracleDataReader: public IDataReader{
    63     
    64 };
    65 
    66 
    67 
    68 class EmployeeDAO{
    69     IDBConnectionFactory* dbConnectionFactory;
    70     IDBCommandFactory* dbCommandFactory;
    71     IDataReaderFactory* dataReaderFactory;
    72     
    73     
    74 public:
    75     vector<EmployeeDO> GetEmployees(){
    76         IDBConnection* connection =
    77             dbConnectionFactory->CreateDBConnection(...);
    78         connection->ConnectionString("...");
    79 
    80         IDBCommand* command =
    81             dbCommandFactory->CreateDBCommand(...);
    82         command->CommandText("...");
    83         command->SetConnection(connection); //关联性
    84 
    85         IDBDataReader* reader = command->ExecuteReader(); //关联性
    86         while (reader->Read()){
    87 
    88         }
    89 
    90     }
    91 };
    复制代码

    分析上述代码,虽然解决了组件创建的问题。但是仔细考虑,由于功能之间具有关联性,不同类型数据库的对象并不能同时创建搭配(如sql的command和oracle的connection搭配,显然不合理)。所以考虑抽象工厂模式。见方法二:

    使用一个工厂,将一系列相互依赖的的对象创建在一个工厂中实现。

    复制代码
     1 //数据库访问有关的基类
     2 class IDBConnection{
     3     
     4 };
     5 
     6 class IDBCommand{
     7     
     8 };
     9 
    10 class IDataReader{
    11     
    12 };
    13 
    14 
    15 class IDBFactory{
    16 public:
    17     virtual IDBConnection* CreateDBConnection()=0;
    18     virtual IDBCommand* CreateDBCommand()=0;
    19     virtual IDataReader* CreateDataReader()=0;
    20     
    21 };
    22 
    23 
    24 //支持SQL Server
    25 class SqlConnection: public IDBConnection{
    26     
    27 };
    28 class SqlCommand: public IDBCommand{
    29     
    30 };
    31 class SqlDataReader: public IDataReader{
    32     
    33 };
    34 
    35 
    36 class SqlDBFactory:public IDBFactory{
    37 public:
    38     virtual IDBConnection* CreateDBConnection()=0;
    39     virtual IDBCommand* CreateDBCommand()=0;
    40     virtual IDataReader* CreateDataReader()=0;
    41  
    42 };
    43 
    44 //支持Oracle
    45 class OracleConnection: public IDBConnection{
    46     
    47 };
    48 
    49 class OracleCommand: public IDBCommand{
    50     
    51 };
    52 
    53 class OracleDataReader: public IDataReader{
    54     
    55 };
    56 
    57 
    58 
    59 class EmployeeDAO{
    60     IDBFactory* dbFactory;
    61     
    62 public:
    63     vector<EmployeeDO> GetEmployees(){
    64         IDBConnection* connection =
    65             dbFactory->CreateDBConnection();
    66         connection->ConnectionString("...");
    67 
    68         IDBCommand* command =
    69             dbFactory->CreateDBCommand();
    70         command->CommandText("...");
    71         command->SetConnection(connection); //关联性
    72 
    73         IDBDataReader* reader = command->ExecuteReader(); //关联性
    74         while (reader->Read()){
    75 
    76         }
    77 
    78     }
    79 };
    复制代码

    模式定义:

    提供一个接口,让该接口复杂创建一系列”相关或者相互依赖的对象“,无需指定它们具体的类。

    类图:

    要点总结:

    如果没有应对”多系列对象构建“的需求变化,则没有必要使用Abstract Factory模式,这是要使用工厂方法即可。

    ”系列对象“指的是某一特定系列下的对象之间有相互依赖或作用的关系。不同系列的对象之间不能相互依赖。

    Abstract Factory模式主要在于应对”新系列“的需求变动。其缺点在于难以应对”新对象“的需求变动。

  • 相关阅读:
    ruby html解析器
    国外cdn
    ruby爬虫utf8编码相关
    Ruby 1.9 regex (named capture group)正则名组
    ruby爬虫综述
    ruby新加实例方法写法
    机房
    Net::HTTP Cheat Sheet
    ror一键安装包forwin
    病毒6655.la
  • 原文地址:https://www.cnblogs.com/yechanglv/p/6931009.html
Copyright © 2011-2022 走看看