• 抽象工厂


    概述:

    抽象工厂方法是工厂方法模式的延伸,它提供了功能更为强大的工厂类并且具备较好的可扩展性;

    优点:

    1、抽象工厂模式隔离了具体类的生成,使得客户端并不需要知道什么被创建。

    2、当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一产品族中的对象;

    3、增加新的产品族很方便,无需修改已有系统代码,符合开闭原则;

    缺点:

    1、增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,违背了开闭原则;

    适用环境:

    1、用户无需关心对象的创建过程,将对象的创建和使用解耦;

    2、产品等级结构稳定,在设计完成之后不会向系统中增加新的产品等级结构或者删除已有的产品等级结构;  

    3、系统中有多于一个的产品族,而每次只使用其中某一产品族。可以通过配置文件等方式来使用户能够动态改变产品族,也可以很方便的增加新的产品族;

    代码一(未经设计模式更改的代码):

    EmployeeDAO1.cpp

    class EmployeeDAO{
    public:
        vector<EmployeeDAO> GetEmployees(){
            SqlConnectionn connection = new SqlConnection(); //建立数据库的连接
            connnection->ConnectionString = "...";
    
            SqlCommand* command = new SqlCommand(); //建立数据库的命名对象
            command->CommandText = "...";
            commend->SetConnection(connection);
    
            SqlDataReader* reader = command->ExcuteReader();
            while (reader->Read()){
    
            }
        }
    };

    现在有需求了,就是想让该数据库操作适合DB2、Oracle、Mysql等数据库,该普通工厂的方法为

    EmployeeDAO2.cpp

    //数据库访问有关的基类
    class IDBConnection{
    
    };
    
    class IDBConnectionFactory{
    public:
        virtual IDBConnection* CreateDBConnection() = 0;
    };
    
    class IDBConmmand{
    
    };
    
    class IDBConmmandFactory{
    public:
        virtual IDBConmmand* CreateDBConmmand() = 0;
    };
    
    class IDataReader{
    
    };
    
    class IDataReaderFactory{
    public:
        virtual IDataReader* CreateDataReader() = 0;
    };
    
    //支持SQL Server
    class SqlConnection :public IDBConnection{
    
    };
    class SqlConnectionFactory :public IDBConnectionFactory{
    
    };
    
    class SqlCommand :public IDBConmmand{
    
    };
    class SqlCommandFactory :public IDBConmmandFactory{
    
    };
    
    class SqlDataReader :public IDataReader{
    
    };
    class SqlDataReaderFactory :public IDataReaderFactory{
    
    };
    
    //支持 Oracle
    class OracleConnection :public IDBConnection{
    
    };
    
    class OracleCommand :public IDBConmmand{
    
    };
    
    class OracleDataReader :public IDataReader{
    
    };
    
    class EmployeeDAO{
    
        IDBConnectionFactory* dbConnectionFactory;
        IDBConmmandFactory* dbConmmandFactory;
        IDataReader* dataReaderFactory;
    
    public:
        vector<EmployeeDAO> GetEmployees(){
            IDBConnection connection = dbConnectionFactory->CreateDBConnection; //建立数据库的连接
            connnection->ConnectionString = "...";
    
            IDBCommand* command = dbConmmandFactory->CreateDBConmmand; //建立数据库的命名对象
            command->CommandText = "...";
            commend->SetConnection(connection);
    
            IDBDataReader* reader = command->ExcuteReader();
            while (reader->Read()){
    
            }
        }
    };

    为了让上面的代码更简洁些,也就是所谓的“系列对象”的问题,可以用抽象工厂方法

    EmployeeDAO3.cpp

    //数据库访问有关的基类
    class IDBConnection{
    
    };
    class IDBConmmand{
    
    };
    class IDataReader{
    
    };
    
    class IDBFactory{
    public:
        virtual IDBConnection* CreateDBConnection() = 0;
        virtual IDBConmmand* CreateDBConmmand() = 0;
        virtual IDataReader* CreateDataReader() = 0;
    };
    
    //支持SQL Server
    class SqlConnection :public IDBConnection{
    
    };
    class SqlCommand :public IDBConmmand{
    
    };
    class SqlDataReader :public IDataReader{
    
    };
    
    class SqlDBFactory :public IDBFactory{
        virtual IDBConnection* CreateDBConnection() = 0;
        virtual IDBConmmand* CreateDBConmmand() = 0;
        virtual IDataReader* CreateDataReader() = 0;
    
    };
    
    //支持 Oracle
    class OracleConnection :public IDBConnection{
    
    };
    
    class OracleCommand :public IDBConmmand{
    
    };
    
    class OracleDataReader :public IDataReader{
    
    };
    
    class EmployeeDAO{
    
        IDBFactory* dbFactory;
    
    
    public:
        vector<EmployeeDAO> GetEmployees(){
            IDBConnection connection = dbFactory->CreateDBConnection; //建立数据库的连接
            connnection->ConnectionString = "...";
    
            IDBCommand* command = dbFactory->CreateDBConmmand; //建立数据库的命名对象
            command->CommandText = "...";
            commend->SetConnection(connection);
    
            IDBDataReader* reader = command->ExcuteReader();
            while (reader->Read()){
    
            }
        }
    };

  • 相关阅读:
    MySQL索引方法
    【转】CentOS Linux解决Device eth0 does not seem to be present(linux)
    charles4.2下载与破解方法以及配置https
    laravel 安装碰到的问题:全局安装 Laravel Installer,然后用下面的指令创建新项目: laravel new blog报连接超时解决方案
    Go的50坑:新Golang开发者要注意的陷阱、技巧和常见错误[2]
    Go的50坑:新Golang开发者要注意的陷阱、技巧和常见错误[1]
    跨集群拷贝hdfs
    kylin
    Error:scalac: Error: org.jetbrains.jps.incremental.scala.remote.ServerException
    笔记
  • 原文地址:https://www.cnblogs.com/zhuifeng-mayi/p/11062922.html
Copyright © 2020-2023  润新知