1. 简单工厂模式的弊端在上一节简单工厂模式中创建了一个工厂类用于生产需要的对象但是这种方式有一个弊端它违反了设计模式中的开放-封闭原则先来看相关的代码// 恶魔果实工厂类 enum class Type:char{SHEEP, LION, BAT}; class SmileFactory { public: SmileFactory() {} ~SmileFactory() {} AbstractSmile* createSmile(Type type) { AbstractSmile* ptr nullptr; switch (type) { case Type::SHEEP: ptr new SheepSmile; break; case Type::LION: ptr new LionSmile; break; case Type::BAT: ptr new BatSmile; break; default: break; } return ptr; } };在上面的工厂函数中需要生成三种人造恶魔果实现在如果想要生成更多那么就需要在工厂函数的switch语句中添加更多的case很明显这违背了封闭原则也就意味着需要基于开放原则来解决这个问题。使用工厂模式可以很完美的解决上述的问题简单工厂模式是只有一个工厂类而工厂模式是有很多的工厂类一个基类包含一个虚工厂函数用于实现多态。多个子类重写父类的工厂函数。每个子工厂类负责生产一种恶魔果实这相当于再次解耦将工厂类的职责再次拆分、细化如果要生产新品种的恶魔果实那么只需要添加对应的工厂类无需修改原有的代码。2. 工厂模式我们先修改一下简单工厂模式中工厂类相关的代码// 恶魔果实工厂类 class AbstractFactory { public: virtual AbstractSmile* createSmile() 0; virtual ~AbstractFactory() {} }; class SheepFactory : public AbstractFactory { public: AbstractSmile* createSmile() override { return new SheepSmile; } ~SheepFactory() { cout 释放 SheepFactory 类相关的内存资源 endl; } }; class LionFactory : public AbstractFactory { public: AbstractSmile* createSmile() override { return new LionSmile; } ~LionFactory() { cout 释放 LionFactory 类相关的内存资源 endl; } }; class BatFactory : public AbstractFactory { public: AbstractSmile* createSmile() override { return new BatSmile; } ~BatFactory() { cout 释放 BatFactory 类相关的内存资源 endl; } };通过示例代码可以看到每个工厂类其实都不复杂在每个子工厂类中也只是重写了父类的工厂方法而已每个子工厂类生产一种恶魔果实但是工厂函数的返回值确是恶魔果实类的基类类型相当于是使用父类指针指向了子类对象此处也是用到了多态。通过这样的处理工厂函数也就不再需要参数了。根据简单工厂模式的代码和上面的修改就可以把工厂模式的UML类图画出来了完整的代码应该是这样的:#include iostream using namespace std; class AbstractSmile { public: virtual void transform() 0; virtual void ability() 0; virtual ~AbstractSmile() {} }; // 人造恶魔果实· 绵羊形态 class SheepSmile : public AbstractSmile { public: void transform() override { cout 变成人兽 -- 山羊人形态... endl; } void ability() override { cout 将手臂变成绵羊角的招式 -- 巨羊角 endl; } }; // 人造恶魔果实· 狮子形态 class LionSmile : public AbstractSmile { public: void transform() override { cout 变成人兽 -- 狮子人形态... endl; } void ability() override { cout 火遁· 豪火球之术... endl; } }; class BatSmile : public AbstractSmile { public: void transform() override { cout 变成人兽 -- 蝙蝠人形态... endl; } void ability() override { cout 声纳引箭之万剑归宗... endl; } }; // 恶魔果实工厂类 class AbstractFactory { public: virtual AbstractSmile* createSmile() 0; virtual ~AbstractFactory() {} }; class SheepFactory : public AbstractFactory { public: AbstractSmile* createSmile() override { return new SheepSmile; } ~SheepFactory() { cout 释放 SheepFactory 类相关的内存资源 endl; } }; class LionFactory : public AbstractFactory { public: // 工厂函数 AbstractSmile* createSmile() override { return new LionSmile; } ~LionFactory() { cout 释放 LionFactory 类相关的内存资源 endl; } }; class BatFactory : public AbstractFactory { public: // 工厂函数 AbstractSmile* createSmile() override { return new BatSmile; } ~BatFactory() { cout 释放 BatFactory 类相关的内存资源 endl; } }; int main() { AbstractFactory* factory new BatFactory; AbstractSmile* obj factory-createSmile(); obj-transform(); obj-ability(); return 0; }在main()函数中的这句代码是实例化了一个生成蝙蝠恶魔果实的工厂对象:AbstractFactory* factory new BatFactory;在真实的项目场景中要生成什么类型的恶魔果实其实是通过客户端的操作界面控制的它对应的可能是一个按钮或者是一个选择列表用户做出了选择程序就可以根据该需求去创建对应的工厂对象最终将选择的恶魔果实生产出来。在上面的例子中不论是恶魔果实的基类还是工厂类的基类它们的虚函数可以是纯虚函数也可以是非纯虚函数。这样的基类在设计模式中就可以称之为抽象类此处的抽象类和C中对抽象类的定义有一点出入。