定义
抽象工厂模式是一种创建型设计模式,它提供一个接口,用于创建一系列相关或依赖的对象,而无需指定它们的具体类。抽象工厂模式将对象的创建过程抽象化,允许子类通过实现具体工厂类来定制对象的创建。
为什么使用抽象工厂模式
-
产品族的一致性
- 抽象工厂模式确保同一产品族中的对象之间的一致性。
-
部分遵循开闭原则
- 可以通过添加新的具体工厂类来扩展新的产品族,而不需要修改现有代码,符合开闭原则。
- 增加新的产品类型时,需要修改抽象工厂接口及其所有具体实现,不完全符合开闭原则。
-
隐藏对象创建细节
- 抽象工厂模式将具体产品的创建过程隐藏起来,客户端只需要使用工厂提供的接口来获取对象。
实现步骤
-
定义抽象产品类
- 定义所有具体产品类的共同接口,客户端将通过这个接口来使用具体产品。
-
实现具体产品类
- 实现产品接口的具体产品类,这些类包含了产品的实际业务逻辑。
-
定义抽象工厂类
- 定义一个抽象工厂类,包含用于创建一系列相关或依赖对象的抽象方法,子类将实现这些方法来创建具体产品对象。
-
实现具体工厂类
- 继承抽象工厂类并实现其抽象方法,具体工厂类负责创建具体产品对象。
优缺点和适用场景
优点
-
产品族的一致性
- 确保同一产品族中的对象之间的一致性。
-
部分符合开闭原则
- 可以通过添加新的具体工厂类来扩展新的产品族,符合开闭原则。
-
隐藏对象创建细节
- 客户端无需知道具体产品的创建过程,只需要通过工厂接口获取对象。
缺点
-
增加系统复杂性
- 引入了更多的类,增加了系统的复杂性。
-
不完全符合开闭原则
- 增加新的产品类型时,需要修改抽象工厂接口及其所有具体实现,不完全符合开闭原则。
适用场景
-
系统需要创建一系列相关或依赖的对象
- 当系统需要创建一系列相关或依赖的对象,并且确保这些对象之间的一致性时,适合使用抽象工厂模式。
-
产品族扩展
- 当系统需要通过增加新的产品族来扩展功能,而不需要修改现有代码时,适合使用抽象工厂模式。
简单工厂模式、工厂方法模式与抽象工厂模式的比较
特性 | 简单工厂模式 | 工厂方法模式 | 抽象工厂模式 |
创建对象的职责 | 单一工厂类负责所有产品创建 | 子类决定创建具体对象 | 子类决定创建一系列相关对象 |
遵循开闭原则 | 不符合,增加新产品需修改工厂类 | 符合,增加新产品无需修改工厂类 | 部分符合,增加产品族符合 |
系统复杂性 | 较低 | 中等 | 较高 |
产品族一致性支持 | 不支持 | 不支持 | 支持 |
咖啡店的例子
我们可以使用抽象工厂模式来实现一个咖啡店系统,该系统可以创建不同种类的咖啡及其配套的杯子和勺子。
#include <iostream> #include <memory> #include <string> // 抽象产品类:咖啡 class Coffee { public: virtual ~Coffee() {} virtual std::string getDescription() const = 0; virtual double cost() const = 0; }; // 具体产品类:美式咖啡 class Americano : public Coffee { public: std::string getDescription() const override { return "Americano"; } double cost() const override { return 5.0; } }; // 抽象产品类:咖啡杯 class CoffeeCup { public: virtual ~CoffeeCup() {} virtual std::string getDescription() const = 0; }; // 具体产品类:美式咖啡杯 class AmericanoCup : public CoffeeCup { public: std::string getDescription() const override { return "Americano Cup"; } }; // 抽象产品类:咖啡勺 class CoffeeSpoon { public: virtual ~CoffeeSpoon() {} virtual std::string getDescription() const = 0; }; // 具体产品类:美式咖啡勺 class AmericanoSpoon : public CoffeeSpoon { public: std::string getDescription() const override { return "Americano Spoon"; } }; // 抽象工厂类 class CoffeeFactory { public: virtual ~CoffeeFactory() {} virtual std::shared_ptr<Coffee> createCoffee() const = 0; virtual std::shared_ptr<CoffeeCup> createCoffeeCup() const = 0; virtual std::shared_ptr<CoffeeSpoon> createCoffeeSpoon() const = 0; }; // 具体工厂类:美式咖啡工厂 class AmericanoFactory : public CoffeeFactory { public: std::shared_ptr<Coffee> createCoffee() const override { return std::make_shared<Americano>(); } std::shared_ptr<CoffeeCup> createCoffeeCup() const override { return std::make_shared<AmericanoCup>(); } std::shared_ptr<CoffeeSpoon> createCoffeeSpoon() const override { return std::make_shared<AmericanoSpoon>(); } }; int main() { // 创建美式咖啡及其配套杯子和勺子 std::shared_ptr<CoffeeFactory> americanoFactory = std::make_shared<AmericanoFactory>(); std::shared_ptr<Coffee> americano = americanoFactory->createCoffee(); std::shared_ptr<CoffeeCup> americanoCup = americanoFactory->createCoffeeCup(); std::shared_ptr<CoffeeSpoon> americanoSpoon = americanoFactory->createCoffeeSpoon(); std::cout << "Coffee: " << americano->getDescription() << ", Cost: " << americano->cost() << std::endl; std::cout << "Cup: " << americanoCup->getDescription() << std::endl; std::cout << "Spoon: " << americanoSpoon->getDescription() << std::endl; return 0; }
玄机博客
© 版权声明
1.本站内容仅供参考,不作为任何法律依据。用户在使用本站内容时,应自行判断其真实性、准确性和完整性,并承担相应风险。
2.本站部分内容来源于互联网,仅用于交流学习研究知识,若侵犯了您的合法权益,请及时邮件或站内私信与本站联系,我们将尽快予以处理。
3.本文采用知识共享 署名4.0国际许可协议 [BY-NC-SA] 进行授权
4.根据《计算机软件保护条例》第十七条规定“为了学习和研究软件内含的设计思想和原理,通过安装、显示、传输或者存储软件等方式使用软件的,可以不经软件著作权人许可,不向其支付报酬。”您需知晓本站所有内容资源均来源于网络,仅供用户交流学习与研究使用,版权归属原版权方所有,版权争议与本站无关,用户本人下载后不能用作商业或非法用途,需在24个小时之内从您的电脑中彻底删除上述内容,否则后果均由用户承担责任;如果您访问和下载此文件,表示您同意只将此文件用于参考、学习而非其他用途,否则一切后果请您自行承担,如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。
5.本站是非经营性个人站点,所有软件信息均来自网络,所有资源仅供学习参考研究目的,并不贩卖软件,不存在任何商业目的及用途
THE END
暂无评论内容