5分钟学设计模式:工厂方法,让你的代码像搭积木一样简单!

大家好,我是知微。

上一次的美食街之旅中,我们探讨了简单工厂模式。今天,让我们继续在美食街的夜色中,探索工厂方法模式的奥秘。

第一幕:美食街的繁华

美食街上,小吃摊的生意越来越火,摊主们为了满足顾客的多样化需求,开始提供更多种类的小吃。

顾客(你):老板,听说你们这除了煎饼果子,还有其他好吃的?

老板:对啊,我们最近推出了烤冷面和章鱼小丸子,都非常受欢迎!

顾客(你):听起来不错,那各来一份吧!

老板:好嘞,马上给您做!

用代码表示

class Snack {
public:
    virtual void serve() = 0;
    virtual ~Snack() {}
};

class RoastedColdNoodles : public Snack {
public:
    void serve() override {
        std::cout << "你的烤冷面好了!" << std::endl;
    }
};

class OctopusBall : public Snack {
public:
    void serve() override {
        std::cout << "你的章鱼小丸子好了!" << std::endl;
    }
};

// 简单工厂
class SnackFactory {
public:
    static Snack* createSnack(const std::string& type) {
        if (type == "COLD_NOODLES") {
            return new RoastedColdNoodles();
        } else if (type == "OCTOPUS_BALL") {
            return new OctopusBall();
        }
        // ...其他小吃类型的创建
        return nullptr;
    }
};

第二幕:小吃摊的扩张

随着生意越来越好,老板一个人弄这么多种类的小吃(简单工厂模式,一个工厂做很多种类),很多时候都忙不过来,出餐速度慢了许多。

思考了几天之后,老板果断做了决定,让家人帮忙,多弄几个摊位,每个摊位都负责自己的小吃(工厂方法模式每个工厂只做对应的产品),顾客可以直接去找他们喜欢的摊位。

顾客(你):老板,我想吃手抓饼,但这家摊位只卖煎饼果子。

老板:没问题,我让我家手抓饼摊位的老板给你做。

顾客(你):这样啊,那我就放心了。

用代码表示

// 抽象产品
class Snack {
public:
    virtual void serve() = 0;
    virtual ~Snack() {}
};

// 具体产品
class HandPies : public Snack {
public:
    void serve() override {
        std::cout << "你的手抓饼好了!" << std::endl;
    }
};

// 简单工厂
class SnackFactory {
public:
    static Snack* createSnack(const std::string& type) {
        if (type == "HANDPIES") {
            return new HandPies();
        }
        // ...其他小吃类型的创建
        return nullptr;
    }
};

第三幕:小吃摊的专业化

老板的决定很快带来了变化,每个摊位都开始专注于自己的特色小吃,顾客可以直接向特定的摊位订购。

顾客(你):我听说这家的章鱼小丸子特别好吃,我就直接来这家摊位了。

章鱼小丸子老板:欢迎光临!我们的章鱼小丸子是这条街上最好吃的,马上就给您做。

顾客(你):太好了,我等不及要尝尝了。

用代码表示

// 抽象工厂
class SnackFactory {
public:
    virtual std::unique_ptr<Snack> createSnack() = 0;
    virtual ~SnackFactory() {}
};

// 具体工厂
class OctopusBallFactory : public SnackFactory {
public:
    std::unique_ptr<Snack> createSnack() override {
        return std::make_unique<OctopusBall>();
    }
};

// 客户端代码
int main() {
    OctopusBallFactory factory;
    auto snack = factory.createSnack();
    snack->serve(); // 章鱼小丸子老板:欢迎光临,我们的章鱼小丸子是这条街上最好吃的!
    return 0;
}

第四幕:小吃摊的繁荣

美食街上的小吃摊变成了一家家各具特色的小吃店,每家店都有自己的招牌小吃,顾客可以根据自己的口味,选择不同的店铺品尝小吃。

顾客(你):这条街上的小吃种类真多,每种都想尝尝。

老板:是啊,我们每家店都有自己的特色,欢迎您常来尝试。

顾客(你):我会的,下次再带朋友一起来。

用代码表示

// 可以为每种小吃创建不同的工厂类
class RoastedColdNoodlesFactory : public SnackFactory {
public:
    std::unique_ptr<Snack> createSnack() override {
        return std::make_unique<RoastedColdNoodles>();
    }
};

class PancakeFactory : public SnackFactory {
    // ...实现
};

// ...其他小吃工厂类

结语

工厂方法模式通过定义一个创建小吃的接口,让具体的工厂类负责生产具体的小吃产品。这样,当需要新增小吃种类时,只需新增相应的工厂,而无需修改既有代码,提高了程序的可扩展性和可维护性。

工厂方法模式的优缺点

  • 优点

    • 提高了代码的扩展性,新增小吃种类无需修改原有代码。
    • 将对象的创建和使用分离,提高了代码的灵活性。
    • 利用多态,可以在运行时决定创建哪种类型的产品。
  • 缺点

    • 随着产品种类的增加,可能需要创建很多工厂类,导致系统变得复杂。
    • 客户端需要知道具体的工厂类名称,可能降低了一些封装性。

应用场景

  • 当系统由多个部分组成,且各部分都有共同的生产对象的需求时。
  • 当需要强调对象创建和对象使用分离的场景时。

总结来说,简单工厂模式适合用于产品类型较少且不会频繁增加的情况,而工厂方法模式则适合于产品类型较多且可能会频繁增加的场合。

工厂方法模式通过使用多态减少了耦合,使得新增产品类型时,不需要修改工厂类,只需要添加相应的具体工厂类即可。

以上就是工厂方法模式的全部内容了,下一期,我们将带来抽象工厂模式的精彩故事,敬请期待!

📢你的每一次👍点赞 ⭐收藏 📝评论,都是我更新的动力,如有错误请留言指正,非常感谢!

posted @ 2024-05-17 15:44  知微之见  阅读(5)  评论(0编辑  收藏  举报