針對Java設(shè)計模式淳玩,推薦一書《大話設(shè)計模式》:
鏈接: https://pan.baidu.com/s/16YZ8nMx6M2C94_dmMWjh0w 提取碼: aw5y
Factory工廠模式分為:
1)簡單工廠模式(Simple Factory) --- 普通工廠模式
2)工廠方法模式(Factory Method) --- 多工廠模式
3)抽象工廠模式(Abstract Factory) --- 抽象工廠模式
什么時候需要用工廠模式呢?
工廠非竿,從字面意思理解蜕着,就是造東西的地方。所以红柱,需要很多類型或者經(jīng)常升級換代承匣,就可以使用工廠模式。比如锤悄,寶馬工廠韧骗,它有很多產(chǎn)品,而且每一款產(chǎn)品還時不時地升個級零聚,換個代袍暴,所以就有工廠這個東西。
所以隶症,使用工廠模式政模,你需要確定一點:
工廠模式針對的是多態(tài)。也就是說蚂会,你的類型如果可能有很多派生淋样,使用工廠模式比較方便。
如果你的需求是經(jīng)常會添加的胁住,比如會添加某個方法趁猴,那么使用工廠模式反而很麻煩刊咳,因為你要修改一連串的項目文件
所以,工廠模式的適用場景大致有這些:
1)對象的創(chuàng)建過程(實例化)很復(fù)雜儡司,需要初始化很多參數(shù)芦缰,比如查詢數(shù)據(jù)庫等。
2)類本身有好多子類枫慷,這些類的創(chuàng)建過程在業(yè)務(wù)中容易發(fā)生改變让蕾,或者對類的調(diào)用容易發(fā)生改變。
工廠模式的優(yōu)點
1)解耦:把對象的創(chuàng)建和使用的過程分開
ClassA想調(diào)用ClassB(其實只是想調(diào)用B的方法)不再需要New一個B,B的實例化或听,就交給工廠類探孝。
2)統(tǒng)一管理對象的創(chuàng)建過程,降低代碼重復(fù)
如果很多地方都需要創(chuàng)建對象B(創(chuàng)建過程復(fù)雜)誉裆,那么很多地方都需要New B(),此時代碼重復(fù)就比較多顿颅。
如果把創(chuàng)建對象B的代碼放到工廠里統(tǒng)一管理,既減少了重復(fù)代碼足丢,也方便以后對B的創(chuàng)建過程的修改維護(hù)粱腻。
中國有16億人,如果每人想買一輛寶馬斩跌,只需要告訴工廠绍些,你想買什么類型的寶馬,是寶馬320還是寶馬523……工廠直接生產(chǎn)出來給你就好了耀鸦,這就是通俗理解工廠模式柬批!通俗理解其好處就是:方便更改應(yīng)用程序和擴展。
工廠方法模式:
一個抽象產(chǎn)品類袖订,可以派生出多個具體產(chǎn)品類氮帐。
一個抽象工廠類,可以派生出多個具體工廠類洛姑。
每個具體工廠類只能創(chuàng)建一個具體產(chǎn)品類的實例上沐。
抽象工廠模式:
多個抽象產(chǎn)品類,每個抽象產(chǎn)品類可以派生出多個具體產(chǎn)品類楞艾。
一個抽象工廠類参咙,可以派生出多個具體工廠類。
每個具體工廠類可以創(chuàng)建多個具體產(chǎn)品類的實例产徊。
也有的人將簡單工廠模式看為工廠方法模式的一種特例昂勒,兩者歸為一類。所以實際分為兩類:工廠方法模式與抽象工廠模式舟铜,兩者區(qū)別如下:
(1)工廠方法模式只有一個抽象產(chǎn)品類,而抽象工廠模式有多個抽象產(chǎn)品類奠衔。
(2)工廠方法模式只有一個抽象工廠類谆刨,而抽象工廠模式有多個抽象工廠類塘娶。
(3)工廠方法模式的具體工廠類只能創(chuàng)建一個具體產(chǎn)品類的實例,而抽象工廠模式可以創(chuàng)建多個具體產(chǎn)品類的實例痊夭。
public class BMW320 {
public BMW320(){
System.out.println("制造-->BMW320");
}
}
public class BMW523 {
public BMW523(){
System.out.println("制造-->BMW523");
}
}
public class Customer {
public static void main(String[] args) {
BMW320 bmw320 = new BMW320();
BMW523 bmw523 = new BMW523();
}
}
這個例子刁岸,客戶必須要知道怎么去創(chuàng)建一款車才可以,這樣的話她我,客戶和車就緊密耦合在一起了虹曙。為了降低耦合,就出現(xiàn)了工廠類,把創(chuàng)建寶馬的操作細(xì)節(jié)都放到了工廠里面去,客戶直接使用工廠的創(chuàng)建工廠方法,傳入想要的寶馬車型號就行了,而不必去知道創(chuàng)建的細(xì)節(jié),這就是簡單工廠模式了番舆!
即我們建立一個工廠類方法來制造新的對象酝碳,如圖:
// 產(chǎn)品類
abstract class BMW {
public BMW(){
}
}
public class BMW320 extends BMW {
public BMW320() {
System.out.println("制造-->BMW320");
}
}
public class BMW523 extends BMW{
public BMW523(){
System.out.println("制造-->BMW523");
}
}
// 工廠類
public class Factory {
public BMW createBMW(int type) {
switch (type) {
case 320:
return new BMW320();
case 523:
return new BMW523();
default:
break;
}
return null;
}
}
// 客戶類
public class Customer {
public static void main(String[] args) {
Factory factory = new Factory();
BMW bmw320 = factory.createBMW(320);
BMW bmw523 = factory.createBMW(523);
}
}
簡單工廠模式又稱靜態(tài)工廠方法模式,它存在的目的很簡單:定義一個用于創(chuàng)建對象的接口恨狈。 先來看看它的組成:
- 工廠類角色:這是本模式的核心疏哗,含有一定的商業(yè)邏輯和判斷邏輯,用來創(chuàng)建產(chǎn)品
- 抽象產(chǎn)品角色:它一般是具體產(chǎn)品繼承的父類或者實現(xiàn)的接口
- 具體產(chǎn)品角色:工廠類所創(chuàng)建的對象就是此角色的實例禾怠。在java中由一個具體類實現(xiàn)返奉。
好了,現(xiàn)在假若客戶想要增加車型吗氏,比如奔馳芽偏、保時捷……那么,就需要在工廠類中增加相應(yīng)的創(chuàng)建業(yè)務(wù)邏輯弦讽,如果需要增加大量車型哮针,那就得吐血了,所以坦袍,就出現(xiàn)了工廠方法模式 十厢。
------- 工廠方法模式 ---------
工廠方法模式去掉了簡單工廠模式中工廠方法的靜態(tài)屬性,使得它可以被子類繼承捂齐,這樣在簡單工廠模式里集中在工廠方法上的壓力可以由工廠方法模式里不同的工廠子類來分擔(dān)蛮放。
工廠方法模式組成:
1)抽象工廠角色: 這是工廠方法模式的核心,它與應(yīng)用程序無關(guān)奠宜。是具體工廠角色必須實現(xiàn)的接口或者必須繼承的父類包颁。在java中它由抽象類或者接口來實現(xiàn)。
2)具體工廠角色:它含有和具體業(yè)務(wù)邏輯有關(guān)的代碼压真。由應(yīng)用程序調(diào)用以創(chuàng)建對應(yīng)的具體產(chǎn)品的對象娩嚼。
3)抽象產(chǎn)品角色:它是具體產(chǎn)品繼承的父類或者是實現(xiàn)的接口。在java中一般有抽象類或者接口來實現(xiàn)滴肿。
4)具體產(chǎn)品角色:具體工廠角色所創(chuàng)建的對象就是此角色的實例岳悟。在java中由具體的類來實現(xiàn)。
看如下代碼:
// 產(chǎn)品類
abstract class BMW {
public BMW(){
}
}
public class BMW320 extends BMW {
public BMW320() {
System.out.println("制造-->BMW320");
}
}
public class BMW523 extends BMW{
public BMW523(){
System.out.println("制造-->BMW523");
}
}
// 工廠類
interface FactoryBMW {
BMW createBMW();
}
public class FactoryBMW320 implements FactoryBMW{
@Override
public BMW320 createBMW() {
return new BMW320();
}
}
public class FactoryBMW523 implements FactoryBMW {
@Override
public BMW523 createBMW() {
return new BMW523();
}
}
// 客戶類
public class Customer {
public static void main(String[] args) {
FactoryBMW320 factoryBMW320 = new FactoryBMW320();
BMW320 bmw320 = factoryBMW320.createBMW();
FactoryBMW523 factoryBMW523 = new FactoryBMW523();
BMW523 bmw523 = factoryBMW523.createBMW();
}
}
工廠方法模式仿佛已經(jīng)很完美的對對象的創(chuàng)建進(jìn)行了包裝,使得客戶程序中僅僅處理抽象產(chǎn)品角色提供的接口贵少,但這樣會使得對象的數(shù)量成倍增長呵俏。當(dāng)產(chǎn)品種類非常多時,會出現(xiàn)大量的與之對應(yīng)的工廠對象滔灶,所以就出現(xiàn)抽象工廠模式了普碎。
---------- 抽象工廠模式 ---------
隨著客戶的要求越來越高,寶馬車需要不同配置的空調(diào)和發(fā)動機等配件录平。于是這個工廠開始生產(chǎn)空調(diào)和發(fā)動機麻车,用來組裝汽車。這時候工廠有兩個系列的產(chǎn)品:空調(diào)和發(fā)動機斗这。寶馬320系列配置A型號空調(diào)和A型號發(fā)動機动猬,寶馬230系列配置B型號空調(diào)和B型號發(fā)動機。
抽象工廠模式是工廠方法模式的升級版本涝影,他用來創(chuàng)建一組相關(guān)或者相互依賴的對象枣察,代碼:
// 產(chǎn)品類
//發(fā)動機以及型號
public interface Engine {
}
public class EngineA extends Engine{
public EngineA(){
System.out.println("制造-->EngineA");
}
}
public class EngineBextends Engine{
public EngineB(){
System.out.println("制造-->EngineB");
}
}
//空調(diào)以及型號
public interface Aircondition {
}
public class AirconditionA extends Aircondition{
public AirconditionA(){
System.out.println("制造-->AirconditionA");
}
}
public class AirconditionB extends Aircondition{
public AirconditionB(){
System.out.println("制造-->AirconditionB");
}
}
// 工廠類
//創(chuàng)建工廠的接口
public interface AbstractFactory {
//制造發(fā)動機
public Engine createEngine();
//制造空調(diào)
public Aircondition createAircondition();
}
//為寶馬320系列生產(chǎn)配件
public class FactoryBMW320 implements AbstractFactory{
@Override
public Engine createEngine() {
return new EngineA();
}
@Override
public Aircondition createAircondition() {
return new AirconditionA();
}
}
//寶馬523系列
public class FactoryBMW523 implements AbstractFactory {
@Override
public Engine createEngine() {
return new EngineB();
}
@Override
public Aircondition createAircondition() {
return new AirconditionB();
}
}
// 客戶類
public class Customer {
public static void main(String[] args){
//生產(chǎn)寶馬320系列配件
FactoryBMW320 factoryBMW320 = new FactoryBMW320();
factoryBMW320.createEngine();
factoryBMW320.createAircondition();
//生產(chǎn)寶馬523系列配件
FactoryBMW523 factoryBMW523 = new FactoryBMW523();
factoryBMW320.createEngine();
factoryBMW320.createAircondition();
}
}
抽象工廠模式和工廠方法模式的區(qū)別,仔細(xì)看代碼就能體會燃逻。