1. 程式人生 > >漫談開發設計中的一些“原則”及“設計哲學”

漫談開發設計中的一些“原則”及“設計哲學”

在開發設計中有一些常用原則或者潛規則,根據筆者的經驗,這裡稍微總結一下最最常用的,以饗讀者。

DRY

這裡的DRY是Do Not Repeat Yourself的縮寫。具體解釋參見 ,嚴謹的定義是 Every piece of knowledge must have a single, unambiguous, authoritative representation within a system,意思是:任何一部分知識在系統中必須只有單一的,清晰並且權威的展示。???這是啥意思,沒懂。簡單說就是不要重複自己任何一部分的工作。比如說,有一段程式碼是用於清除字條串中的HTML符號,在多個程式中會用到此功能,如果每個地方都使用如下程式碼

html = html.replaceAll("\\\\<.*?>","") 
html = html.replaceAll(" ","");
html = html.replaceAll("&"."");

如果是隻有2,3個地方用到(Martin曾經提到過Rule of three,意思是一段程式碼如果被copy3次以上就應該重構到一個單獨的子方法中),你可能就直接複製過來用,但是想想是2,3百個地方用到呢?如果上面需要再做個修改(如下),你是不是要去這個2,3百個地方去改程式碼。

html = html.replaceAll("<"."<");
html = html.replaceAll(">".">");

所以這個DRY的規則就是推薦使用 子方法 的方式,這樣只需要修改一次即可. 與之類似的程式設計思想有 DIE(Duplication is Evil),SPoT(Single Point of Truth), SSOT (Singel Source of Truth) 。 題外話,和DRY對應的是WET,意思是 "write everything twice"(任何東西都寫兩遍)或者"we enjoy typing" (我們就是喜歡打字編碼)。 :-)

KISS

KISS 是 Keep it simple, stupid (或者Keep it short and simple )的簡稱。意思是在設計時保持簡約,通俗。這個很像是現在推暢的“極簡風”。

使用KISS有什麼好處呢?如下是其中的一些:

  • 你可以更快的解決更多的問題

  • 你可以使用更少的程式碼來解決複雜的問題

  • 你可以寫出更高質量的程式碼

  • 你可以建立更大的系統,更好的去運維

  • 你的程式碼將更加靈活,當有新需求時可以更好的支援擴充套件,修改或者重構

  • 等等

在軟體設計領域, 有一些技術具體實現這個精髓,比如 DDD (Domain Driven Design),TDD (Test Driven Develop),這個使程式碼集中在真正需要的功能上,而不需要其他額外的。另外一個建議是 不要試圖通過註釋來提高程式碼的可讀性,而應該從程式碼本身提高。比如如下是不太好的變數定義

// i is for 'counter' and j means total sum
int i, j;

而如下是好的設計

// more intuitive one
int counter,sum;

與此相呼應的是稱作 奧卡姆剃刀 或者 簡約之法則

Occam's razor  The simplest (explanation|solution) is usually the best one. 往往最簡單的解決方案是最好的解決方案

具體到以Java為例的程式設計,如下有一些實踐KISS的建議

  • 首先,認清自己,不要認為自己是個天才,這往往是你犯的第一個錯。

  • 把你的工作打散成幾個子工作,每個部分不會耗費超過4-12個小時去完成

  • 把一個問題分成幾個小的子問題,每個問題可以通過1個或者只要幾個類就能解決。

  • 保持每個方法只做一件事,並且不要超過30-40行的程式碼量

  • 保持每個類的體積不要太大。

  • 不要害怕扔掉不用的程式碼。就像家裡用不到的東西就及時扔掉一樣。

New Jersey style (Worse is better)

新澤西風格,也叫做“Worse is better”。此原則指出,系統的質量不會因為新功能的增多而提高。 比如一個軟體,只提供一些功能,但是使用者很方便使用,有可能比一些提供了非常多令人眼花繚亂功能的“大雜燴”似的軟體。比如像 Linux下面的 vi/vim, 瀏覽器中的Chrome.

SOLID

SOLID是幾個程式設計哲學的總稱,即 SOLID (Single responsibility, Open-closed, Liskov substitution, Interface segregation and Dependency inversion) ,下面我們分別解釋一下:

Single responsibility (SRP)

單一功能原則。Robert描述這個為“A class should have only one reason to change.”,即修改一個類(或者模組)有(且只能有)一個理由。簡單說就是 一個類或者模組只能負責一個功能。舉個例子,有一個模組負責生成一個報表,可以想像可能有兩個理由去修改此模組,第一,報表的內容要變,第二,報表的格式要改。這兩個改動是出於不同的理由,一個是內容的一個美化版面的。 而 “單一職責” 規則認為這是兩個不同的職責,因此應該分成兩個不同的子模組。如果把兩件事情放在一起,並且不同的改動是出於不同的原因,這種設計是不好的。此規則方便系統各模組間解耦合。

Open/closed principle (OCP)

開閉原則。Bertrand描述為“"software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification";”,也就是說對於一個實體(類,模組,方法等)允許在不修改原始碼的前提下擴充套件它的功能行為。即,你可以把 新程式碼放到新的類或者方法中,新類通過繼承來重用已有程式碼及功能。而 已有的程式碼只有在修bug時才去修改。 此原則主要用於降低在新增新加功能時引入新的bug的風險。

The Liskov Substitution Principle (LSP)

里氏替換原則. 原文是 “Derived classes must be substitutable for their base classes.”,意思是,派生類(子類)物件能夠替換其基類(超類)物件被使用。 比如說,如果 S 是T 的子類, 那麼任何T類的具體實現物件都可以替換S的實現物件出現的地方,具體的呼叫者也不知道具體是父類還是子類,還不會出現任何錯誤。比如下圖,呼叫者可以2來替換1的地方 。

Interface segregation principle (ISP)

介面隔離。原文是 many client-specific interfaces are better than one general-purpose interface. 意思是多個特定客戶端介面要好於一個寬泛用途的介面。Make fine grained interfaces that are client specific. 應該定義粒度合適的一系列介面(像下圖),以便於每個客戶去實現具體的功能請求。換句話說是,客戶(client)不應該必須去依賴於它用不到的功能方法。此原則的目的是系統解開耦合,從而容易重構,更改和重新部署。

Dependency inversion principle (DIP)

依賴反轉原則. 原文是 One should “Depend upon Abstractions. Do not depend upon concretions.” 意思是 一個方法應該遵從“依賴於抽象而不是一個例項”。該原則規定:

  1. 高層次的模組不應該依賴於低層次的模組,兩者都應該依賴於抽象介面。

  2. 抽象介面不應該依賴於具體實現。而具體實現則應該依賴於抽象介面。

這個就像是設計模式中的Adaptor介面卡模式。下圖解釋了這個原理。

圖1中,高層物件A依賴於底層物件B的實現;圖2中,把高層物件A對底層物件的需求抽象為一個介面A,底層物件B實現了介面A,這就是依賴反轉。

SOC

Separation of concerns, 即關注點分離。 是處理複雜性的一個原則。由於關注點混雜在一起會導致複雜性大大增加,所以能夠把不同的關注點分離開來,分別處理就是處理複雜性的一個原則,一種方法。這個與SOLID中的 SRP很類似。

YANGI

是"You aren't gonna need it"的縮寫,直譯是“你將來用不到它的”。這個是極限程式設計的一個程式設計思想。意思是說,永遠不要因為 預計你會用到某個功能就去寫一段程式碼去實現,總是隻有問題出現了,真的需要這個功能時才去寫

參考

如有問題可以通過郵件[email protected]/微信helloworld_2000聯絡我。謝謝。 原文位於: http://cloudsdocker.github.io...