明亮解我“工厂模式无用”之惑

2020-08-10 12:03:33 浏览数 (1)

明亮,是我的大学同学,我们一个在北京,一个在深圳,昨晚两人视频关于工厂模式聊到深夜。

明亮啊,我怎么觉得工厂模式没有用啊!

不会啊,工厂模式可是最常用的设计模式之一,你说说为啥觉得没用。

你看我给你举个例子,就以餐馆为例吧,类图如下所示,其中 FoodFactory、Food 是抽象类。

首先,如果餐馆的 cook() 通过工厂模式来创建 Food,代码如下:

代码语言:javascript复制
public class Restaurant {
    public Food cook() {
        FoodFactory factory = new ChineseFoodFactory();
        Food food = factory.createFood();
        return food;
    }
}

而如果不使用工厂模式,代码如下:

代码语言:javascript复制
public class Restaurant {
    public Food cook() {       
        Food food = new ChineseFood();
        return food;
    }
}

如果我们使用工厂模式,可以不需要知道具体创建的 Food 类,但是仍需知道具体的 Factory 类,也都要 new 一个对象出来,工厂类只是把 new Food 的逻辑封装了下,并没起到什么作用啊,而且代码还更复杂了,你说工厂模式是不是没有用?

嗯,确实如你所说,使用工厂模式会让代码变得更加复杂,这是因为我们在原有逻辑上抽象出了一个新的层次概念,但是工厂模式并不是没有用的。你之所以还没能看到工厂模式的好,是因为你还没碰到实例化的具体类容易变化的场景,而在这种场景下,工厂模式能让 Restaurant 类遵循“开放-关闭原则”。而遵循该原则的好处就是,在不修改现有代码的前提下,去搭配新的行为,让我们的代码能弹性地应对变化

开放-关闭原则:类对扩展开放,对修改关闭。

下面给你举个变化的例子吧,例如,餐馆有一天想尝试做川菜版的中餐,在不使用工厂模式时,我们必须要去修改 Restaurant 的 cook() 方法。

代码语言:javascript复制
Food food = new ChuangChineseFood();

这样是违背”修改关闭“的。而工厂模式可将实例化具体类的逻辑抽离到工厂中,当面对变化时,通过修改工厂的内部逻辑,来实现 Restaurant 的”修改关闭“。除此之外,工厂模式,通过抽象出工厂接口,让我们能可以实现 Restaurant 的“扩展开放”。我们先对 Restaurant 修改下,把 factory 由局部变量变为成员变量。这样,你便可以利用多态的机制,在运行时传入不同的 Factory 来烹饪食物。

代码语言:javascript复制
public class Restaurant {
    private FoodFactory factory;

    public Food cook() {
        Food food = factory.createFood();
        return food;
    }

    public void setFoodFactory(FoodFactory factory) {
        this.factory = factory;
    }
}

例如,当你想白天中餐,晚上做西餐时,只需通过 setter 方法修改 facotry 即可。

代码语言:javascript复制
if (time == DAY) {
    restaurant.setFoodFactory(chineseFoodFactory);
} else {
    restaurant.setFoodFactory(westernFoodFactory);
}
Food food = resuaurant.cook();

嗯,明亮,我明白你的意思了,工厂模式虽然麻烦了些,但是能让类遵循“开放-关闭原则”,从而更弹性地去应对改变。原来它这么有用,那以后所有的实例化操作我都使用工厂模式,让我的代码具有超强的弹性,弹~弹~弹~

别逗了,万万不可,并不是所有地方都要使用,只有当实例化具体类容易变化时,使用工厂模式才是合适的,才需要考虑进一步的抽象。而对于不容易变化的实例化操作,是不需要遵循“开放-关闭原则”的,不然就是过度设计了。而如何判断实例化操作是否容易变化,这就需要我们的经验了。

过度设计啊,真有种装X失败的感觉。

哈哈哈,你现在知道工厂模式并非无用了吧。别再小瞧设计模式了,这可都是前人总结的宝贵经验!

禅定时刻

我之前不能理解工厂模式的用处,主要还是自己对工厂模式所需解决的问题不清楚。只有应对实例化具体类容易改变的代码时,工厂模式才能发挥出它真正的本领。大家也要避免过度设计,避免装X失败。

0 人点赞