设计模式系列--工厂模式
2022/1/1...大约 3 分钟
设计模式系列--工厂模式
场景:有一个农场,种了很多水果树,能产出很多种水果:苹果、橘子、香蕉等,每种水果有不同的价格和其他属性等;有一个供应商从这个农场中进口水果,跟供应商做买卖时,需要根据水果名,给到供应商关于这个水果的所有信息。
这个场景下,每个水果都有一个自己的产品介绍,当供应商指定水果时,只需要把这个水果介绍给他就行,最简单的实现就是通过switch-case或者if-else,也就是 简单工厂模式
简单工厂模式
#include <memory>
enum class FruitType : int{
Apple = 1,
Orange = 2,
Balana = 3,
}
// fruit base
class Fruit {
public:
virtual ~Fruit() = default;
virtual float price() { return 1.0;}
virtual void print() { std::cout << price() << std::endl;}
};
// Apple
class Apple : public Fruit{
public:
~Apple() override = default;
float price() { return 7.4; }
}
// Orange
class Orange : public Fruit{
public:
~Orange() override = default;
float price() { return 4.9; }
}
// 农场获取水果信息的工厂方法
class Farm {
public:
Farm() = default;
~Farm() = default;
std::shared_ptr<Fruit> getSpecificFruit(FruitType fruit_type){
switch(fruit_type){
case FruitType::Apple:
return std::make_shared<Apple>();
case FruitType::Orange:
return std::make_shared<Orange>();
default:
return nullptr;
}
}
}
优缺点
优点:
- 产品(这里是指农场的水果)只需要关注产品具体信息,产品和农场职责清晰,互不干扰,以达到解耦的目的
- 后续添加新的产品只需要添加新产品的类,以及修改Factory的配置
缺点:
- 每次有产品变更都要修改Factory的逻辑代码,不能及时发布的场景下信息不及时
工厂方法模式
这种模式是对简单工厂模式的一个优化解法,生产水果时,不通过switch-case以及if-else获取水果信息,而是各自提供实现接口,在接口有变动时只需要修改相应的接口就行了
在简单工厂的前提下:
class Farm{
public:
std::shared_ptr<Fruit> createApple() {return std::make_shared<Apple>(); }
std::shared_ptr<Fruit> createOrange() {return std::make_shared<Orange>(); }
}
抽象工厂模式
场景:原来这个区域内只有我们一家农场,这几年修路了,经济发展的很快,旁边的相邻市区也新开了几家农场,每个农场都能够产生相同的水果,但是品质会有差别。这个供应商通过农场工会统一订购水果,因此工会要把每家农场的每种水果信息提供给该供应商,让供应商进行选择。
简单工厂模式把产品接口抽象,实现了农场和水果之间的分离,在多个农场这种场景下,把多个农场也进行抽象,实现多个农场的分离,以达到解耦的目的。
class FarmA_Apple: public Fruit{
public:
virtual ~FramA_Apple() override = default;
float price() override { return 8.8; }
}
class FarmA_Orange: public Fruit{
public:
virtual ~FarmA_Orange() override = default;
float price() override { return 4.8; }
}
class FarmB_Apple: public Fruit{
public:
virtual ~FarmB_Apple() override = default;
float price() override { return 9.9; }
}
class FarmB_Orange: public Fruit{
public:
virtual ~FarmB_Orange() override = default;
float price() override {return 6.6;}
}
class Balana: public Fruit{
public:
virtual ~Balana() override = default;
float price() override {return 3.3;}
}
// Base
class FarmBase {
public:
BaseFactory() = default;
virtual ~BaseFactory() = default;
virtual std::shared_ptr<Fruit> createFruit(FruitType type) = 0;
}
// FarmA
class FarmAFactory: public FarmBase {
public:
~FarmA() override = default;
std::shared_ptr<Fruit> createApple() { return std::make_shared<FarmA_Apple>(); }
std::shared_ptr<Fruit> createOrange() {return std::make_shared<FarmA_Orange>(); }
std::shared_ptr<Fruit> createBalana() {return std::make_shared<Balana>(); }
}
// FarmB
class FarmBFactory: public FarmBase{
public:
~FarmB() override = default;
std::shared_ptr<Fruit> createApple(){return std::make_shared<FarmB_Apple>();}
std::shared_ptr<Fruit> createOrange(){return std::make_shared<FarmB_Orange>();}
std::shared_ptr<Fruit> createBalana(){return std::make_shared<Balana>();}
}
// FarmFactory
class FarmFactory{
public:
std::shared_ptr<FarmBase> createFarmA(){return std::make_shared<FarmA>();}
std::shared_ptr<FarmBase> createFarmB(){return std::make_shared<FarmB>();}
}
优缺点
优点:
- 农场与农场解耦,水果与水果解耦,工会只需要提供接口,各家农场自己去实现相应的类就可以了
*以上就是工厂模式相关的介绍,如果疑问、错误,欢迎留言交流。