一、工厂模式是什么?
工厂模式是一种创建型的软件设计模式。定义一个用于创建对象的工厂接口,并让工厂子类决定实例化哪一个产品类,使产品类的实例化延迟到工厂子类中执行。说白了就是用来造东西的,一般是比较简单的东西,我们不需要知道它如何生产的,直接从工厂拿到产品即可。
工厂模式的优点:
- 良好的封装性。将产品的实例化封装执行,避免被修改,这样的产品具备良好的一致性。
- 良好的扩展性。增加产品时,同步增加一个工厂子类,不会违反开闭原则。
- 标准的解耦合框架。使用者只需要知道自己要什么产品即可,不用去管产品具体的特性等等,降低了模块间的耦合。
工厂模式的缺点:
- 代码量大。每加一个产品,都要加一个工厂子类,代码会显得臃肿。
- 不利于扩展复杂的产品结构。如果你要苹果、香蕉、梨,工厂模式的结构还可以,但如果你要山东的苹果、海南的香蕉、北京的苹果,就显得结构呆呆的。这可以用抽象工厂模式解决,对产品族和产品种类进行区分。
二、简单工厂模式
在介绍工厂模式前,先介绍其前身-简单工厂模式,简单工厂模式是用一个简单的工厂类,直接对产品进行实例化,虽然大大减少了代码量,但是违反了设计中的开闭原则,因为每次添加产品,工厂类都要进行修改。
2.1 结构图
客户端即Main主函数,调用简单工厂制造产品,并获取产品。具体要什么产品由客户端命令决定。
2.2 代码示例
场景描述:我联系了一个生产水果的工厂,从工厂拿了一个苹果、一个香蕉和一个梨,用来果腹,工厂给我一个报价我付钱即可。
//Prodect.h /****************************************************/ #pragma once #include <iostream> using namespace std; // 产品种类 enum PRODECT_TYPE { APPLE, // 苹果 BANANA, // 香蕉 PEAR // 梨 }; // 抽象产品类 class Prodect { public: // 构造函数 Prodect(int price) :m_price(price) {}; // 析构函数 virtual ~Prodect() {}; // 获取价格 int getPrice() { return m_price; } protected: // 产品价格 int m_price; }; // 具体产品类-苹果 class AppleProdect : public Prodect { public: // 构造函数 AppleProdect(int price) :Prodect(price) { cout << "获得了一个苹果。" << endl; }; // 析构函数 virtual ~AppleProdect() { cout << "吃掉了一个苹果。" << endl; }; }; // 具体产品类-香蕉 class BananaProdect : public Prodect { public: // 构造函数 BananaProdect(int price) :Prodect(price) { cout << "获得了一个香蕉。" << endl; }; // 析构函数 virtual ~BananaProdect() { cout << "吃掉了一个香蕉。" << endl; }; }; // 具体产品类-梨 class PearProdect : public Prodect { public: // 构造函数 PearProdect(int price) :Prodect(price) { cout << "获得了一个梨。" << endl; }; // 析构函数 virtual ~PearProdect() { cout << "吃掉了一个梨。" << endl; }; };
//Factory.h /****************************************************/ #pragma once #include <iostream> #include "Prodect.h" using namespace std; // 简单工厂 class SimpleFactory { public: // 获取产品 Prodect* getProdect(PRODECT_TYPE type) { Prodect* prodect = nullptr; switch (type) { case APPLE: prodect = new AppleProdect(5); break; case BANANA: prodect = new BananaProdect(2); break; case PEAR: prodect = new PearProdect(3); break; default: cout << "无该产品。" << endl; break; } return prodect; } };
//main.cpp /****************************************************/ #include <iostream> #include "Factory.h" #include "Prodect.h" using namespace std; int main() { SimpleFactory* factory = new SimpleFactory(); cout << "开始生产。" << endl; Prodect *A = factory->getProdect(APPLE); Prodect *B = factory->getProdect(BANANA); Prodect *C = factory->getProdect(PEAR); int applePrice = A->getPrice(); int bananaPrice = B->getPrice(); int pearPrice = C->getPrice(); int sum = A->getPrice() + B->getPrice() + C->getPrice(); cout << "苹果价格:" << applePrice << "元。" << endl; cout << "香蕉价格:" << bananaPrice << "元。" << endl; cout << "梨子价格:" << pearPrice << "元。" << endl; cout << "累计消费:" << sum << "元。" << endl; delete A; delete B; delete C; delete factory; cout << "享用完毕。" << endl; return 0; }
程序结果如下。
在上述示例中,我们可以看到,如果我想给工厂再添加一个产品,那么除了添加一个产品子类外,还要跑到简单工厂的类中进行switch的扩展,这样不利于代码的封装,破坏了开闭原则。而工厂模式的设计能弥补该不足。
三、工厂模式
3.1 结构图
客户端即Main主函数,通过工厂子类来制造对应的产品,并获取产品。具体要什么产品由工厂子类决定。
3.2 代码示例
场景描述:我联系了一个生产水果的工厂,从工厂拿了一个苹果、一个香蕉和一个梨,用来果腹,工厂给我一个报价我付钱即可。
//Prodect.h /****************************************************/ #pragma once #include <iostream> using namespace std; // 抽象产品类 class Prodect { public: // 构造函数 Prodect(int price) :m_price(price) {}; // 析构函数 virtual ~Prodect() {}; // 获取价格 int getPrice() { return m_price; } protected: // 产品价格 int m_price; }; // 具体产品类-苹果 class AppleProdect : public Prodect { public: // 构造函数 AppleProdect(int price) :Prodect(price) { cout << "获得了一个苹果。" << endl; }; // 析构函数 virtual ~AppleProdect() { cout << "吃掉了一个苹果。" << endl; }; }; // 具体产品类-香蕉 class BananaProdect : public Prodect { public: // 构造函数 BananaProdect(int price) :Prodect(price) { cout << "获得了一个香蕉。" << endl; }; // 析构函数 virtual ~BananaProdect() { cout << "吃掉了一个香蕉。" << endl; }; }; // 具体产品类-梨 class PearProdect : public Prodect { public: // 构造函数 PearProdect(int price) :Prodect(price) { cout << "获得了一个梨。" << endl; }; // 析构函数 virtual ~PearProdect() { cout << "吃掉了一个梨。" << endl; }; };
//Factory.h /****************************************************/ #pragma once #include <iostream> #include "Prodect.h" using namespace std; // 抽象工厂类 class Factory { public: // 获取产品 virtual Prodect* getProdect() = 0; }; // 具体工厂类-苹果 class AppleFactory : public Factory { public: // 获取产品 virtual Prodect* getProdect() { Prodect* prodect = new AppleProdect(5); return prodect; } }; // 具体工厂类-香蕉 class BananaFactory : public Factory { public: // 获取产品 virtual Prodect* getProdect() { Prodect* prodect = new BananaProdect(2); return prodect; } }; // 具体工厂类-梨 class PearFactory : public Factory { public: // 获取产品 virtual Prodect* getProdect() { Prodect* prodect = new PearProdect(3); return prodect; } };
//main.cpp /****************************************************/ #include <iostream> #include "Factory.h" #include "Prodect.h" using namespace std; int main() { Factory* factoryA = new AppleFactory(); Factory* factoryB = new BananaFactory(); Factory* factoryC = new PearFactory(); cout << "开始生产。" << endl; Prodect *A = factoryA->getProdect(); Prodect *B = factoryB->getProdect(); Prodect *C = factoryC->getProdect(); int applePrice = A->getPrice(); int bananaPrice = B->getPrice(); int pearPrice = C->getPrice(); int sum = A->getPrice() + B->getPrice() + C->getPrice(); cout << "苹果价格:" << applePrice << "元。" << endl; cout << "香蕉价格:" << bananaPrice << "元。" << endl; cout << "梨子价格:" << pearPrice << "元。" << endl; cout << "累计消费:" << sum << "元。" << endl; delete A; delete B; delete C; delete factoryA; delete factoryB; delete factoryC; cout << "享用完毕。" << endl; return 0; }
程序结果如下。
这样设计的好处就是如果多一个产品,那就只需要在产品类和工厂类中各扩展一个子类即可,不影响原有的程序。
四、总结
我尽可能用较通俗的话语和直观的代码例程,来表述我对工厂模式的理解,或许有考虑不周到的地方,如果你有不同看法欢迎评论区交流!希望我举的例子能帮助你更好地理解工厂模式。
如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!