當前位置:學問谷 >

行業範例 >工程 >

軟件技術方案設計原則

軟件技術方案設計原則

軟件開發是一項高強度的腦力勞動過程,到目前為止尚沒有辦法使軟件開發完全機械化,只能靠人腦去設計,也無法保證一個軟件完全沒有錯誤。同硬件產品相比,一方面是同功能的軟件產品不再需要一個生產過程,只需要拷貝就行了,而硬件產品卻需要重複生產;另一方面,軟件產品功能需求的變化遠比硬件產品多。這就造成軟件產品和硬件產品在成型之後面臨的問題是不同的,軟件產品主要是應付用户功能需求的變化和擴展,硬件產品主要着眼於如何大規模地生產。硬件產品的大規模生產可以交給機器去執行,而軟件產品的需求變化還是要靠人腦去完成。以下是軟件技術方案設計原則,歡迎閲讀。

軟件技術方案設計原則

如何快速開發出符合用户功能需求的軟件,如何保證開發出的軟件儘可能少地出現錯誤,如何使開發出的軟件能夠容易地適應用户功能需求的變化和擴展,是所有軟件開發人員追求的目標;我想,也正是為了實現上述目標,才有了軟件設計原則和設計模式

軟件開發是起始於面向過程的,為什麼會這樣呢?我想是因為面向過程地解決問題更直接,軟件本身就是一個解決問題的過程;面向過程的最大問題就是不容易把問題進行分解,再大的問題都要在一個過程裏面解決,從第一步直到最後一步;最多是把一個大過程分解成幾個順序執行的小過程,很考驗人的邏輯推理能力,開發出的軟件不容易維護、重用和擴展。面象對象的方法沒那麼直接,需要有一個抽象的過程,要把問題抽象成一個個對象,每個對象解決一個小問題,不同對象的組合就可解決不同的大問題;而且把對象跟日常的事物聯繫起來,產生了屬性、事件、方法這樣的概念,增加了對象的直觀性。

設計原則和設計模式都是針對面向對象的設計方法而提出來的,如果在軟件開發中還完全採用面向過程的方法,是無所謂設計原則和設計模式的。在軟件開發中,面向過程是起步,是基礎,沒什麼好研究的了;面向對象才是深入,是王道,需要不斷地去總結方法;下面的軟件設計都是指面向對象的設計方法。

根據前人總結的經驗,在軟件開發中,遵循一定的設計原則,靈活地採用一些設計模式,可以提高軟件的易維護性、可擴展性以及重用的機率。關於這方面最權威的著作恐怕就是Robert C. Martin寫的敏捷軟件開發一書了;關於這本書,個人閲讀的理解如下:

  一、設計原則,該書提出瞭如下設計原則:

1、單一職責原則(SRP):一個類只實現一個功能;換一種説法,一個類只能有一個引起它變化的原因;在軟件工程中有一個要求,叫做高內聚;一個類只實現一個功能,無凝內聚度是最高的了;這一原則可以使一個類更好地被重用;當然,“一個功能”是相對的,在某種情況下,MODEM功能是一個單一功能,而在另一種情況下,可能就要把MODEM功能再分解成多個小功能;

2、開放封閉原則(OCP):開放是指一個類能夠擴展功能,封閉是指這個類對於功能修改是封閉的,也就是説不能修改其已有的代碼和功能;要實現這一目標,關鍵是抽象;在客户類中只使用抽象基類,在應用中子類繼承基類,並按實際需要擴展基類的功能;按更通俗的.説法就是:接口不能改變,功能可以擴展;

3、子類替換原則(LSP):就是一個子類在任何情況下,都能替換掉它的基類;這是面向對象設計方法中實現繼承和多態必須遵循的一條基本原則,顯然也是開放封閉原則能夠實現的基礎;如何實現這一原則呢?那就是子類必須要有比基類相同或更弱的前置條件,相同或更強的後置條件;前置條件就是調用一個方法之前必須滿足的條件,後置條件就是一個方法執行之滿足的條件;為了更清楚地説明這一個問題,見下面的函數表達式:

Y = F(X);

F是一個函數,X是一個整型的輸入參數,Y是一個整型的返回值,如果F要求X>0,返回值Y>1,則X>0和Y>1就分別是F的前置條件和後置條件;如果F是基類A中的一個函數,B是A的一個子類,並擴展了F的功能,則B類中F的前置條件必須跟A類中的相同或更弱,也就B類中的F必須至少能接受X>0,如果能同時接收X<=0的條件更好,但不能要求X>1,這是一個X>0更強的條件;B類中的F必須保證返回值Y>1,當然如果能保證Y>10更好,但不能使返回值Y<=1,這樣就不滿足A類中F返回值Y>1的條件;不滿足子類替換原則最直接的後果就是使應用程序產生BUG;必須説明的是,在實際中是很難完全遵循子類替換原則的,必須作合理的假設,在這個假設的前提下遵循子類替換原則,這就是所謂契約設計;

4、依賴倒置原則(DIP):就是上層模塊不能依賴於下層模塊,兩者都應該依賴抽象;抽象不能依賴細節,細節應該依賴於抽象;對這一原則要靈活看待,因為這一原則和當前開發中常用組件開發方式看起來是相矛盾的;首先明確定義一下上層模塊和下層模塊,所謂上層模塊是調用別人的模塊,也可稱之為客户模塊,下層模塊是被別人調用的模塊,也可稱之為服務模塊;顯然這是一個相對的概念,因為一個模塊很可能同時即調用別的模塊,又被另外的模塊調用;依賴倒置原則告訴我們客户模塊和服務模塊不能互相依賴,而只能依賴於一個抽象的基類;另外這個抽象基類的接口是由客户模塊決定,而不是由服務模塊決定;也就是説客户模塊需要什麼,服務模塊就提供什麼,而不是服務模塊提供什麼,客户模塊就使用什麼;這頗有點當前企業信奉的一個原則:客户就是上帝,客户需要什麼,我們就提供什麼;而我們當前常用的組件編程中,每一個組件都是一個被別人調用的具體類,顯然是屬於細節和服務模塊,我們調用組件,實際上就依賴了這些組件的模塊;根據依賴倒置原則是不是就不能調用這些組件呢?當然不能這麼呆板,在設計中還有另一條原則,穩定依賴是沒有害處的;説到底,這些組件也是根據客户需求制定出來的,只不過是已經固化了的需求;而且這些組件經過了嚴密測試,是穩定的,依賴它們沒有害處;依賴倒置原則是針對我們自己的設計來説的;當然,如果我們自己設計的某一個服務類經過了嚴格的測試和大量的使用,都已經驗證沒有問題,也可以作為一個通用的組件,別人可以調用它,依賴它,沒有問題;

5、接口隔離原則(ISP):這一原則好象是單一職責原則的升級版,接口隔離原則強調的是當一個服務類需要被即有共同功能需求又有不同功能需求的客户類使用時,不能在服務類中加進它的客户不需要的方法,比如在服務類A的客户中, B類客户需要F方法,而C類客户則不需要F方法,這時不能簡單地把F方法加到服務類A中以滿足B類客户的需求,而應分離接口;比如另設計一個服務類D,其中包含F方法,並把共用的功能委託給A實現,這樣B客户可以使用D,而C客户繼續使用A;對這一原則我有所保留的是:如果F方法對C類沒有影響,直接加到A類中也無防,而且這種情況是很普遍;

6、共同封閉原則:這是針對包的;一個包對應用一個程序文件,包含一到多個類,這些類具有共同的封閉性,要麼是都不能修改,要麼是隻能由同一原因引起修改;

7、共同重用原則:也是針對包的;不同類的通用性也是不一樣的,通用性最高的就是在所有項目中都可使用,比如我們用到的集成開發工具中的組件;有些類可能包含些行業特徵,只能這一行業類的軟件中使用,有些類包含了某一個項目的特徵,就可能在該項目中使用;但是一個包中的所有類的通用性都應該是一樣的,這樣才能保證包的重用度最大化;

  二、設計模式,該書列出了以下常用的設計模式;

1、策略模式(STRATEGY):在一個擁有通用算法的具體類中,把一些調用的方法委託給一個接口類實現,通過接口的不同實現,擴展不同的功能;策略模式能夠重用通用具體類,又易於擴展功能;

2、工廠模式(FACTORY):在一個工廠類中,傳入不同的參數,可生成不同的類(相同的接口,不同的實現);工廠模式易於擴展功能;

3、封裝模式(FAADE):對一個具有複雜接口的類(或API函數)進行封裝,並提供幾個簡單的接口供外部調用;封裝模式可以隔離複雜的接口,並使其使用變得簡單;

4、命令模式(COMMAND):上層模塊要操作一組COMMAND對象,這些COMMAND對象都具有同樣的方法(不同的實現),上層模塊在操作COMMAND對象時,只需要調用它們的方法,而不用關心方法的實現;在某些情況下,這種模式會極大地簡化系統;

5、組合模式(COMPOSITE):當A調用B,一對一的關係,需要改變為A調用多個B(或B的子類對象)時,不更改A的代碼(比如在A中創建一個B或B的子類對象的列表,再依次從列表中取出對象調用),而是從B繼續一個子類C,在C類中創建B或B的子類對象的列表,重寫C類中相應的方法為依次調用列表中對象的方法,從而用A和C一對一的關係代替A和B之間一對多的關係,並保持A的代碼不用更改;

6、觀察者模式(OBSERVER):在被觀察者中提供註冊接口(Register)用於註冊觀察者,所有註冊的觀察者都放入一個列表中,在觀察者中提供觀察接口(Update),用於接收被觀察者發出的通知;當被觀察者發生變化時,依次調用列表中的觀察者的觀察接口(Update),觀察者在觀察接口(Update)中,對感興趣的被觀察者變化進行處理;

7、代理模式(PROXY):主要用於代理數據庫操作,可以實現數據庫操作和業務操作的代碼分離;實現模式如下:

應用程序調用一個接口A,B和C都實現A中的所有接口,其中B是知曉數據庫的代現,利用一個數據庫類D進行數據庫操作,然後委託相應的方法給C;代理模式使用不多,主要是在B類中把方法再委託給C,在大多數情況下都沒有必要;

8、適配器模式(ADAPTER):在一個穩定的架構中,增加一個外部組件,但該組件的接口不符合架構的規範,這時就可創建一個適配器類對外部組件進行封裝,適配器的接口符合架構的規範(這樣才能納入架構),相應的方法委託給外部組件實現;這樣就可把外部組件納入到已有的架構中;另外,也可能是需要提供一個具有不同接口的組件給另外的客户端使用,同時又要把該組合件的功能納入到已有的架構中,通過一個適配器把組件納入架構,另外的客户端直接使用組件;

最後説明:使用設計模式是有代價的,可能需要增加新的類,編寫額外的代碼,增加複雜度;優勢就是,可以使系統更適應於功能需求的變化,包括功能修改和擴展,隔離變化等;可以提高代碼的重用率;所以對於設計模式,不能生搬硬套,而應是順勢而為。

  • 文章版權屬於文章作者所有,轉載請註明 https://xuewengu.com/flhy/gongcheng/7w1949.html