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