解決問題
主要解決創(chuàng)建復雜對象的問題。
應(yīng)用場景
當某一系列對象需要復雜的邏輯控制創(chuàng)建過程,過程創(chuàng)建過程比較復雜時,可以采用工廠模式。
工廠模式常見的有三種:
簡單工廠模式: 又稱之為靜態(tài)工廠模式
工廠模式:最常見的一種工廠模式,用于生產(chǎn)一系列相似的對象
抽象工廠模式:可用于生產(chǎn)各種各樣的對象(用于較復雜的場景)
下面我們來一一介紹
原理與示例
以我們?nèi)ワ埖瓿燥垶槔?/p>
簡單工廠模式(simple factory ,static factory)
類似于其名稱,它適合于比較簡單的場景,通過提供一個靜態(tài)方法來創(chuàng)建對象。
這次我們?nèi)サ氖且粋€小飯店,就一個廚師,只會做西紅柿炒雞蛋和下面條。。。。。原理圖如下所示
public abstract class Food {
}
public class Noodle extends Food {
}
public class TomatoOmelette extends Food {
}
public class Factory {
public static Food createFood(@Nonnull String food) {
if (food.equals("noodle")) {
return new Noodle();
}
if (food.equals("TomatoOmelette")) {
return new TomatoOmelette();
}
return null;
}
}
public class Client {
public static void main(String[] args) {
// 想吃面條
Food food = Factory.createFood("noodle");
//.....
}
}
這種工廠模式的好處在于,屏蔽了客戶端與對象的直接交互(就是我作為客戶去吃飯,沒有讓我自己做飯的道理),只需要告訴飯店需要吃什么菜就可以了。
但它的壞處也是明顯的,它并沒有降低創(chuàng)造對象的復雜度,仍然需要許多if 業(yè)創(chuàng)建對象,對于多種類對象并不合適。所以也能適合簡單場景
工廠方法模式
后來這個小餐館竟然賺錢了,客人越來越多,廚師抱怨了,做兩種食物忙不過來,老板就又招了一個廚師,讓每一人負責一道菜。
public abstract class Food {
}
public class Noodle extends Food {
}
public class TomatoOmelette extends Food {
}
public interface Factory {
public Food create();
}
public class NoodleFactory implements Factory {
@Override
public Food create() {
return new Noodle();
}
}
public class TomatoOmeletteFactory implements Factory {
@Override
public Food create() {
return new TomatoOmelette();
}
}
public class Client {
public static void main(String[] args) {
// 想吃面條
Food food = new NoodleFactory().create();
//.....
}
}
因為我們是老顧客了,所以到了餐館之后,只需要告訴對應(yīng)的廚師你想吃飯就行了,到于你想吃什么飯,由你告訴的廚師來決定。
該模式相當于將創(chuàng)建不同種類的對象的邏輯給隔離開了,特別對于創(chuàng)建邏輯差異化較大的對象,此時就對應(yīng)的工廠各司其職。就像生產(chǎn)自行車的一定不可能與生產(chǎn)汽車的在一條生產(chǎn)線上一樣。
該模式雖然做了復雜性分離,但其惡心之處在于,你竟然得先創(chuàng)建一個工廠。就比如你想吃面條,你得創(chuàng)建一個工廠,這個成本是不可接受的。所以后來又有了抽象工廠模式。
抽象工廠模式
老板的這一招改進,讓自己的生意更加火爆。他決定擴展自己的業(yè)務(wù),將自己的業(yè)務(wù)擴展成兩個系列:面條系列(炸醬面、雞蛋面、拉面、扯面。。。),炒菜(西紅柿雞蛋、青椒土豆絲、酸辣大白菜等)。當我再次來到飯店時,廚師已經(jīng)都不認識了,咋點菜呢?“服務(wù)員,來一碗面雞蛋面!”。這種方式由就需要抽象工廠來實現(xiàn)了。工廠方法模式雖然能夠?qū)崿F(xiàn),但已經(jīng)過于復雜了,需要定義太多的factory。
炒菜系就不再畫了,多個Factory之間仍然可以選擇三種工廠模式來解決創(chuàng)建工廠的問題。
來看一下示例吧
public abstract class Food {
}
public class EggNoodle extends Food {
}
public class LaNoodle extends Food {
}
public interface AbstractNoodleFactory {
public Food createLaNoodle();
public Food createEggNoodle();
}
public class NoodleFactory implements AbstractNoodleFactory {
public Food createLaNoodle() {
return new LaNoodle();
}
public Food createEggNoodle() {
return new EggNoodle();
}
}
public class Client {
public static void main(String[] args) {
// 想吃拉面
Food food = new NoodleFactory().createLaNoodle();
//.....
}
}
抽象工廠模式,解決了更加復雜一些的問題,它更像一個具有多條生產(chǎn)線工廠,可以生產(chǎn)各種產(chǎn)品。
但還是強調(diào)一下,任何一種設(shè)計模式在實際應(yīng)用時,往往都不是單獨使用的;因為現(xiàn)實問題更加復雜,需要你結(jié)合其它生產(chǎn)模式一起使用。三種工廠模式各有用途,在實際使用時,可以簡單選擇,也可以相互組合,以解決你的實際問題。