我的博客原文:
依賴倒置原則java
設計模式六大原則之三:依賴倒置原則。git
姓名 :依賴倒置原則github
英文名 :Dependence Inversion Principle編程
價值觀 :大男子主義的典型表明,什麼都得經過老大或者老爸贊成設計模式
伴侶 :必定是個溫柔體貼的女子ide
我的介紹 :工具
給你們講個故事,我胡亂想的,若有雷同,確定是英雄所見略同。那必須交個朋友。測試
一個小村裏,有兩家飯館,雖然掛着不一樣的牌子,挨在一塊兒,可是老闆確是表兄弟。這兩兄弟摳得很,爲了節省成本,密謀了一個想法:在兩家飯館誰家忙的時候,可讓不忙的那家的員工過去支援一下。這樣子,原本每家飯館都須要 2 個洗碗工,總共須要 4 個,他們就只招了 3 個,省了 1 個洗碗工的成本,固然不止洗碗工,還有服務員等等。兩兄弟約定了規則:this
大概經過這個小故事,描述了依賴倒置原則的基本內容。設計
下面經過代碼來模擬這個故事。
這個錯誤的示範將就看哈,可能有些問題沒描述清楚。
abstract class Boss { abstract void support(); abstract void askHelp(Boss boss); } abstract class Staff { private String name; abstract void service(); abstract void askHelp(Boss boss); public String getName() { return name; } public void setName(String name) { this.name = name; } }
class BossA extends Boss { private StaffA staffA; public BossA(StaffA staffA) { this.staffA = staffA; } @Override void support() { staffA.service(); } @Override void askHelp(Boss boss) { boss.support(); } } class BossB extends Boss { private StaffB staffB; public BossB(StaffB staffB) { this.staffB = staffB; } @Override void support() { staffB.service(); } @Override void askHelp(Boss boss) { boss.support(); } }
class StaffA extends Staff { public StaffA(String name) { this.setName(name); } @Override void service() { System.out.println(this.getName() + "提供服務"); } @Override void askHelp(Boss boss) { boss.support(); } } class StaffB extends Staff { public StaffB(String name) { this.setName(name); } @Override void service() { System.out.println(this.getName() + "提供服務"); } @Override void askHelp(Boss boss) { boss.support(); } }
/** 初始化老闆和員工 */ StaffA staffA = new StaffA("A 員工"); StaffB staffB = new StaffB(" B 員工"); Boss bossA = new BossA(staffA); Boss bossB = new BossB(staffB); /** A 老闆向 B 老闆求支援 */ bossA.askHelp(bossB); // 打印出:B 員工提供服務 /** B 員工向 A 老闆求支援 */ staffB.askHelp(bossA); // 打印出:A 員工提供服務
好像看起來實現了要求了,可是其實這段代碼沒有按照上面的 3 點規則編寫,破壞了第 3 點規則,老闆們的員工沒有用員工的抽象類,破壞了細節依賴抽象這一點。設想一下,假如如今 A 老闆把 A 員工辭退了,從新招了個 C 員工,那麼怎麼實現呢?是否是須要再新增一個 StaffC 類,而後再修改 BossA 類代碼,把 StaffA 換成 StaffC。這樣超級麻煩,在平時寫項目中要時刻考慮這一點:在具體實現類使用其餘類,是否是能夠用其抽象類?
代碼:
看了上面那個憋屈的代碼,再來看下面簡潔的代碼,纔會發現依賴倒置原則是多麼強大。
abstract class Boss2 { private Staff2 staff; public Boss2(Staff2 staff) { this.staff = staff; } abstract void support(); abstract void askHelp(Boss2 boss); public void setStaff(Staff2 staff) { this.staff = staff; } public Staff2 getStaff() { return staff; } } abstract class Staff2 { private String name; abstract void service(); abstract void askHelp(Boss2 boss); public void setName(String name) { this.name = name; } public String getName() { return name; } }
class BossImpl extends Boss2 { public BossImpl(Staff2 staff) { super(staff); } @Override void support() { this.getStaff().service(); } @Override void askHelp(Boss2 boss) { boss.support(); } }
class StaffImpl extends Staff2{ public StaffImpl(String name) { this.setName(name); } @Override void service() { System.out.println(this.getName() + "提供服務"); } @Override void askHelp(Boss2 boss) { boss.support(); } }
/** 正確示範 */ Staff2 staffA2 = new StaffImpl("A 員工"); Staff2 staffB2 = new StaffImpl("B 員工"); Boss2 bossA2 = new BossImpl(staffA2); Boss2 bossB2 = new BossImpl(staffB2); /** A 老闆向 B 老闆求支援 */ bossA2.askHelp(bossB2); // 打印出:B 員工提供服務 /** B 員工向 A 老闆求支援 */ staffB2.askHelp(bossA2); // 打印出:A 員工提供服務 /** A 老闆辭退了 A 員工,換成了 C 員工 */ Staff2 staffC2 = new StaffImpl("C 員工"); bossA2.setStaff(staffC2); /** B 員工向 A 老闆求支援 */ staffB2.askHelp(bossA2); // 打印出:C 員工提供服務
這代碼相比上面錯誤的示範,簡潔了不少,實現的功能卻更靈活,這就是依賴倒置原則強大的地方,它能夠將類的耦合性下降,提供靈活的處理。
代碼:
總的來講,要實現依賴倒置原則,要有『面向接口編程』這個思惟,掌握好這個思惟後,就能夠很好的運用依賴倒置原則。
參考資料:《大話設計模式》、《Java設計模式》、《設計模式之禪》、《研磨設計模式》、《Head First 設計模式》
但願文章對您有所幫助,設計模式系列會持續更新,感興趣的同窗能夠關注公衆號,第一時間獲取文章推送閱讀,也能夠一塊兒交流,交個朋友。