工廠模式定義:一個(gè)創(chuàng)建產(chǎn)品對(duì)象的工廠接口啦粹,將產(chǎn)品對(duì)象的實(shí)際創(chuàng)建工作推遲到具體工廠類當(dāng)中肺樟。這滿足創(chuàng)建型模式中所要求的“創(chuàng)建與使用分離”的特點(diǎn)。
按實(shí)際業(yè)務(wù)場(chǎng)景劃分顽聂,工廠模式有 3 種不同的實(shí)現(xiàn)方式肥惭,分別是簡(jiǎn)單工廠模式盯仪、工廠方法模式和抽象工廠模式。
我們把被創(chuàng)建的對(duì)象稱為“產(chǎn)品”蜜葱,把創(chuàng)建產(chǎn)品的對(duì)象稱之為“工廠”全景。如果要?jiǎng)?chuàng)建的產(chǎn)品不對(duì),只要一個(gè)工廠類就可以完成牵囤,這種模式叫“簡(jiǎn)單工廠模式”爸黄。
簡(jiǎn)單工廠模式種創(chuàng)建實(shí)例的方法通常為靜態(tài)(static)方法,因此簡(jiǎn)單工廠模式(Simple Factory Pattern)又叫做靜態(tài)工廠方法模式
(Static Factory Method Pattern)揭鳞。
簡(jiǎn)單工廠模式又一個(gè)具體的工廠類馆纳,可以生成多個(gè)不同的產(chǎn)品,屬于創(chuàng)建型設(shè)計(jì)模式汹桦,但是不在 GoF 23 種設(shè)計(jì)模式之列鲁驶。
適用場(chǎng)景
- 工廠類負(fù)責(zé)創(chuàng)建的對(duì)象比較少
- 客戶端(應(yīng)用層)只知道傳入工廠類的參數(shù),對(duì)于創(chuàng)建對(duì)象(邏輯)不關(guān)心
優(yōu)點(diǎn)和缺點(diǎn)
優(yōu)點(diǎn):
- 工廠類必須包含必要的邏輯判斷舞骆,可以決定在什么時(shí)候創(chuàng)建哪一個(gè)產(chǎn)品實(shí)例钥弯。客戶端可以免除直接創(chuàng)建產(chǎn)品對(duì)象的職責(zé)督禽,很方便的創(chuàng)建出相應(yīng)的產(chǎn)品脆霎。工廠和產(chǎn)品的職責(zé)區(qū)分明確;
- 客戶端無需知道所創(chuàng)建具體產(chǎn)品的類名狈惫,只需要知道參數(shù)即可睛蛛;
- 可以引入配置文件,在不修改客戶端代碼的情況下更換和添加新的具體產(chǎn)品類胧谈。
缺點(diǎn):
- 簡(jiǎn)單工廠模式的工廠類單一忆肾,負(fù)責(zé)所有產(chǎn)品的創(chuàng)建,職責(zé)過重菱肖,一旦異常客冈,可能整個(gè)系統(tǒng)受到影響。且工廠類代碼會(huì)非常臃腫稳强,違背高聚合原則场仲;
- 使用簡(jiǎn)單工廠模式會(huì)增加系統(tǒng)中類的個(gè)數(shù)(引入新的工廠類),增加系統(tǒng)的復(fù)雜度和理解難度退疫;
- 系統(tǒng)擴(kuò)展困難渠缕,一旦增加新產(chǎn)品不得不修改工廠邏輯,在產(chǎn)品類型較多時(shí)褒繁,可能造成邏輯過于復(fù)雜亦鳞;
- 使用 static 工廠方法,造成工廠角色無法形成基于繼承的等級(jí)結(jié)構(gòu)。
模式結(jié)構(gòu)與實(shí)現(xiàn)
簡(jiǎn)單工廠模式的主要角色如下:
- 簡(jiǎn)單工廠(Simple Factory):負(fù)責(zé)實(shí)現(xiàn)創(chuàng)建所有實(shí)例的內(nèi)部邏輯蚜迅。工廠類的創(chuàng)建產(chǎn)品類的方法可以被外界直接調(diào)用舵匾,創(chuàng)建所需的產(chǎn)品對(duì)象;
- 抽象產(chǎn)品(Product):是簡(jiǎn)單工廠創(chuàng)建的所有對(duì)象的父類谁不,負(fù)責(zé)描述所有實(shí)例共有的公共接口坐梯;
-
具體產(chǎn)品(Concrete Product):是簡(jiǎn)單工廠模式的創(chuàng)建目標(biāo)。
簡(jiǎn)單工廠模式結(jié)構(gòu)圖
簡(jiǎn)單工廠模式結(jié)構(gòu)圖
代碼實(shí)現(xiàn):
public interface Product {
void produce();
}
public class ConcreateProductA implements Product {
@Override
public void produce() {
System.out.println("produce product A....");
}
}
public class ConcreateProductB implements Product {
@Override
public void produce() {
System.out.println("produce product B...");
}
}
public class SimpleFactory {
public static Product makeProduct(String type) {
if ("A".equalsIgnoreCase(type)) {
return new ConcreateProductA();
} else if ("B".equalsIgnoreCase(type)) {
return new ConcreateProductB();
}
return null;
}
}
public class Main {
public static void main(String[] args) {
Product product = SimpleFactory.makeProduct("A");
if (product != null) {
product.produce();
}
}
}