木灵鱼儿 - 简单工厂模式
type: channel
link: https://www.mulingyuer.com/tag/%E7%AE%80%E5%8D%95%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F/
items: 创建型模式：工厂模式（包含抽象工厂）

创建型模式：工厂模式（包含抽象工厂）
type: item
date: 2022-05-29T21:31:46+08:00
description: 简介工厂模式是讲需要实例化的代码提取出来，放到一个专门的类中去做管理和维护，达到和主体代码的解耦，从而提高项目的扩展性和维护性。将创建实例与调用实例进行解耦！简单来说就是把new操作（创建实例）放到一个专门的地方统一管理，而不是在代码中耦合使用，方便管理和扩展。工厂模式有三种用法：简单工厂模式、工厂方法模式、抽象工厂模式简单工厂模式简单工厂模式是指由一个工厂对象决定创建出哪一种产品类的实例。比如我们需要建一个饭店，这个饭店需要招三名厨师，他们要有各自的拿手菜：水煮牛肉、青椒炒蛋、炒米粉。为了能方便的招聘厨师，我定了一个要求，厨师必须会：开火、颠勺、关火、出菜于是我写了一个接口来要求这些厨师。abstract class Cooks { abstract openFire(): void; //开火 abstract dianshao(): void; //颠勺 abstract shutFire(): void; //关火 abstract accomplish(): string; //出菜 }通过这个接口我找到三名厨师：小王、小明、小红class xw extends Cooks { openFire() { console.log("开火，开始准备水煮牛肉"); } dianshao() { console.log("颠勺"); } shutFire() { console.log("关火，水煮牛肉快好了"); } accomplish() { return "水煮牛肉"; } } class xm extends Cooks { openFire() { console.log("开火，开始准备青椒炒蛋"); } dianshao() { console.log("颠勺"); } shutFire() { console.log("关火，青椒炒蛋快好了"); } accomplish() { return "青椒炒蛋"; } } class xh extends Cooks { openFire() { console.log("开火，开始准备炒米粉"); } dianshao() { console.log("颠勺"); } shutFire() { console.log("关火，炒米粉快好了"); } accomplish() { return "炒米粉"; } }现在我厨师有了，就需要考虑，怎么让厨师去做菜，饭店都是有人专门管理这个事情的，它负责跟厨师和外部沟通，我们称之为厨房管理员这个管理员就可以写成工厂模式，它接受一个菜名，便叫厨师做菜，厨师做完了，就可以出菜了。class KitchenManager { private cook: Cooks | undefined; cookFood(foodName: string) { if (foodName === "水煮牛肉") { this.cook = new xw(); } else if (foodName === "青椒炒蛋") { this.cook = new xm(); } else if (foodName === "炒米饭") { this.cook = new xh(); } else { throw new Error("这个菜做不了"); } //具体做菜逻辑 this.cook.openFire(); this.cook.dianshao(); this.cook.shutFire(); return this.cook.accomplish(); } }此时一个简单工厂模式就搭建完成，我们甚至可以把具体的做菜逻辑封装到每个厨师的类上面，我们需要负责调用accomplish拿到做好的菜品即可。当我们需要增加新的菜品时，外部的使用代码并不用改动逻辑，只是传入的参数不同而已，而我们只需要改动厨房管理员这部分代码，比如增加更多的else if判断，或者招聘更多的厨师，以满足客户需求。简单工厂也称之为静态工厂，因为上述的管理员代码，完全可以转成静态方法使用，功能不受影响。但是简单工厂也是有缺点的，虽然整体代码满足开闭原则，但是工厂本身是违背开闭原则的，因为每增加一个新厨师，或者新菜品，工厂一定会增加一个判断，比如else if。工厂方法模式工厂方法模式指定义一个创建对象的接口，但是让实现这个接口的类来决定实例化哪个类，工厂方法让类的实例化推迟到子类中进行。它用于解决简单工厂中特别多的if判断的问题，当我们的店铺越来越大的时候，菜品和做菜师傅也越来越多，那么KitchenManager承担了特别多的逻辑，成了一个全能工厂，这显然不太好维护。我们将每个菜品分类为不同的菜系，通过不同菜系工厂去调用对应的厨师，再产出实际的食物。然后管理员只提供不…