企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持知识库和私有化部署方案 广告
### 场景 举个生活中常见的例子--组装电脑,需要选择一系列配件,比如CPU、硬盘、内存、主板、电源、机箱等。为简化讨论,只考虑选择CPU和主板的问题。 ### 选择组装电脑配件 选择CPU时,有一系列问题,比如品牌、型号、针脚数目、主频等问题,为简化讨论,只考虑针脚数目;同样,选择主板时,也有一系列问题,比如品牌、芯片组、集成芯片、总线频率等问题,为简化讨论,只考虑CPU插槽的孔数。 选择不同的CPU和主板,是每个客户在组装电脑的时候,向装机公司提出的要求,也就是最终拟定的装机方案。在确定方案前,还需要考虑各个配件之间的兼容性,比如CPU针脚数和主板提供的CPU插槽不兼容,是无法安装的。也就是说,装机方案是有整体性的,选择的各个配件之间是有联系的。 ### 简答工厂的解决方案 ```cpp #include <iostream> #include <memory> /** * CPU接口 */ class CPUApi { public: ~CPUApi() {} virtual void calclate() = 0; }; /** * 主板接口 */ class MainboardApi { public: ~MainboardApi() {} virtual void installCPU() = 0; }; /** * Intel的CPU接口 */ class IntelCPU : public CPUApi { public: IntelCPU(int pins) : pins_(pins) {} void calclate() override { std::cout << "now in Intel CPU, pins=" << pins_ << std::endl; } private: int pins_ = 0; // CPU的针脚数 }; /** * AMD的CPU接口 */ class AMDCPU : public CPUApi { public: AMDCPU(int pins) : pins_(pins) {} void calclate() override { std::cout << "now in AMD CPU, pins=" << pins_ << std::endl; } private: int pins_ = 0; // CPU的针脚数 }; /** * 技嘉的主板 */ class GAMainboard : public MainboardApi { public: GAMainboard(int cpuholes) : cpuholes_(cpuholes) {} void installCPU() override { std::cout << "now in GAMainboard, cpuholes=" << cpuholes_ << std::endl; } private: int cpuholes_ = 0; // CPU插槽的孔数 }; /** * 微星的主板 */ class MSIMainboard : public MainboardApi { public: MSIMainboard(int cpuholes) : cpuholes_(cpuholes) {} void installCPU() override { std::cout << "now in MSIMainboard, cpuholes=" << cpuholes_ << std::endl; } private: int cpuholes_ = 0; // CPU插槽的孔数 }; /** * 创建CPU简单工厂 */ class CPUFactory { public: static std::shared_ptr<CPUApi> createCPUApi(int type) { std::shared_ptr<CPUApi> ptr = nullptr; if (type == 1) ptr.reset(new IntelCPU(1156)); else if (type == 2) ptr.reset(new AMDCPU(939)); return ptr; } }; /** * 创建主板简单工厂 */ class MainboardFactory { public: static std::shared_ptr<MainboardApi> createMainboardCpi(int type) { std::shared_ptr<MainboardApi> ptr = nullptr; if (type == 1) ptr.reset(new GAMainboard(1156)); else if (type == 2) ptr.reset(new MSIMainboard(939)); return ptr; } }; /** * 装机工程师的类 */ class ComputerEngineer { public: void makeComputer(int cpuType, int mainboardType) { // 1: 首先准备装好机器所需要的配件 prepareHardwares(cpuType, mainboardType); // 2: 组装机器 // 3: 测试机器 // 4: 交付客户 } private: void prepareHardwares(int cpuType, int mainboardType) { std::shared_ptr<CPUApi> cpu_ptr_ = CPUFactory::createCPUApi(cpuType); std::shared_ptr<MainboardApi> mb_ptr_ = MainboardFactory::createMainboardCpi(mainboardType); cpu_ptr_->calclate(); mb_ptr_->installCPU(); } }; void test1() { std::cout << "test1" << std::endl; ComputerEngineer engineer; engineer.makeComputer(1, 1); } void test2() { std::cout << "test2" << std::endl; ComputerEngineer engineer; engineer.makeComputer(1, 2); } int main(int argc, char** argv) { test1(); test2(); return 0; } ``` 输出结果: ``` test1 now in Intel CPU, pins=1156 now in GAMainboard, cpuholes=1156 test2 now in Intel CPU, pins=1156 now in MSIMainboard, cpuholes=939 ``` ### 简单工厂的问题 上面测试的结果,显然,test1是满足装机要求的,而test2不满足装机要求,CPU的针脚和主板的插孔不一致,根本无法组装。所以简单工厂模式不能解决这个问题。 ### 抽象工厂的解决方案 1. **抽象工厂定义** 提供一个创建一系列相关或者相互依赖对象的接口,而无需指定它们具体的类。 2. **抽象工厂代码实现** ```cpp /** * 抽象工厂的接口,声明创建抽象产品对象的操作 */ class AbstractFactory { public: /** * 创建CPU的对象接口 */ virtual std::shared_ptr<CPUApi> createCPUApi() = 0; /** * 创建主板的对象接口 */ virtual std::shared_ptr<MainboardApi> createMainboardCpi() = 0; }; /** * 装机方案一: Intel的CPU + 技嘉的主板 * 这里创建的CPU和主板对象是对应的,能匹配上 */ class Schema1 : public AbstractFactory { public: std::shared_ptr<CPUApi> createCPUApi() { return std::shared_ptr<CPUApi>(new IntelCPU(1156)); } std::shared_ptr<MainboardApi> createMainboardCpi() { return std::shared_ptr<MainboardApi>(new GAMainboard(1156)); } }; /** * 装机方案二: AMD的CPU + 微星的主板 * 这里创建的CPU和主板对象是对应的,能匹配上 */ class Schema2 : public AbstractFactory { public: std::shared_ptr<CPUApi> createCPUApi() { return std::shared_ptr<CPUApi>(new AMDCPU(939)); } std::shared_ptr<MainboardApi> createMainboardCpi() { return std::shared_ptr<MainboardApi>(new MSIMainboard(939)); } }; /** * 装机工程师的类 */ class ComputerEngineer { public: void makeComputer(std::shared_ptr<AbstractFactory> schema) { // 1: 首先准备装好机器所需要的配件 prepareHardwares(schema); // 2: 组装机器 // 3: 测试机器 // 4: 交付客户 } private: void prepareHardwares(std::shared_ptr<AbstractFactory> schema) { std::shared_ptr<CPUApi> cpu_ptr = schema->createCPUApi(); std::shared_ptr<MainboardApi> mb_ptr = schema->createMainboardCpi(); cpu_ptr->calclate(); mb_ptr->installCPU(); } }; void test1() { std::cout << "test1" << std::endl; std::shared_ptr<ComputerEngineer> engineer(new ComputerEngineer()); std::shared_ptr<AbstractFactory> schema(new Schema1()); engineer->makeComputer(schema); } void test2() { std::cout << "test2" << std::endl; std::shared_ptr<ComputerEngineer> engineer(new ComputerEngineer()); std::shared_ptr<AbstractFactory> schema(new Schema2()); engineer->makeComputer(schema); } int main(int argc, char** argv) { test1(); test2(); return 0; } ``` 运行结果: ``` test1 now in Intel CPU, pins=1156 now in GAMainboard, cpuholes=1156 test2 now in AMD CPU, pins=939 now in MSIMainboard, cpuholes=939 ``` ## 抽象工厂的本质 **选择产品簇的实现**