工廠模式是一種建立型模式,在工廠模式中,建立物件時不會對客戶端暴露建立細節(將建立的**封裝到乙個工廠類中),而是通過乙個介面指向由工廠類建立並返回的物件。
對於設計模式和各個原則來說,無非就是要實現**的高內聚和低耦合,還有盡量遵循開閉原則。開閉原則簡單來說就是:軟體中的物件(類,函式,模組)對擴充套件開放,對修改關閉。
於是,圍繞開閉原則展開以下討論。
傳統工廠模式是如何違背了開閉原則的,工廠模式加反射機制是如何遵循開閉原則的。
以披薩為話題,我們要建立各種口味的披薩,例如乳酪披薩,水果披薩。
這個顯然可以就通過工廠模式來實現,下面用傳統工廠模式。
首先我們要宣告乙個ipizza介面:
public
inte***ce
ipizza
ipizza的實現類:
//乳酪披薩
public
class
cheesepizza
implements
ipizza
}
//水果披薩
public
class
fruitpizza
implements
ipizza
}
下面通過工廠建立各種口味的披薩。
寫乙個工廠類,把建立各種口味披薩的任務交給它。
//披薩工廠類
public
class
pizzafactory
public
static ipizza createpizza
(string pizzatype)
elseif(
"水果披薩"
.equals
(pizzatype)
)return pizza;
}}
測試:
public
class
pizzatest
}
控制台結果:
ok!就是那麼簡單,但是問題來了,我現在突然想到還有一種口味的披薩:蛋黃披薩。我想把它新增到系統中,要怎麼做呢?
第一步,實現ipizza介面
//蛋黃披薩
public
class
eggyolkpizza
implements
ipizza
}
第二步,修改工廠類(emmm,思考一下,這是不是違背了開閉原則)
修改過程就是新增乙個else if分支。
public
class
pizzafactory
public
static ipizza createpizza
(string pizzatype)
elseif(
"水果披薩"
.equals
(pizzatype)
)elseif(
"蛋黃披薩"
.equals
(pizzatype)
)return pizza;
}}
**搞定,測試一下:
新增披薩口味是成功了,但是我們也違背了開閉原則,如果有很多個口味的披薩引進來,那我們豈不是要改工廠類改到吐?
同樣也是寫乙個工廠類,把建立各種口味披薩的任務交給它。
public
class
pizzafactory
public
static ipizza createpizza
(string pizzatype)
catch
(exception e)
return pizza;
}}
測試:
public
class
pizzatest
}
控制台結果:
ok!新增乙個口味的披薩,還是蛋黃披薩吧。
很簡單,只需要擴充套件多乙個類就行了,不需要取修改工廠類。
只需一步,擴充套件乙個蛋黃披薩的類
public
class
eggyolkpizza
implements
ipizza
}
測試:
搞定。這樣無論要加多少種口味,只需要拓展就行了,這不就很好的遵循了開閉原則嗎,無論新增多少個披薩類,都不用對工廠類進行任何改變,直接在客戶端(main方法)呼叫即可,相比較與傳統工廠模式簡直不要方便太多。
很顯然,傳統工廠模式違背了開閉原則(擴充套件新口味要修改工廠類),而工廠模式結合反射的方式則沒有違背。只不過是後者傳參的方式變成了傳全限定類名。
設計模式 開閉原則
開閉原則的核心是 對擴充套件開放,對修改關閉 白話意思就是我們改變乙個軟體時 比如擴充套件其他功能 應該通過擴充套件的方式來達到軟體的改變,而不應愛修改原有 來實現變化 軟體系統中包含的各種元件,例如模組 modules 類 classes 以及功能 functions 等等,應該在不修改現有 的基...
設計模式 開閉原則
設計模式 開閉原則 即 對立與統一原則 軟體實體應該對擴充套件開放,對修改關閉,即實體應當通過擴充套件實現變化,而不是修改 實現變化 什麼是軟體實體,專案或軟體中按照一定邏輯規劃劃分的模組 抽象 類 方法書店銷售書籍 然後書寫 如下 書籍介面 public inte ce ibook 書店 類書籍,...
設計模式 開閉原則
ocp原則 開閉原則 1 對外能擴充套件 提供方 2 對修改關閉 使用方 下面這段 實現了繪製形狀的功能,如果設計如下 package ocp author lihaiyu date 2020 11 8 20 50 public class ocp 這是乙個用於繪製圖形的類,使用方 class gr...