03 C++设计模式之工厂方法(Factory Method)模式

工厂方法定义

在父类中提供一个创建对象的方法,允许子类决定实例化对象的类型

工厂方法优缺点

优点
  • 用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程。
    灵活性增强,对于新产品的创建,只需多写一个相应的工厂类。
  • 典型的解耦框架。高层模块只需要知道产品的抽象类,无须关心其他实现类,满足迪米特法则、依赖倒置原则和里氏替换原则。
缺点
  • 类的个数容易过多,增加复杂度
  • 增加了系统的抽象性和理解难度
  • 抽象产品只能生产一种产品,此弊端可使用抽象工厂模式解决。

工厂方法应用场景

  • 当你在编写代码的过程中,如果无法预知对象确切类别及其依赖关系时,可使用工厂方法。
  • 如果你希望用户能扩展你软件库或框架的内部组件,可使用工厂方法。
  • 如果你希望复用现有对象来节省系统资源,而不是每次都重新创建对象,可使用工厂方法。

工厂方法的结构和实现

结构
  • 产品(Product)将会对接口进行声明。对于所有由创建者及其子类构建的对象,这些接口都是通用的。
  • 具体产品(Concrete Products)是产品接口的不同实现。
  • 创建者(Creator)类声明返回产品对象的工厂方法。该方法的返回对象类型必须与产品接口相匹配。 你可以将工厂方法声明为抽象方法,强制要求每个子类以不同方式实现该方法。或者,你也可以在基础工厂方法中返回默认产品类型。注意,尽管它的名字是创建者,但他最主要的职责并不是创建产品。一般来说,创建者类包含一些与产品相关的核心业务逻辑。工厂方法将这些逻辑处理从具体产品类中分离出来。打个比方,大型软件开发公司拥有程序员培训部门。但是,这些公司的主要工作还是编写代码,而非生产程序员。
  • 具体创建者(Concrete Creators) 将会重写基础工厂方法,使其返回不同类型的产品。注意,并不一定每次调用工厂方法都会创建新的实例。工厂
    方法也可以返回缓存、对象池或其他来源的已有对象。
实现

Product.h:

#ifndef  PRODUCT_H_
#define  PRODUCT_H_

#include <string>

// 抽象产品类 电影
class Movie {
 public:
    virtual std::string get_a_movie() = 0;
};

#endif  // PRODUCT_H_

ConcreteProduct.h:

#ifndef  CONCRETE_PRODUCT_H_
#define  CONCRETE_PRODUCT_H_

#include <iostream>
#include <string>
#include "Product.h"

// 具体产品类 电影::国产电影
class ChineseMovie : public Movie {
 public:
    std::string get_a_movie() override {
        return "《让子弹飞》";
    }
};

// 具体产品类 电影::日本电影
class JapaneseMovie : public Movie {
 public:
    std::string get_a_movie() override {
        return "《千与千寻》";
    }
};

// 具体产品类 电影::美国电影
class AmericanMovie : public Movie {
 public:
    std::string get_a_movie() override {
        return "《钢铁侠》";
    }
};

#endif  // CONCRETE_PRODUCT_H_

Creator.h:

#ifndef  CREATOR_H_
#define  CREATOR_H_

#include "Product.h"

// 抽象工厂类 生产电影
class Factory {
 public:
    virtual std::shared_ptr<Movie> get_movie() = 0;
};

#endif  // CREATOR_H_

ConcreteCreator.h:

#ifndef CONCRETE_CREATOR_H_
#define CONCRETE_CREATOR_H_

#include <memory>
#include "Creator.h"
#include "ConcreteProduct.h"

// 具体工厂类 中国生产者
class ChineseProducer : public Factory {
 public:
    std::shared_ptr<Movie> get_movie() override {
        return std::make_shared<ChineseMovie>();
    }
};

// 具体工厂类 日本生产者
class JapaneseProducer : public Factory {
 public:
    std::shared_ptr<Movie> get_movie() override {
        return std::make_shared<ChineseMovie>();
    }
};

// 具体工厂类 美国生产者
class AmericanProducer : public Factory {
 public:
    std::shared_ptr<Movie> get_movie() override {
        return std::make_shared<ChineseMovie>();
    }
};

#endif  // CONCRETE_CREATOR_H_

main.cpp:

#include "ConcreteCreator.h"

int main() {
     system("chcp 65001");
    std::shared_ptr<Factory> factory;
    std::shared_ptr<Movie> product;

    // 这里假设从配置中读到的是Chinese(运行时决定的)
    std::string conf = "China";

    // 程序根据当前配置或环境选择创建者的类型
    if (conf == "China") {
        factory = std::make_shared<ChineseProducer>();
    } else if (conf == "Japan") {
        factory = std::make_shared<JapaneseProducer>();
    } else if (conf == "America") {
        factory = std::make_shared<AmericanProducer>();
    } else {
        std::cout << "error conf" << std::endl;
    }

    product = factory->get_movie();
    std::cout << "获取一部电影: " << product->get_a_movie() << std::endl;
    system("pause");
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Carson.Yang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值