學完工廠模式,才發(fā)現(xiàn)還有一個抽象工廠模式;學習后發(fā)現(xiàn)不論是通過接口方式、還是繼承方式,都可以使用抽象工廠模式;但是個人建議更多的時候,我們可以優(yōu)先考慮接口方式,畢竟 單繼承,多實現(xiàn)
設計模式分為三種類型,共23種
- 創(chuàng)建型模式:單例模式、工廠模式、抽象工廠模式、建造者模式、原型模式
- 結構型模式:代理模式、裝飾模式、外觀模式、享元模式、橋接模式、組合模式、適配器模式
- 行為型模式:觀察者模式、策略模式、中介者模式、模版方法模式、命令模式、迭代器模式、職責鏈模式(責任鏈模式)、備忘錄模式、解釋器模式(Interpreter模式)、狀態(tài)模式、訪問者模式
每個人的理解方式、理解程度都不相同,怎么去理解有時候并不太關鍵,主要最終結果一致即可,以下僅代表個人學習觀點,如有錯誤,歡迎指出,共同進步
基礎認知
簡單工廠模式針對的是單一對象+綜合行為
管理的(同等級產(chǎn)品),抽象工廠模式針對的是同類行為
管理(同族產(chǎn)品)
取個簡單的例子來說明一下工廠模式和抽象工廠模式,思維上可以稍微跳躍一下去想象
抽象工廠模式,即工廠方法模式的升級版,其可以生產(chǎn)一個產(chǎn)品族的產(chǎn)品。
簡單工廠模式更多的針對是單類產(chǎn)品:以生活中隨處可見的車為例,通常車的組成發(fā)動機、輪胎、方向盤等等,如果我們寫一個工廠模式,那么首先我們需要做以下幾步
- 寫一個抽象產(chǎn)品類(主要用于說明車的組成,內(nèi)部包含發(fā)動機、輪胎、方向盤等等)
- 寫一個或多個具體產(chǎn)品類繼承、實現(xiàn)抽象類的方法(他們內(nèi)部的實現(xiàn)有所不同,例如發(fā)動機可能有v4,v6的)
- 寫一個工廠管理類去動態(tài)創(chuàng)建所需要的具體類
在上面條件下,其實生活中的車大多有各自品牌,例如奧迪、寶馬廠商等等,而這些廠商也未必只生產(chǎn)車,可能他們都對彩妝行業(yè)有涉獵,那么就有了奧迪口紅?寶馬口紅?寶馬搖搖椅等等… 而像這種不同品牌的同樣單一類型產(chǎn)品可以定義為同級產(chǎn)品
·,而他們各自的廠商品牌可定義為同族產(chǎn)品
那么在這種場景下又改如何去寫工廠模式?難道像之前一樣,寫一個抽象產(chǎn)品類,然后寫具體產(chǎn)品類(汽車的組成類),然后用工廠嗎?
可能我上面描述的并不是很清晰,可以直接對照這里
形象比喻
工廠方法模式的局限性是只能生產(chǎn)一類產(chǎn)品,這里我們把同類產(chǎn)品呢叫做同等級產(chǎn)品,如手機是一個等級,電腦是一個等級。
而有一個新的定義,就是同族產(chǎn)品,如華為手機、華為電腦是同一族,同屬華為族;蘋果手機、蘋果電腦是同一族,同屬蘋果族。于是,產(chǎn)品工廠的定義也由同等級工廠升級為同族產(chǎn)品工廠,如華為工廠、蘋果工廠。不言而喻,不管是華為工廠還是蘋果工廠,都具有生產(chǎn)手機和電腦的功能,故,抽象工廠的的作用就被定義了,那就是定義生產(chǎn)手機和電腦。
你可能會發(fā)現(xiàn)中間好像少了一層管理類(奧迪、寶馬分化),這時候就用到了抽象工廠模式, 這種模式可以說是換了一個維度是分類組裝,需要用到一個抽象工廠類~
- 抽象產(chǎn)品類
- 具體產(chǎn)品類
- 抽象工廠類
- 具體工廠類
抽象工廠模式 相比于 簡單工廠模式,個人認為主要區(qū)別有以下幾點
- 簡單工廠模式,一般只有一個工廠類用于管理各抽象類下具體類的創(chuàng)建
- 抽象工廠模式,多了一層抽象層用于管理各具體工廠類,同時多個具體工廠并行
- 針對每個具體產(chǎn)品行為做了統(tǒng)一管理
采用接口、基礎方式實現(xiàn)工廠模式、工廠抽象模式(“單繼承,多實現(xiàn)”
)的區(qū)別
繼承方式
- 缺點:相對而言擴展性有限,大部分只對當前的某一類型進行擴展使用
- 優(yōu)點:耦合性降低
接口方式
- 缺點:加入工廠管理者類太多,對于后期不太方便維護
- 優(yōu)點:擴展性強,較靈活
Demo結構、效果
錯誤理解
分類結構
效果
基礎實現(xiàn)
后來再看,發(fā)現(xiàn)當時理解的有一定問題,等之后有時間再來寫一個示例
如果將抽象工廠模式細化的話,可以用類似這種方式去學習;如果不理解,我建議直接看項目實現(xiàn)
抽象產(chǎn)品類
ProductName
package com.example.kotlindemo.factory;
public interface ProductName {
public void carName();
}
ProductYield
package com.example.kotlindemo.factory;
public interface ProductYield {
public void carYield();
}
具體產(chǎn)品類
AdNameModel
package com.example.kotlindemo.factory;
import android.util.Log;
public class AdNameModel implements ProductName {
@Override
public void carName() {
Log.e("tag", "奧迪 A4");
}
}
AdYieldModel
package com.example.kotlindemo.factory;
import android.util.Log;
public class AdYieldModel implements ProductYield {
@Override
public void carYield() {
Log.e("tag","奧迪 A4 出產(chǎn)于:2008");
}
}
BmNameModel
package com.example.kotlindemo.factory;
import android.util.Log;
public class BmNameModel implements ProductName {
@Override
public void carName() {
Log.e("tag", "寶馬 X1");
}
}
BmYieldModel
package com.example.kotlindemo.factory;
import android.util.Log;
public class BmYieldModel implements ProductYield {
@Override
public void carYield() {
Log.e("tag", "寶馬 X1 出產(chǎn)于:2006");
}
}
抽象工廠類
行為管理者:共性行為,擁有相同的組成部分
CarFactory
package com.example.kotlindemo.factory;
public interface CarFactory {
public ProductName name();
public ProductYield yield();
}
具體工廠類
以單產(chǎn)品為維度,內(nèi)部涵蓋抽象多個具體類
具體工廠類 AdFactory
package com.example.kotlindemo.factory;
public class AdFactory implements CarFactory {
@Override
public ProductName name() {
return new AdNameModel();
}
@Override
public ProductYield yield() {
return new AdYieldModel();
}
}
具體工廠類 BmFactory
package com.example.kotlindemo.factory;
public class BmFactory implements CarFactory {
@Override
public ProductName name() {
return new BmNameModel();
}
@Override
public ProductYield yield() {
return new BmYieldModel();
}
}
使用方式
AdFactory adFactory = new AdFactory();
adFactory.name().carName();
adFactory.yield().carYield();
BmFactory bmFactory = new BmFactory();
bmFactory.name().carName();
bmFactory.yield().carYield();
項目實現(xiàn)
基礎實現(xiàn)有時候反倒把人繞暈… 不如直接以這樣的方式說明
抽象產(chǎn)品
ProductN
package com.example.kotlindemo.factoryN;
public interface ProductN {
public void carName();
public void carYield();
}
具體產(chǎn)品
每一個產(chǎn)品都相對獨立,具有共性行為
AdModelN
package com.example.kotlindemo.factoryN;
import android.util.Log;
public class AdModelN implements ProductN {
@Override
public void carName() {
Log.e("tag", "奧迪 A4");
}
@Override
public void carYield() {
Log.e("tag","奧迪 A4 出產(chǎn)于:2008");
}
}
BmModelN
package com.example.kotlindemo.factoryN;
import android.util.Log;
public class BmModelN implements ProductN {
@Override
public void carName() {
Log.e("tag", "寶馬 X1");
}
@Override
public void carYield() {
Log.e("tag", "寶馬 X1 出產(chǎn)于:2006");
}
}
抽象工廠
package com.example.kotlindemo.factoryN;
public interface CarFactoryN {
public ProductN model();
}
具體工廠
每一個具體的工廠都可以返回該對象的不同模型,例如同為奧迪車型可以返回 奧迪A4、奧迪A6、奧迪Q5等等
AdFactoryN文章來源:http://www.zghlxwxcb.cn/news/detail-549705.html
package com.example.kotlindemo.factoryN;
public class AdFactoryN implements CarFactoryN {
@Override
public ProductN model() {
return new AdModelN();
}
}
BmFactoryN文章來源地址http://www.zghlxwxcb.cn/news/detail-549705.html
package com.example.kotlindemo.factoryN;
public class BmFactoryN implements CarFactoryN {
@Override
public ProductN model() {
return new BmModelN();
}
}
使用方式
AdFactoryN adFactoryN = new AdFactoryN();
adFactoryN.model().carName();
adFactoryN.model().carYield();
BmFactoryN bmFactoryN = new BmFactoryN();
bmFactoryN.model().carName();
bmFactoryN.model().carYield();
到了這里,關于設計模式 - 抽象工廠模式的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!