当前位置: 首页 > article >正文

【GeekBand】C++设计模式笔记9_Abstract Factory_抽象工厂

1. “对象创建”模式

  • 通过 “对象创建” 模式绕开new,来避免对象创建(new)过程中导致的紧耦合(依赖具体类),从而支持对象创建的稳定。它是接口抽象之后的第一步工作。
  • 典型模式
    • Factory Method
    • Abstract Factory
    • Prototype
    • Builder

2. Abstract Factory 抽象工厂

2.1 动机(Motivation)

  • 在软件系统中,经常面临着 “一系列相互依赖的对象” 的创建工作;同时,由于需求的变化,往往存在更多系列对象的创建工作。
  • 如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种 “封装机制” 来避免客户程序和这种 “多系列具体对象创建工作” 的紧耦合?

2.2 模式定义

提供一个接口,让该接口负责创建一系列 “相关或者相互依赖的对象”,无需指定它们具体的类。
——《设计模式》GoF

2.3 实例代码

2.3.1 EmployeeDAO1
class EmployeeDAO {  
public:
    vector<EmployeeDO> GetEmployees() {
    	// 创建数据库连接
        SqlConnection* connection = new SqlConnection();
        connection->ConnectionString = "...";
		
		// 创建sql命令
        SqlCommand* command = new SqlCommand();
        command->CommandText = "...";
        
        // 将sql命令与数据库连接关联
        command->SetConnection(connection);
		
		// 执行sql命令,获取数据
        SqlDataReader* reader = command->ExecuteReader();
        while (reader->Read()) {

        }
    }
};
2.3.2 EmployeeDAO2
/******************** 数据库访问有关的基类 ********************/ 
// 数据库连接类
class IDBConnection {
    
};

// 数据库连接对象创建工厂
class IDBConnectionFactory {
public:
    virtual IDBConnection* CreateDBConnection() = 0;
};

// 数据库命令类
class IDBCommand {
    
};

// 数据库命令对象创建工厂
class IDBCommandFactory {
public:
    virtual IDBCommand* CreateDBCommand() = 0;
};

class IDataReader {
    
};

// 数据库数据读取对象创建工厂
class IDataReaderFactory {
public:
    virtual IDataReader* CreateDataReader() = 0;
};

// 支持SQL Server
class SqlConnection : public IDBConnection {
    
};

class SqlConnectionFactory : public IDBConnectionFactory {
    
};

class SqlCommand : public IDBCommand {
    
};

class SqlCommandFactory : public IDBCommandFactory {
    
};

class SqlDataReader : public IDataReader {
    
};

class SqlDataReaderFactory : public IDataReaderFactory {
    
};

// 支持Oracle
class OracleConnection : public IDBConnection {
    
};

class OracleCommand : public IDBCommand {
    
};

class OracleDataReader : public IDataReader {
    
};


class EmployeeDAO {
    IDBConnectionFactory* dbConnectionFactory;
    IDBCommandFactory* dbCommandFactory;
    IDataReaderFactory* dataReaderFactory;
      
public:
    vector<EmployeeDO> GetEmployees() {
        IDBConnection* connection = dbConnectionFactory->CreateDBConnection();
        connection->ConnectionString("...");

        IDBCommand* command = dbCommandFactory->CreateDBCommand();
        command->CommandText("...");
        
        command->SetConnection(connection); // 关联性

        IDBDataReader* reader = command->ExecuteReader(); // 关联性
        while (reader->Read()) {

        }
    }
};
2.3.3 EmployeeDAO3
// 数据库访问有关的基类
class IDBConnection {
    
};

class IDBCommand {
    
};

class IDataReader {
    
};

/*
	将有关联性的对象创建工作放在一个类中进行,sql连接、sql命令、sql数据读取三种对象是相互依赖的关系
	sql连接只能跟sql的命令、sql数据的读取对象关联使用,所以一次性创建sql的连接、命令和数据读取对象
*/ 
class IDBFactory {
public:
    virtual IDBConnection* CreateDBConnection() = 0;
    virtual IDBCommand* CreateDBCommand() = 0;
    virtual IDataReader* CreateDataReader() = 0;
};


// 支持SQL Server
class SqlConnection : public IDBConnection {
    
};

class SqlCommand : public IDBCommand {
    
};

class SqlDataReader : public IDataReader {
    
};

class SqlDBFactory : public IDBFactory {
public:
    virtual IDBConnection* CreateDBConnection() = 0;
    virtual IDBCommand* CreateDBCommand() = 0;
    virtual IDataReader* CreateDataReader() = 0; 
};

// 支持Oracle
class OracleConnection : public IDBConnection {
    
};

class OracleCommand : public IDBCommand {
    
};

class OracleDataReader : public IDataReader {
    
};


class EmployeeDAO {
    IDBFactory* dbFactory;
    
public:
    vector<EmployeeDO> GetEmployees() {
        IDBConnection* connection = dbFactory->CreateDBConnection();
        connection->ConnectionString("...");

        IDBCommand* command = dbFactory->CreateDBCommand();
        command->CommandText("...");
        
        command->SetConnection(connection); // 关联性

        IDBDataReader* reader = command->ExecuteReader(); // 关联性
        while (reader->Read()) {

        }
    }
};

2.4 结构(Structure)

在这里插入图片描述

2.5 要点总结

  • 如果没有应对 “多系列对象构建” 的需求变化,则没有必要使用 Abstract Factory 模式,这时候使用简单的工厂完全可以;
  • “系列对象” 指的是在某一特定系列下的对象之间有相互依赖、或作用的关系,不同系列的对象之间不能相互依赖;
  • Abstract Factory 模式主要在于应对 “新系列” 的需求变动,其缺点在于难以应对 “新对象” 的需求变动。

http://www.kler.cn/a/369678.html

相关文章:

  • 100种算法【Python版】第21篇——Wilson算法
  • 深入解析Diffusion和AsymmDiT:Mochi 1的高效AI视频生成之路
  • Python爬虫:商品详情的“八卦记者”
  • Qt 文本文件读写与保存
  • JavaEE企业级开发技术-利用Mybatis完成CRUD
  • spring final修饰
  • 如何让Nginx更安全?
  • css绘制s型(grid)
  • 【Linux学习】(8)第一个Linux编程进度条程序|git三板斧
  • 静态局部变量
  • 深入RAG:知识密集型NLP任务的解决方案
  • 路由守卫重定向页面
  • vxe-table 表格中使用输入框、整数限制、小数限制,单元格渲染数值输入框
  • 雷军救WPS“三次”,WPS注入新生力量,不再“抄袭”微软
  • Kubernetes(K8S) + Harbor + Ingress 部署 SpringBoot + Vue 前后端分离项目
  • WPF+MVVM案例实战(一)- 设备状态LED灯变化实现
  • 【Rust练习】18.特征 Trait
  • Puppeteer 与浏览器版本兼容性:自动化测试的最佳实践
  • Javaee---多线程(一)
  • ubuntu系统
  • 重写(外壳不变)
  • Linux下的文件系统(进程与文件)
  • Spring Cloud Alibaba实战入门之Nacos注册中心(四)
  • 青少年编程与数学 02-002 Sql Server 数据库应用 16课题、安全机制
  • HardLockUp
  • Rust 力扣 - 5. 最长回文子串