您现在的位置是:亿华云 > IT科技
设计模式之工厂模式
亿华云2025-10-03 06:30:04【IT科技】4人已围观
简介本文转载自微信公众号「程序喵大人」,作者程序喵大人 。转载本文请联系程序喵大人公众号。01 简单工厂方法简单工厂方法可能是最常见的工厂类创建型模式了,其中有几个角色,一个是抽象产品角色,一个是具体产品
本文转载自微信公众号「程序喵大人」,设计式作者程序喵大人 。模式转载本文请联系程序喵大人公众号。厂模
01 简单工厂方法
简单工厂方法可能是设计式最常见的工厂类创建型模式了,其中有几个角色,模式一个是厂模抽象产品角色,一个是设计式具体产品角色,多个具体产品都可以。模式抽象成同一个抽象产品。厂模拿操作系统举例,设计式操作系统作为一个抽象产品,模式它有几种具体产品角色,厂模有Windows操作系统,设计式有Android操作系统,模式有iOS操作系统。厂模有一个操作系统的工厂,工厂可以根据不同的需求生产出不同内核的操作系统,这个操作系统的工厂就是最后一个角色:工厂角色。
#include <iostream> enum class BallEnum { BasketBall = 1, SocketBall = 2 }; class Ball { public: Ball() { } virtual ~Ball() { } virtual void Play() { } }; class BasketBall : public Ball { public: void Play() override { std::cout << "play basketball \n"; } }; class SocketBall : public Ball { public: void Play() override { std::cout << "play socketball \n"; } }; class SimpleFactory { public: static Ball* CreateBall(BallEnum type); }; Ball* SimpleFactory::CreateBall(BallEnum type) { switch (type) { case BallEnum::BasketBall: return new BasketBall(); case BallEnum::SocketBall: return new SocketBall(); } return nullptr; } int main() { Ball* basket = SimpleFactory::CreateBall(BallEnum::BasketBall); basket->Play(); Ball* socket = SimpleFactory::CreateBall(BallEnum::SocketBall); socket->Play(); return 0; }在简单工厂方法中,有一个专门的工厂类,根据不同的参数返回不同具体产品类的实例,这些具体产品可以抽象出同一个抽象产品,香港云服务器即有一个共同的父类。 通过上述代码您可能也看到了简单工厂方法的优点,实现了对象的创建和使用逻辑分离,只需要传入不同参数,就可以获得特定具体类的实例。但简单工厂方法也有些缺点,当增加了新的产品,就需要修改工厂类的创建逻辑,如果产品类型较多,就可能造成工厂类逻辑过于复杂,不利于系统的维护,适用于具体产品类型比较少并且以后基本不会新加类型的场景,这样工厂类业务逻辑不会太过复杂。
02 工厂方法模式
为了解决上面简单工厂方法模式的缺点,进一步抽象出了工厂方法模式,工厂类不再负责所有产品的构建,每一个具体产品都有一个对应的工厂,这样在新加产品时就不会改动已有工厂类的创建逻辑。这些工厂也会抽象出一个抽象工厂。可以理解为有四种角色,抽象产品,源码下载具体产品,抽象工厂,具体工厂,其实就是把简单工厂模式中的工厂类做进一步抽象,看代码吧:
#include <iostream> enum class BallEnum { BasketBall = 1, SocketBall = 2 }; class Ball { public: Ball() { } virtual ~Ball() { } virtual void Play() { } }; class BasketBall : public Ball { public: void Play() override { std::cout << "play basketball \n"; } }; class SocketBall : public Ball { public: void Play() override { std::cout << "play socketball \n"; } }; class FactoryBase { public: virtual ~FactoryBase() { } virtual Ball* CreateBall() = 0; }; class BasketBallFactory : public FactoryBase { public: Ball* CreateBall() override { return new BasketBall(); } }; class SocketBallFactory : public FactoryBase { public: Ball* CreateBall() override { return new SocketBall(); } }; int main() { FactoryBase* factory; BallEnum ball_type = BallEnum::SocketBall; switch (ball_type) { case BallEnum::BasketBall: factory = new BasketBallFactory(); break; case BallEnum::SocketBall: factory = new SocketBallFactory(); break; } Ball* ball = factory->CreateBall(); ball->Play(); return 0; }工厂模式提高了系统的可扩展性,完全符合开闭原则,当新加具体产品时,完全不会对已有系统有任何修改。当不知道以后会有多少具体产品时可以考虑使用工厂模式,因为不会降低现有系统的稳定性。但是它也有缺点,每当新加一个产品时,不仅需要新加一个对应的产品类,同时还需要新加一个此产品对应的工厂,系统的复杂度比较高。怎么解决呢,可以再抽象一下:
03 抽象工厂模式
在工厂方法中,每一个抽象产品都会有一个抽象工厂,这样新增一个产品时都会新增两个类,一个是具体产品类,一个是具体工厂类,我们可以考虑多个抽象产品对应一个抽象工厂,这样可以有效减少具体工厂类的网站模板个数,见如下代码:
#include <iostream> enum class BallEnum { BasketBall = 1, SocketBall = 2 }; class Ball { public: Ball() { } virtual ~Ball() { } virtual void Play() { } }; class BasketBall : public Ball { public: void Play() override { std::cout << "play basketball \n"; } }; class SocketBall : public Ball { public: void Play() override { std::cout << "play socketball \n"; } }; class Player { public: Player() { } virtual ~Player() { } virtual void Name() { } }; class BasketBallPlayer : public Player { public: void Name() override { std::cout << "BasketBall player \n"; } }; class SocketBallPlayer : public Player { public: void Name() override { std::cout << "SocketBall player \n"; } }; class FactoryBase { public: virtual ~FactoryBase() { } virtual Ball* CreateBall() = 0; virtual Player* CreatePlayer() = 0; }; class BasketBallFactory : public FactoryBase { public: Ball* CreateBall() override { return new BasketBall(); } Player* CreatePlayer() override { return new BasketBallPlayer(); } }; class SocketBallFactory : public FactoryBase { public: Ball* CreateBall() override { return new SocketBall(); } Player* CreatePlayer() override { return new SocketBallPlayer(); } }; int main() { FactoryBase* factory; BallEnum ball_type = BallEnum::SocketBall; switch (ball_type) { case BallEnum::BasketBall: factory = new BasketBallFactory(); break; case BallEnum::SocketBall: factory = new SocketBallFactory(); break; } Ball* ball = factory->CreateBall(); Player* player = factory->CreatePlayer(); ball->Play(); player->Name(); return 0; }总结
系统的复杂度不会被消除,只能被转移。系统总会有稳定部分和不稳定部分,只是我们要合理选择好边界,认真思考,考虑好将哪部分打造成稳定部分,哪部分打造成不稳定部分。简单工厂方法模式中if-else的逻辑在工厂类里,如果这里在新增一个产品时有bug可能导致所有产品都创建失败,这里是不稳定部分,所以有了工厂方法模式,将工厂类内部打造成稳定部分,将不稳定的逻辑转移到外面。
很赞哦!(75)