工廠方法模式
前言
上文描述了簡單工廠模式,但是簡單工廠模式并不屬于23種設(shè)計模式。所以本文我們介紹簡單工廠模式的高級實現(xiàn)。在此之前先看一下簡單工廠模式所存在的問題。預(yù)留問題:
- 違背了開閉原則還違反了高內(nèi)聚低耦合的原則。
- 無法形成繼承的層級結(jié)構(gòu)
工廠方法模式
工廠方法模式(Factory Method Pattern)又稱為工廠模式,又稱工廠模式、多態(tài)工廠模式和虛擬構(gòu)造器模式,它屬于類創(chuàng)建型模式。在工廠方法模式中,工廠父類負(fù)責(zé)定義創(chuàng)建產(chǎn)品對象的公共接口,而工廠子類則負(fù)責(zé)生成具體的產(chǎn)品對象,這樣做的目的是將產(chǎn)品類的實例化操作延遲到工廠子類中完成,即通過工廠子類來確定究竟應(yīng)該實例化哪一個具體產(chǎn)品類。
主要作用
工廠方法模式主要把類的創(chuàng)建放到工廠的子類中進(jìn)行創(chuàng)建,同時由子類來決定創(chuàng)建哪一個類
舉個例子,上文中小明有一個自己的簡單汽車工廠可以生產(chǎn)汽車,這時候甲方來了說能不能生產(chǎn)一批自行車?
這時候咋辦 小明就只有去改造他的汽車簡單工廠了,但是成本太高了。而且搞不好甲方又要生產(chǎn)其他的產(chǎn)品呢。所以這次必須要完美的解決這個問題。所以小明去請教了一個企業(yè)家。
企業(yè)家的建議就是創(chuàng)建生產(chǎn)自行車的工廠,不改造原有的汽車工廠,這樣的話每次甲方有新的需求只需要創(chuàng)建一個工廠就行,這樣也不用害怕甲方在增加其他的產(chǎn)品。這就是工廠方法模式。
總結(jié)
上述就是簡單工廠模式和工廠方法模式的區(qū)別,簡單工廠模式產(chǎn)品單一,擴(kuò)展難 這時候我們來看一下都有哪些角色。
- 抽象產(chǎn)品(Product)
- 具體產(chǎn)品(Concrete Product)
- 抽象工廠(Creator)
- 具體工廠(Concrete Creator)
簡單示意圖:

實例
還是拿上文中的汽車工廠舉例子 首先創(chuàng)建抽象工廠類汽車工廠
public abstract class CarFactory {
public abstract Car getCar();
}
抽象產(chǎn)品角色,我們的產(chǎn)品就是生產(chǎn)汽車,注意汽車和自行車都是屬于同一產(chǎn)品等級,產(chǎn)品等級和產(chǎn)品族的概念等下文介紹
public interface Car {
/**
* 輸出簡單信息
*/
void output();
}
然后創(chuàng)建具體產(chǎn)品,這里生產(chǎn)奧迪汽車和鳳凰牌自行車
/**
* 奧迪汽車產(chǎn)品
*/
public class AudiCar implements Car {
@Override
public void output() {
System.out.println("生產(chǎn)出了奧迪車");
}
}
/**
* 鳳凰牌自行車
*/
public class BicycleCar implements Car {
@Override
public void output() {
System.out.println("生產(chǎn)鳳凰牌自行車");
}
}
然后創(chuàng)建具體工廠類,然后繼承抽象工廠類。
/**
* 生產(chǎn)汽車
*/
public class AutomobileFactory extends CarFactory {
@Override
public Car getCar() {
return new AudiCar();
}
}
/**
* 生產(chǎn)自行車
*/
public class BicycleFactory extends CarFactory{
@Override
public Car getCar() {
return new BicycleCar();
}
}
然后我們創(chuàng)建一個客戶端來進(jìn)行調(diào)用。
public static void main(String[] args) {
/**
* 生產(chǎn)汽車
*/
CarFactory carFactory = new AutomobileFactory();
Car car = carFactory.getCar();
car.output();
/**
* 生產(chǎn)自行車
*/
CarFactory bicFactory = new BicycleFactory();
Car biccar = bicFactory.getCar();
biccar.output();
}
輸出結(jié)果
生產(chǎn)出了奧迪車 生產(chǎn)鳳凰牌自行車
如果這個時候要開始生產(chǎn)電動車了哪我們就可以直接創(chuàng)建一個電動車的產(chǎn)品工廠,然后繼承抽象工廠,在創(chuàng)建具體的產(chǎn)品就可以了
缺點
會造成大量的類,在添加新產(chǎn)品的時候不光要增加產(chǎn)品類還要增加對應(yīng)的工廠類。對系統(tǒng)造成了額外的開銷,同時也增加了系統(tǒng)的負(fù)責(zé)度,還有就是一個具體工廠只能創(chuàng)建一個具體的產(chǎn)品。雖然說解決了對工廠方法內(nèi)的修改關(guān)閉,如果換一個產(chǎn)品的話也是需要修改具體的產(chǎn)品類。
優(yōu)點
- 符合開閉原則
- 符合單一職責(zé)原則
- 解決類簡單工廠模式無法繼承等級結(jié)構(gòu)問題
其主要就是:將靜態(tài)工廠里的工廠類用繼承的方式細(xì)分
應(yīng)用實例
接下來我們看一下在Java中有哪些使用工廠方法模式的例子
Collection接口
Collection接口可以看成一個總的抽象工廠,它的一些實現(xiàn)這個接口的類,像ArrayList,LinkedHashSet等等可以看作一個個不同的品牌的工廠,而總的產(chǎn)品Iterator接口里面會定義產(chǎn)品所需功能的細(xì)節(jié),然后在交給各個品牌不同的工廠來實現(xiàn)。
往期推薦
一個 Java 對象占據(jù)多少內(nèi)存?不經(jīng)意間,大量的內(nèi)存被無形地浪費(fèi)了
新來的萌妹紙在線變魔術(shù),一個 'rm -rf' 把公司數(shù)據(jù)庫整沒了
面試高頻題,程序員必看!MySQL 為何不推薦默認(rèn)值為 null ?

老家浙江東海邊,靠海吃海,目前經(jīng)營一個小品牌,讓普通人吃到最新鮮的海鮮。有興趣可以點擊了解:《浙里有漁,鮮人一步!》???
點擊領(lǐng)取:程序員最新學(xué)習(xí)資料!
下方二維碼關(guān)注我

技術(shù)草根,堅持分享?編程,算法,架構(gòu)
朋友助力下!點個贊和在看!