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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了明亮解我“工厂模式无用”之惑相关的知识,希望对你有一定的参考价值。

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

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

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

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

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

public

class

Restaurant

{

public

Food
 cook
()

{

FoodFactory
 factory 
=

new

ChineseFoodFactory
();

Food
 food 
=
 factory
.
createFood
();

return
 food
;

}
}

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

public

class

Restaurant

{

public

Food
 cook
()

{

Food
 food 
=

new

ChineseFood
();

return
 food
;

}
}

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

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

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

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

Food
 food 
=

new

ChuangChineseFood
();

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

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 即可。

if

(
time 
==
 DAY
)

{
    restaurant
.
setFoodFactory
(
chineseFoodFactory
);
}

else

{
    restaurant
.
setFoodFactory
(
westernFoodFactory
);
}
Food
 food 
=
 resuaurant
.
cook
();

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

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

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

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

禅定时刻

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

大家可以长按二维码,关注下~

你的订阅,是我写作路上最大的支持!
技术图片

以上是关于明亮解我“工厂模式无用”之惑的主要内容,如果未能解决你的问题,请参考以下文章

JDOJ-1194: VIJOS-P1009 清帝之惑之康熙

vijos 1009 清帝之惑之康熙

不惑之惑!

夏之惑==反省

不惑之惑

测绘地理信息企业转型之惑