日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

接口隔离原则_设计模式六大原则

發布時間:2025/4/16 asp.net 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 接口隔离原则_设计模式六大原则 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

作者:VieLei
原文:https://blog.csdn.net/s10461/article/details/53941097

在android中我們常提起的設計模式大約有23種,利用好設計模式能夠幫助我們很好的構建代碼結構,也便于我們以后的維護。每次看完,看的時候總覺得很明白,但是過一段時間以后都會忘記,或只記得一些片段,又或到真正使用起來的時候才會發現一系列的問題。本系列筆記會從頭記錄這23種設計模式,當然一定會有不正確的地方。

本系列筆記參考了《設計模式之禪》、《Android源碼設計模式解析與實戰》以及huachao1001的 從Android代碼中來記憶23種設計模式一文。

開始之前

在所有的設計模式之前都會先將面向對象的六大原則,大部分同學都已經很明白了,所以在這里也想記錄一些不一樣的東西。

單一職責原則(SRP)

一個類所承擔的功能或指責必須是同一類或者相近的,不要讓一個類承擔過多的職責。換一句話說,一個類的職責應該單一。但是在我們的使用過程中,在大部分應用中很難做到真正意義上的指責單一,所以對于單一職責原則我是這么理解的:

接口的職責必須單一。

類的設計盡量做到只有一個原因引起類的變化,指的是設計類而不是實現類,實現類做到單一職責的話無形中會增加很多類,會使原本簡單的事情變得更加復雜。

開閉原則(OCP)

一個軟件實體應該對擴展開發,對修改關閉。其含義是說一個軟件實體應該通過擴展實現變化,而不是通過修改內部已有的代碼來實現變化。

軟件實體是什么?

  • 項目或軟件產品中按照一定邏輯劃分的模塊

  • 抽象和類

  • 方法

開閉原則指導我們,當軟件需要變化時應”盡量通過”擴展的方式來修改,而不是通過變化已有代碼來實現,這里說的是盡量,并不是絕對不可以修改原始類,當我們嗅到“腐化”氣味時應盡量早重構。而不是通過繼承等方式添加新的實現,這會導致類的膨脹及歷史代碼的遺留。

通常我們可以用接口或抽象類來約束一組可變化的行為。主要包含3個層次:

第一:通過接口或抽象類約束擴展,對擴展邊界定義,不允許實現類出現接口或抽象類以外的public 方法。
第二:參數類型、引用變量盡量使用接口或抽象對類,而不是實現類。
第三:抽象層盡量保持穩定。
當然在實際應用過程中,往往修改源代碼和擴展是同時存在的。

里氏替換原則(LSP)

有兩種解釋方法,有一種特別麻煩、特別繞的就不再說了。

  • 所有引用基類的地方必須能透明地使用其子類對象。

依然比較繞,通俗一點解釋是這樣的:只要任何有父類出現的地方(如形參),都可以替換為子類,而且替換為子類也不會產生異常和錯誤。對于使用者(方法)本身不需要關心到底是父類還是子類。

但是,有子類出現的地方,替換為父類就不一定可以了。

舉個例子:

//窗口類
public?class?Window(){
????public?void?show(View?child){
????????child.draw();
????}
}
public?abstract?class?View(){
????public?abstract?void?draw();
????public?void?measure(int?widht,int?height){
????????//測量視圖大小
????}
}
public?class?Button?extends?View{
????public?void?draw(){
????????//繪制按鈕
????}
}

public?class?TextView?extends?View{
????public?void?draw(){
????????//繪制文本
????}
}

里氏替換原則為良好的繼承定義了一個規范:

  • 1、子類必須完全實現父類的方法。我們在做系統設計的時候經常定義一個接口或抽象類,然后編碼實現,調用類直接傳入接口或抽象類,其實這里已經使用了里氏原則。

如果子類不能全實現父類的方法,或者父類的某些方法在子類中已經發生畸變,建議斷開繼承關系,采用依賴、聚合、組合等關系代替。

  • 2、子類有自己的個性。即有子類出現的地方,父類未必可以。

  • 3、覆蓋或實子類重載父類的方法時,傳入的參數必須比父類更寬松(相同或范圍大)。(否則會出現本來虛調用父類方法的地方調用了子類的方法)

  • 4、覆蓋或實子類重載父類的方法時,返回的結果必須范圍更小(和父類類型相同或是父類返回類型的子類)。
    依賴倒置原則(DIP)
    依賴倒置主要是實現解耦,使得高層次的模塊不依賴于低層次模塊的具體實現細節。怎么去理解它呢,我們需要知道幾個關鍵點:

(1)高層模塊不應該依賴底層模塊(具體實現),二者都應該依賴其抽象(抽象類或接口)。模塊之間的依賴通過抽象產生,實現類之間不發生直接依賴關系,依賴關系通過接口或抽象類產生。

高層模塊就是調用端,底層模塊就是具體實現類。

(2)抽象不應該依賴細節(廢話,抽象類跟接口肯定不依賴具體的實現了)

(3)細節應該依賴于抽象(同樣廢話,具體實現類肯定要依賴其繼承的抽象類或接口)
在我們用的Java語言中,抽象就是指接口或者抽象類,二者都是不能直接被實例化;細節就是實現類,實現接口或者繼承抽象類而產生的類,就是細節。使用Java語言描述就簡單了:就是各個模塊之間相互傳遞的參數聲明為抽象類型,而不是聲明為具體的實現類;

依賴導致的本質是通過抽象使各個類或者模塊的實現彼此獨立,不相互影響,實現模塊間的松耦合。

每個類(底層模塊)盡量有接口和抽象類,或者接口抽象類二者皆有。
變量的聲明盡量是抽象或者接口
盡量不覆蓋父類的方法
里氏替換原則
一個例子:
母親給孩子講故事,只要給她一本書,她就可以照著書給孩子講故事了。代碼如下:

class?Book{??
????public?String?getContent(){??
????????return?"很久很久以前有一個阿拉伯的故事……";??
????}??
}??

class?Mother{??
????public?void?narrate(Book?book){??
????????System.out.println("媽媽開始講故事");??
????????System.out.println(book.getContent());??
????}??
}??

public?class?Client{??
????public?static?void?main(String[]?args){??
????????Mother?mother?=?new?Mother();??
????????mother.narrate(new?Book());??
????}??
}??

運行結果:媽媽開始講故事 很久很久以前有一個阿拉伯的故事……

運行良好,假如有一天,需求變成這樣:不是給書而是給一份報紙,讓這位母親講一下報紙上的故事,報紙的代碼如下:

class?Newspaper{??
????public?String?getContent(){??
????????return?"林書豪38+7領導尼克斯擊敗湖人……";??
????}??
}??

這位母親卻辦不到,因為她居然不會讀報紙上的故事,這太荒唐了,只是將書換成報紙,居然必須要修改Mother才能讀。假如以后需求換成雜志呢?換成網頁呢?還要不斷地修改Mother,這顯然不是好的設計。原因就是Mother與Book之間的耦合性太高了,必須降低他們之間的耦合度才行。

我們引入一個抽象的接口IReader。讀物,只要是帶字的都屬于讀物:

interface?IReader{??
????public?String?getContent();??
}??

Mother類與接口IReader發生依賴關系,而Book和Newspaper都屬于讀物的范疇,他們各自都去實現IReader接口,這樣就符合依賴倒置原則了,代碼修改為:

class?Newspaper?implements?IReader?{??
????public?String?getContent(){??
????????return?"林書豪17+9助尼克斯擊敗老鷹……";??
????}??
}??

class?Book?implements?IReader{??
????public?String?getContent(){??
????????return?"很久很久以前有一個阿拉伯的故事……";??
????}??
}??

class?Mother{??
????public?void?narrate(IReader?reader){??
????????System.out.println("媽媽開始講故事");??
????????System.out.println(reader.getContent());??
????}??
}??

public?class?Client{??
????public?static?void?main(String[]?args){??
????????Mother?mother?=?new?Mother();??
????????mother.narrate(new?Book());??
????????mother.narrate(new?Newspaper());??
????}??
}?????

這樣修改后,無論以后怎樣擴展Client類,都不需要再修改Mother類了。這只是一個簡單的例子,實際情況中,代表高層模塊的Mother類將負責完成主要的業務邏輯,一旦需要對它進行修改,引入錯誤的風險極大。所以遵循依賴倒置原則可以降低類之間的耦合性,提高系統的穩定性,降低修改程序造成的風險。

依賴倒置原則在Java中的表現就是:模塊間通過抽象發生,實現類之間不發生直接依賴關系,其依賴關系是通過接口或者抽象類產生的。如果類與類直接依賴細節,那么就會直接耦合,那么當修改時,就會同時修改依賴者代碼,這樣限制了可擴展性。

接口隔離原則(ISP)
關于接口有一點要說明:類也是接口

有兩種定義方法:一種為類不應該依賴它不需要的接口;另一種為類之間的依賴關系應該建立在最小的接口上。接口隔離的原則是將非常龐大、臃腫的接口分割成更小更具體的接口。

有的時候會感覺單一職責和接口隔離隔離原則很像,單一職責更關注的是功能的單一,是業務層次上的劃分。而接口隔離原則更關心的是接口的數量要少。

比如說一個接口有一組10個功能,提供給若干個模塊使用,每個模塊按照按照不同的權限只能使用接口中的一部分功能。按照單一職責原則是允許的,但是按照接口隔離原則是不允許的,接口隔離原則要求:”盡量使用多個專用接口”,意思為有幾個模塊就提供幾個接口,而不是建立一個龐大的接口供所有模塊使用。

接口設計時有限度的,當然也不要分了隔離接口而將全部接口都細化,這樣就變為過度設計了

最佳實踐:

  • 一個接口只服務于一個模塊或業務流程

  • 壓縮接口對外提供的public方法

迪米特原則(LOD)

一個對象應該對一個被調用的類(被耦合)有最少的了解。調用者只需要知道它需要調用的方法即可。類與類之間的關系越密切,當一個類發生改變時,對另一個類影響也越大。

迪米特原則包含的四層含義:

  • 只和朋友交流:每個類必然會和其他類有耦合關系,兩個對象間的耦合就成為朋友關系(聚合、組合、依賴等)。朋友類得定義是這樣的:出現在成員變量、方法的輸入、輸出參數中的稱為成員朋友類,而出現在方法體內部的類不屬于朋友類。

  • 朋友之間也是有距離的:不要對外公布太多的public方法和非靜態的public變量,盡量內斂。

迪米特原則的核心觀念是:解耦。即:高內聚、低耦合。

最后

  • 單一職責原則 (SRP)

  • 開閉原則 (OCP)

  • 里氏替換原則 (LSP)

  • 迪米特原則 (LOD)

  • 接口隔離原則 (ISP)

  • 依賴倒置原則 (DIP)
    至此設計模式的6大基礎原則幾經全部介紹完畢,將6大原則的首字母組合起來,就是SOLID(穩定的)。

不是說按照一定的設計模式來設計程序就能應對各種場景,或不對代碼結構做任何修改。只是我們在進行程序設計的時候盡量遵循這6大原則。

長按關注,更多精彩

看完,有收獲就點個“好看”鴨

↓↓↓↓

總結

以上是生活随笔為你收集整理的接口隔离原则_设计模式六大原则的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。