Java 七大设计原则 - 依赖倒置原则/面向接口编程
一、什么是依賴倒置原則(Dependence Inversion Principle, DIP) ?? - 面向接口編程(Object-Oriented Design, OOD)
? (1)?高層模塊與低層模塊都應該依賴其“抽象”
? ? ? ? ?模塊間的依賴通過抽象發生,實現類之間不發生直接的依賴關系,其依賴關系是通過接口或抽象類產生的
? (2)?抽象不應該依賴細節
? ? ? ? ? ?java 接口或抽象類不依賴于實現類
? (3) 細節應該依賴抽象
? ? ? ? ? ? java 實現類依賴于接口或抽象類
?? 每一個邏輯的實現都是由原子邏輯組成的,不可分割的原子邏輯就是低層模塊(一般是接口,抽象類),原子邏輯的組裝就是高層模塊。
? ? 在Java語言中,抽象就是指接口和或抽象類,兩者都不能被直接實例化,細節就是實現類,實現接口或繼承抽象類而產生的類就是細節,可以被直接實例化。
?依賴倒置原則的本質就是通過抽象(抽象類或接口)使各個類或模塊實現彼此獨立,不互相影響,實現模塊間的松耦合。在項目中使用這個規則需要以下原則;
二、為什么要這么做?
? ? ? DIP好處: 采用依賴倒置原則可以減少類間的耦合性,提高系統的穩定性,降低并行開發引起的風險,提高代碼的可讀性和可維護性。
看例子
2.1 :? 老師在學校教張三學習
public class Teacher{//老師的職責是教學生public void teach(Zhangsan zhangSan){zhangSan.study();} }public class ZhangSan {//張三學習public void study(){System.out.println("張三開始學習");} }//學校模塊調用 老師模塊 和 學生模塊 public class School {public static void main(String[] args) {Teacher tt = new Teacher();ZhangSan zz = new ZhangSan();//老師教張三學習tt.drive(zz);}}?但是、假如新來一個學生 lisi、老師是否還能教學呢?
?上面的設計沒有使用依賴倒置原則,模塊與模塊之間耦合度太高,生產力太低,只要需求一變就需要大面積重構,說明這樣的設計是不合理。
重新設計:
? ? ?在新增低層模塊時,只修改了高層模塊(業務場景類),對其他低層模塊(Driver類)不需要做任何修改,可以把"變更"的風險降低到最低
1. 老師抽象 public interface ITeacher {//老師教學public void teach(IStudent student); }2. 李老師(老師實現) public class LiTeacher implements ITeacher{@overridepublic void teach(IStudent student){student.study();} }3. 學生抽象 public interface IStudent {//學生學習public void study(); }4. 張學生(學生實現) public class ZhangSan implements IStudent{@overidepublic void run(){System.out.println("學習");} }5. 李學生(學生實現) public class LiSi implements IStudent{@overidepublic void run(){System.out.println("學習");} }6. //學校public class School {public static void main(String[] args) {ITeacher liTeacher = new liTeacher();//張學生(學生實現)IStudent zz =new ZhangSan();//李學生(學生實現)IStudent ll =new ZhangSan();liTeacher.teach(zz);liTeacher.teach(ll);} }? ??
?? ?在Java中,只要定義變量就必然有類型,并且可以有兩種類型:表面類型和實際類型,表面類型是在定義時賦予的類型,實際類型是對象的類型。就如上面的例子中,ZhangSan 的表面類型是IStudent ,實際類型是 ZhangSanStudent。
?? 抽象是對實現的約束,是對依賴者的一種契約,不僅僅約束自己,還同時約束自己與外部的關系,其目的就是保證所有的細節不脫離契約的范疇,確保約束雙方按照規定好的契約(抽象)共同發展,只要抽象這條線還在,細節就脫離不了這個圈圈。
2.2? 傳遞依賴抽象對象、增加系統結構穩定性
構造函數傳遞依賴對象: 在類中通過構造函數聲明依賴對象(好比Spring中的構造器注入),
采用構造器注入。
public class LiTeacher implements ITeacher{//類構造 - 依賴注入public void LiTeacher(IStudent student ){}@overridepublic void teach(IStudent student){student.study();} }?也可以接口設置
public interface ITeacher{//接口中 注入依賴public void setStudent(IStudent student);}
?
總結:
1. 每個類盡量都要有接口或抽象類,或者抽象類和接口都有:
? ? ?(依賴倒置原則的基本要求,有抽象才能依賴倒置)
2.變量的表面類型盡量是接口或者抽象類
3.任何類都不應該從具體類派生
4. 盡量不要重寫基類已經寫好的方法(里式替換原則)
5. 結合里式替換原則來使用: 結合里式替換原則和依賴倒置原則我們可以得出一個通俗的規則,接口負責定義public屬性和方法,并且聲明與其他對象的依賴關系,抽象類負責公共構造部分的實現,實現精準的實現業務邏輯,同時在適當的時候對父類進行細化。
?
總結
以上是生活随笔為你收集整理的Java 七大设计原则 - 依赖倒置原则/面向接口编程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vue项目通讯录_Vue实现类似通讯录功
- 下一篇: 插入排序Java代码实现