設計模式遵循原則
- 開閉原則:對擴展開放,對修改關閉
- 里氏代換原則:只有當衍生類可以替換掉基類,軟件單位的功能不受到影響時,基類才能真正被覆用。而衍生類也能夠在基類的基礎上增加新的行為
- 依賴倒轉原則:開閉原則的基礎,對接口編程,依賴于抽象而不依賴于具體
- 接口隔離原則:使用多個隔離的接口來降低耦合度
- 迪米特法原則:最少知道原則。一個實體應該盡量少的與其他實體之間發生相互作用,使得系統功能模塊相對獨立
- 合成復用原則:盡量使用合成/聚合的方式,而不是使用繼承。繼承實際上破環了類的封裝性,超類的方法可能會被子類修改。
工廠模式
簡單工廠模式
簡單工廠模式當中,一個工廠負責生產所有的產品。如上圖所示,無論是戴爾鼠標還是惠普鼠標,都在一家鼠標工廠中生產。工廠通過用戶的需要生產不同的鼠標,即用戶傳入生產鼠標的參數,工廠返回生產出的鼠標實體。
具體實現如下:
//鼠標基類 class Mouse{public void sayHi(){}; } //鼠標擴展類 class DellMouse extends Mouse{@Overridepublic void sayHi() {System.out.println("產品:戴爾鼠標");} } class HpMouse extends Mouse{@Overridepublic void sayHi() {System.out.println("產品:惠普鼠標");} } //鼠標工廠 class MouseFactory{//生產鼠標的方法,所有的鼠標都通過該方法生成public static Mouse createMouse(int i) {switch (i) {case 0: return new DellMouse();case 1: return new HpMouse();default: return null;}} } public class NormFactory {public static void main(String[] args) {Mouse hpm = MouseFactory.createMouse(1);Mouse dellm = MouseFactory.createMouse(0);hpm.sayHi();dellm.sayHi();} }
打印結果如下:
產品:惠普鼠標
產品:戴爾鼠標
上述模式下,所有的鼠標都在同一個MouseFactory工廠下生產,有一個統一的create靜態方法。在使用工廠時,不需要對工廠進行實例化,只需要調用該靜態方法便可得到相應的產品。
但如果用戶需要添加新一類的產品,例如有一項華碩鼠標,工廠要生產該產品則需要改create函數,這有悖于設計原則的開閉原則。
工廠模式
在該模式下,不同品牌的產品交由不同的工廠來生產,有一個統一的工廠接口,生產該產品的工廠都要實現該接口。
生產哪種產品不再由參數決定,而是在創建工廠時讓工廠來決定,例如惠普的工廠只會生產惠普的鼠標,而戴爾的工廠只會生產戴爾的鼠標。
具體實現如下:
class Mouse{public void sayHi(){}; }class DellMouse extends Mouse{@Overridepublic void sayHi() {System.out.println("產品:戴爾鼠標");} } class HpMouse extends Mouse{@Overridepublic void sayHi() {System.out.println("產品:惠普鼠標");} } //生產工廠接口 interface MouseFactory{public Mouse createMouse(); } //不同的鼠標交由不同的工廠生產 class HpMouseFactory implements MouseFactory{@Overridepublic Mouse createMouse() {return new HpMouse();} } class DellMouseFactory implements MouseFactory{@Overridepublic Mouse createMouse() {return new DellMouse();} } public class NormFactory {public static void main(String[] args) {MouseFactory hpFact = new HpMouseFactory();MouseFactory dellFact = new DellMouseFactory();Mouse hpm = hpFact.createMouse();Mouse dellm = dellFact.createMouse();hpm.sayHi();dellm.sayHi();} }
打印結果如下:
產品:惠普鼠標
產品:戴爾鼠標
該模式下代碼的可擴展性大大提高,當需要添加一種商品時,只需要添加生產該商品的工廠,并讓其實現生產工廠接口即可。
但在該模式下,商品的生產變得更為復雜,我們要得到一件商品,必須先得到一座生產該商品的工廠,再調用該工廠的生產方法才能得到該商品。
抽象工廠模式
、
該模式下的工廠生產的產品不唯一,同一品牌的工廠有著各種不同的產品,相當于是工廠模式的一個加強版。
具體實現如下:
class Mouse{public void sayHi(){}; }class DellMouse extends Mouse {@Overridepublic void sayHi() {System.out.println("產品:戴爾鼠標");} } class HpMouse extends Mouse {@Overridepublic void sayHi() {System.out.println("產品:惠普鼠標");} }class KeyBoard {public void kick(){}; } class HpKeyBoard extends KeyBoard {@Overridepublic void kick() {System.out.println("產品:惠普鍵盤");} } class DellKeyBoard extends KeyBoard {@Overridepublic void kick() {System.out.println("產品:戴爾鍵盤");} } //總的工廠接口 interface PcFactory {public Mouse createMouse() ;public KeyBoard createKeyBoard() ; } class HpFactory implements PcFactory {@Overridepublic Mouse createMouse() {return new HpMouse();}@Overridepublic KeyBoard createKeyBoard() {return new HpKeyBoard();} } class DellFactory implements PcFactory {@Overridepublic Mouse createMouse() {return new DellMouse();}@Overridepublic KeyBoard createKeyBoard() {return new DellKeyBoard();} }//當需要增加一個華碩工廠時: class AsusMouse extends Mouse {@Overridepublic void sayHi() {System.out.println("產品:華碩鼠標");} } class AsusKeyBoard extends KeyBoard {@Overridepublic void kick() {System.out.println("產品:華碩鍵盤");} } class AsusFactory implements PcFactory {@Overridepublic Mouse createMouse() {return new AsusMouse();}@Overridepublic KeyBoard createKeyBoard() {return new AsusKeyBoard();} }public class NormFactory {public static void main(String[] args) {PcFactory hpFact = new HpFactory();Mouse hpm = hpFact.createMouse();KeyBoard hpkbd = hpFact.createKeyBoard();PcFactory dellFact = new DellFactory();Mouse dellm = dellFact.createMouse();KeyBoard dellkbd = dellFact.createKeyBoard();hpm.sayHi();dellm.sayHi();hpkbd.kick();dellkbd.kick();} }
打印結果如下:
產品:惠普鼠標
產品:戴爾鼠標
產品:惠普鍵盤
產品:戴爾鍵盤
但該模式如果要添加產品時,需要修改PcFactory、DellFactory、HpFactory等所有實現了PcFactroy接口的工廠類,這是十分不好的。