摘要:接口隔離原則是什么客戶端代碼不應(yīng)當(dāng)被迫依賴于它們不需要的方法。
這是理解SOLID原則,關(guān)于接口隔離原則如何幫助我們創(chuàng)建簡單的抽象接口,并使客戶端代與接口之間存在的更少的依賴關(guān)系。接口隔離原則是什么
Clients should not be forced to depend on methods that they do not use.客戶端代碼不應(yīng)當(dāng)被迫依賴于它們不需要的方法。
這個原則本身與單一職責(zé)原則關(guān)系十分緊密,它意味著當(dāng)你在定義你的抽象層代碼時,不應(yīng)當(dāng)在客戶端代碼在實現(xiàn)抽象邏輯時,暴露一些客戶端代碼不需要使用或者關(guān)心的方法。
進一步說明的話,就是當(dāng)你有意地在抽象層中暴露的方法時,這意味著所有實現(xiàn)這些抽象邏輯的客戶端代碼都必須要實現(xiàn)所有的抽象方法,盡管這些方法并不一定都對客戶端代碼有意義。
將你的接口的保持精簡和小顆粒度,并且不要在它們中間增加無用的抽象方法,當(dāng)你在對新的抽象接口進行命名時,你就會擁有更好的選擇,因為你已有了若干小顆粒的命名類型。這樣做的意義在于當(dāng)你在需要提供一個更加大顆粒度的抽象接口時,你可以擁有足夠的靈活性來將已有的小顆粒度接口進行組合。
如何實踐接口隔離原則這個例子是關(guān)于一個ATM用戶界面的抽象接口,這個接口會處理諸如存款請求、取款請求等邏輯,從這個例子中我們會了解到,我們?nèi)绾螌@個接口進行隔離,使其進一步劃分為多個獨立的、更加具體的若干接口。
首先我們應(yīng)當(dāng)有一個工具函數(shù)庫接口,這個接口會描述我們想要暴露的關(guān)于byte操作邏輯的方法,讓我們創(chuàng)建這樣一個接口,如下
type ByteUtils interface { Read(b []byte) (n int, err error) // Read into buffer Write(b []byte)(n int, err error) // Write into buffer Trim(b []byte, exclusions string)[]byte // Trim buffer by removing bytes from the exclusion chars }
它可以正常工作一段時間,但是很快我們就會發(fā)現(xiàn)以下兩個問題:
它的命名ByteUtils太過于通用,如果我們僅通過命名本身,基本無法獲取任何具體的信息
當(dāng)使用它時,會有一些古怪的感覺,因為當(dāng)你根據(jù)不同的優(yōu)化場景來按不同邏輯實現(xiàn)trim方法時,你所實現(xiàn)的read和write幾乎沒什么差別,但是你卻需要重復(fù)地實現(xiàn)它們,同時在某些不需要讀或者寫的場景,仍然需要實現(xiàn)它們。
所以它雖然能夠正常工作,但是卻不夠好。
我們可以通過創(chuàng)建三個更精簡、更具體的接口來替代原先通用的接口:
type Reader interface { Read(b []byte) (n int, err error) } type Writer interface { Write(b []byte)(n int, err error) } type Trimmer interface { Trim(b []byte, exclusions string)[]byte }
這種顆粒度比較細的接口也可以稱為角色接口,因為它們更易于重構(gòu)和改變,甚至對于已經(jīng)定義好的角色和目的也可以很容易的進行重新部署和定義。
在這三個基礎(chǔ)上,我們可以通過組合它們來獲取一個更有關(guān)聯(lián)性的接口列表,比如:
type ReadWriter interface { Reader Writer } type TrimReader interface { Trimmer Reader }
這意味客戶端代碼擁有了可以根據(jù)它們各自的需求來組合抽象層接口的靈活性,這樣就會避免在實現(xiàn)抽象接口時不必要的麻煩(比如必須要實現(xiàn)某些無用的方法),比如上面的TrimReader的實現(xiàn)并未包含多余的Write方法的聲明。
總結(jié)正如你所看到的,通用的接口往往會無意識的將自己和類的實現(xiàn)耦合在了一起,所以你應(yīng)當(dāng)盡量的避免這種情況的發(fā)生。在設(shè)計接口時,你應(yīng)當(dāng)時刻提醒自己,我是否需要使用所有在接口中聲明的方法呢?如果不是的話,將接口細分為更多個更精簡、更具體的接口。
正如甘地曾經(jīng)說過:
你的行動決定你的習(xí)慣,你的習(xí)慣決定你的價值,你的價值會決定你的命運。
如果在架構(gòu)中,你每次都會經(jīng)過仔細思考,會按照好的模式來進行設(shè)計,它將會成為一種習(xí)慣,自然慢慢會轉(zhuǎn)變?yōu)槟愕膬r值或者原則,最終則會成為你的命運,比如成為了一個始終給予完善解決方案的軟件架構(gòu)師。
我的觀點是,始終通過挑戰(zhàn)自己來變的更好,在某些時刻,你可能會遇到問題,但是往往你可能已經(jīng)擁有了答案。
Happy coding!
譯者注對于接口隔離原則的理解,我一直覺的它本身其實是單一職責(zé)原則的一個擴展,但是它們之間也有細微的不同:
單一職責(zé)原則往往面向?qū)崿F(xiàn)層,比如具體的類或者某個方法
接口隔離原則往往面向抽象層,比如一些抽象類或者抽象方法
所以將兩個原則結(jié)合起來看的話,可以很容器得到當(dāng)時提出這兩個原則的人的意圖,那就是一定要時刻保持簡單。
在實際工作中,我深知保持簡單是一件十分困難的事情,因為工程師本身的使命便是解決問題,而問題往往充滿了未知性,而未知性往往代表著改變,這還沒有考慮到在項目實施過程中,產(chǎn)品經(jīng)理天馬行空的設(shè)計思路,客戶們五花八門的需求等等。在這些外界條件下,我們的代碼往往會變得復(fù)雜無比,充滿了各種反模式和冗余代碼,最終會使自己陷入無盡的bug修復(fù)和維護工作中,怎么還會有時間進行自我提升呢?
所以,為了能夠按時下班,為了能夠及早回家,為了能夠讓我們的擁有更多的時間來提升自己和陪伴家人,在軟件設(shè)計之初,盡可能地針對將來所面臨的改變,在設(shè)計層面降低軟件抽象模塊間的耦合程度,在項目實施時,提高每個具體實現(xiàn)模塊內(nèi)部的內(nèi)聚程度,同時使它們保持簡單,這樣便是一個好的開始。
關(guān)注公眾號 全棧101,只談技術(shù),不談人生
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/107333.html
摘要:什么是里氏替換原則某個對象實例的子類實例應(yīng)當(dāng)可以在不影響程序正確性的基礎(chǔ)上替換它們。除了在編程語言層面,在前端實際工作中,你可能會聽到一個叫作的概念,這個概念我認為也是里氏替換原則的一直延伸。 這是理解SOLID原則,關(guān)于里氏替換原則為什么提倡我們面向抽象層編程而不是具體實現(xiàn)層,以及為什么這樣可以使代碼更具維護性和復(fù)用性。 什么是里氏替換原則 Objects should be rep...
這是理解SOLID原則中,關(guān)于依賴倒置原則如何幫助我們編寫低耦合和可測試代碼的第一篇文章。 寫在前頭 當(dāng)我們在讀書,或者在和一些別的開發(fā)者聊天的時候,可能會談及或者聽到術(shù)語SOILD。在這些討論中,一些人會提及它的重要性,以及一個理想中的系統(tǒng),應(yīng)當(dāng)包含它所包含的5條原則的特性。 我們在每次的工作中,你可能沒有那么多時間思考關(guān)于架構(gòu)這個比較大的概念,或者在有限的時間內(nèi)或督促下,你也沒有辦法實踐一些好...
摘要:事件驅(qū)動模型對于一些復(fù)雜的事件驅(qū)動模型,比如拖拽,往往使用開閉原則會達到意想不到的效果。 這是理解SOLID原則,介紹什么是開閉原則以及它為什么能夠在對已有的軟件系統(tǒng)或者模塊提供新功能時,避免不必要的更改(重復(fù)勞動)。 開閉原則是什么 Software entities (classes, modules, functions, etc.) should be open for ext...
摘要:設(shè)計原則梳理,參考核心技術(shù)與最佳實踐敏捷開發(fā)原則模式與實踐,文章面向?qū)ο笤O(shè)計的五大原則設(shè)計模式原則單一職責(zé)原則定義特性僅有一個引起類變化的原因一個類只承擔(dān)一項職責(zé)職責(zé)變化的原因避免相同的職責(zé)分散到不同的類,功能重復(fù)問題一個類承擔(dān)的職責(zé)過多, PHP設(shè)計原則梳理,參考《PHP核心技術(shù)與最佳實踐》、《敏捷開發(fā)原則、模式與實踐》,文章PHP面向?qū)ο笤O(shè)計的五大原則、設(shè)計模式原則SOLID 單一...
閱讀 2961·2021-11-24 09:39
閱讀 2871·2021-09-29 09:34
閱讀 3567·2021-09-24 10:23
閱讀 1747·2021-09-22 15:41
閱讀 1703·2019-08-30 15:55
閱讀 3518·2019-08-30 13:58
閱讀 2626·2019-08-30 13:11
閱讀 1673·2019-08-29 12:31