簡單聊聊軟體設計的 SRP (Single Responsibility Principle) 原則

** 本文同步發表於 FB 社團-軟體設計鮮思維 **

SRP, Single Responsibility Principle (單一責任原則)

這是上星期課堂中,當我解釋 Multi-tier MVC 分層結構時,聽到學員告訴我的。

哈,這是我第二次遇到學員有告訴我這個術語,看來都蠻熟悉 Martin 在 "Agile Software Development, Principles, Patterns, and Practices" 一書內所提到的幾個軟體設計原則。

不過當我問他們工作上是否至少有把 UI 與 Logic/Data Acess 層分離? 沒有!還是全都攪在一起,沒有人講究上述分層的 "基本責任分派"。

沒有「知行合一」,確實實踐並從實務中體會與調整作法,那麼,學會 "背" 這些術語是沒啥用處的!

其實也只有一個字需要真正了解:責任 (responsibility)。

o Web UI (view & ui controller) / Standalone UI:Presentation (只負責傳送與回傳已運算資訊)。

o Domain Controller:負責控制流程 (control flow)。

o DAO (data access object)/ Adapter:負責連結資料庫/外部系統。

o Entity (或稱 business) Object:負責處理邏輯運算。

確實理解 "responsibility" 這個術語可不是用背的,而是身體力行,從過程當中去體會該術語的「真諦」。

從原點出發,一個詞彙可通一堆觀念。如當確實做好單一類別的責任分派時,所得到的效果就是「高內聚力 (high cohesion)」—責任明確。

開源免費下載-完整設計模式 (design patterns) 程式碼(C#.NET)/UML Model 檔

關於爾後我們 HSDc. 軟體設計顧問所開設的課程,除了教材內容尚無開放以外,其它包括完整可執行的程式碼、UML Model 檔,均以開源方式 (open source)免費供下載。

所有開源文件的釋出 (release),均可以透過加入 FB社團-軟體設計鮮思維 獲取最新的訊息。而所有的程式碼/UML Model,我們則是一律統一放置於 GitHub,當然在 README 文件上我們會附上基本的操作說明。

以後這些開源文件,尤其是案例程式碼,我們均會不定期持續版本更新。讀者可以透過 Git 工具隨時作同步更新。

目前提供了兩份開源文件:

另外補充關於上述設計模式 (Design Patterns)案例的說明。

在 C#.NET 程式碼部分 (Java/Spring 版本後續會另行公布),包含了完整 23 個設計模式範例;而關於 UML Model,則還增加了以周遭生活案例的塑模 (modeling),讓每一個設計模式的目的更容易理解。

關於 C#.NET 程式碼的結構部分,主要分為兩個專案 (project):一為 Web MVC by ASP.NET;另一為 Control by POCO (plain-old CLR objects)。

關於本案例的設計模式物件分層結構,可以參考下圖:

圖、圖、設計模式的物件分層結構

圖、設計模式的物件分層結構

閱讀全文 »

Design for Interface 的生活案例-沖煮咖啡的介面設計

** 本文同步發表於 FB 社團-軟體設計鮮思維 **

GoF Design Pattern 一書開宗明義即提及:Design for Interface!

軟體的介面設計很重要的一個精神就是:不要重新造輪子!!
如果引用某些 3rd party library/framework 的功能,要懂得利用介面與主系統隔閡掉,如此才能造成 PnP (Plug & Play)的效果。

舉個生活的範例。88度C 的主要服務是銷售糕點與咖啡,其中咖啡服務 (需求分析)需要系統有個結構元素-咖啡機 (結構設計)來實現。

咖啡機的目的是沖煮咖啡 (Interface 規格),而購置某品牌的考量可能有:1.成本低 2.穩定/快速 3.好喝

如果購買的 A牌咖啡可能故障或沒達成上述需求,那麼就直接抽換掉,可能送修或改購置另一品牌的咖啡機即可 (但前提是不應影響到主系統的服務)。

咖啡機故障/效能不佳等因素,88度C 這個系統的設計/開發人員不可能也沒必要把咖啡機打開去維修或更改電路/零件吧?

現實生活上應用這類介面規範的案例非常多,主機板透過 PCI Express (介面)可插入各品牌顯示卡即是一例。(主機板設計人員不用考量顯卡的實作)

但回歸軟體資訊系統,不懂得介面設計,直接侵入 (hack)到 3rd party library/framework,想要把輪子改得更好甚或重新造輪子。這樣不僅耗工做沒啥意義的事情,且造成主系統與這些 3rd party 的嚴重耦合 (coupling),導致不容易/無法抽換,因而造成主系統的主要服務更為僵化難以應變的後果!

圖、範例-從Twitter畫面操作找出 Use Cases

圖、範例-沖煮咖啡的介面設計

[系統分析] 從 GUI 畫面分析使用者的操作目的 (Use Cases) – 以 Twitter 為例

這是上一期「系統分析設計與實作」課程的一位美女學員-Isis 的案例作品。她對 Use Case (使用案例)用於系統需求分析情有獨鍾,而且相當積極的學習與詢問問題。

不過可能待在業界許久,一開始對 Use Case 這類講究目標導向的分析方法並不容易理解,總是不自覺就鑽入到細節,或是聯想到實作面議題。所以就不容易抓到 Use Case 的分析主軸-界定參與者 (actor)使用系統的操作目的,以及實現該目的的操作程序。

我使用了幾種方法,包括如何從企業流程的分析找出使用案例,或要求綜覽閱讀 Use Case 的經典名著「Writting Effective Use Case」(再針對她提問的問題回應),甚至乾脆從某一個實際的專業問題領域 (problem domain)著手,但效果仍不彰。

畢竟大部分軟體人員少對所謂的「抽象 (abstraction)」技能下功夫。抽象是需要經由思考、閱讀、觀察等長期日積月累才得以鍛鍊而成的。

所以換一種較具象的方法,從現實各網站的使用者操作畫面中,完成下列的系統分析工作:

  • 界定系統範圍 (system boundary),並給予系統命名。
  • 規劃功能模組 (functional module),這是邏輯性的功能分類。
  • 從每一張畫面表單,透過所提供的資訊,以及要求使用者輸入的資料欄位中,藉以分析其背後的操作目的,也就是使用案例。

我先給她系統規模較小的 Twitter 案例,要她完成上述三項重點工作,而先不用撰寫使用案例陳述 (use case description)。雖然使用案例陳述才是實現系統功能的主要程序,但可以先等系統功能的界定有了初步釐清與共識後再來描述相對的實現步驟,這對使用 Use Case 分析的 SA 而言,比較能有循序的分析節奏,才不致亂了套。

耶!!這方法還真對 IS 的性向,不到兩天就完成了我看了也覺得很有創意的分析。經由她的首肯,我就把她的案例作品分享上來。

圖、範例-從Twitter畫面操作找出 Use Cases

圖、範例-從Twitter畫面操作找出 Use Cases

閱讀全文 »

關於 PTT Soft_Job 對於 OOP 的一些回應

沒想到 PTT 的 Soft_Job 看版有人在聊 OOP 的觀念,忍不住作了一些回應。

  1. 早期把物件化的分析/設計思維歸為 OOA/OOD (Object-Oriented Analysis/Design);實現物件化思維的程式語言則稱之為 OOP (OO Programming)。
  2. 實現 OO 思維主要有兩個機制:介面 (interface)、多型 (polymorphism)。包括 .NET/Java 等主流語言,早已支持 OOP,甚至連 php/python 等原來屬於 script-based 的程式語言,也朝向 OO 化的實現機制。
  3. 從 OOP 的角度來看到物件化的設計思維是不妥的;原因在於絕大數開發人員並不知道 Why OO Thinking!其實採用 OO 設計化思維是必然會增加開發成本的。因為它並非為了解決某一局部的邏輯性問題,而是考量全局,從系統整體來看待「變動 (Change)」的議題,進而提出如何擁抱改變 (embrace changing)的解決方案。
  4. 再則從實作上,OO 化的特徵是分散式的 (因為基於類別 (class)的責任分派 (responsibility assign)原則)。所以為了實現 OOP 的分散式架構,程式碼必然大量分散於各類別內,如此會造成實作與偵錯的難度;因而一個必要的配套措施:TDD (Test Driven Development),測試先行是一定要養成的好習慣。
  5. 越是大型變動頻繁、高度維護,或者期待包裝為產品,增加其再利用性價值的系統,採以 OO 的設計/實現 (當然,前提要有這樣實在技能的軟體架構師/Developer)才能感受到其好處:每一次只改變一點點;每一次的變動可以侷限在可控制的變動範圍內。
  6. OO 的特徵是將 程序/資料 封裝至某一類別內,其實在抽象層次,程序稱之為「行為 (behavior)」、資料稱之為「屬性 (attribute)」,兩者均為物件必然會有的特徵 (features),是非常自然不致分離的。但因現實仍沒有一種有效的機制能把物件的狀態 (state)儲存起來,所以實作技術上是把物件與資料分離,資料儲存於資料庫系統內、待執行期間 (run-time)才透過如 OR Mapping (如 .NET ER Framework、Java Hibernate 等),將物件與資料合而為一。
  7. 實業界很有趣的一個現象:重視 MIS (Management Infomation System)系統的公司,幾採以資料導向的開發模式;重視 Web 框架如網路行銷公司,大都採以程序導向的開發模式。至於所謂的 OO 化,實現的程度其實還蠻微小的。
  8. 順待提下重構 (refactor)的觀念:重構是屬於事後 (Coding 後)的設計,一般與事前 (Coding 前,如典型的 SA/SD)設計可能存在著 3:7 或 4:6 (事前:事後)的比重。而且往往寫完程式才是另一段故事的開始:持續重構 (continous refactoring)。
  9. 重構的要件:不會影響到已經上線系統的所有功能。 衡量重構的指標:每一個 method 不會超過 10 行、最長不得超過 20 行。
  10. 如今重視 Web 相關技術、快速實現商業創意的年代,其實已少人有人談及 OO 更遑論具體實踐了。西元2000年以前,包括 UML 三大師 (Booch、Rumbaugh、Jacobson)、Martin Fowler (重構一書即為他的著作)、Kent Beck (XP/Agile 的始祖)、Bob (Clean Code 作者)均為支持物件思維的軟體大家。國外除了這些大師外,實現 OO 的專家其實也不多,一般是會落在如開發底層框架 (如 .NET Framework)的關鍵架構師。
  11. 閱讀全文 »

ASP.NET MVC 框架學習心得註記

這幾天利用撰寫一個 Web.NET 小專案的機會,打算使用 ASP.NET MVC 5,藉此順便學習下 Web MVC 的框架技術。

花了快兩天的時間研讀一些文章,總算對 ASP.NET MVC 框架有了全貌的認識;先註記下基本的心得:

  • ASP.NET 源自於 Java Struts MVC,本質完全沒變。
  • ASP.NET MVC 僅是位於系統 3層(3-tier)架構的 Presentation 層,完全沒有涵蓋系統的控制 (Control)與邏輯 (Logic, or Model)層。
    {P.S. 關於這個觀念,個人已在課堂上論述許久;後續再撰寫該篇專文討論。}
  • ASP.NET 的 MVC 中的 Model,係指 Data Model,也就是屬於資料傳遞類型的物件 (DTO, Data Transfer Object),並未涉及到邏輯運算。
  • 微軟的企圖心,利用 EF (Entity Framework) O-R (Object-Relation) Mapping 技術,實現 Model (Data Model)與資料庫的無縫式對應,讓開發人員對於撈取資料庫的程序更是簡化不少。
  • ASP.NET Model 透過 EF 直接對應資料庫,本質上就是 Client/Server 架構;好像重回到 10 年來前 Windows Form 的 4GL,雖然實作變得更簡單 (不需自行控制 Web 表單的狀態與資料庫連結問題),但會導致系統本質上的混亂-沒有確實隔離問題領域 (problem domain) 的功能控制 (functional control)與業務邏輯 (business logic)層。
  • ASP.NET MVC 的頁面 (Page)係以所謂的 Razor 語法 (把它想成 PHP 就好了),以 "@" 為語法的頭尾標記,來實現 UI 邏輯控制的部位。
  • 至於 Web Page 的呈現,則係利用最為普遍的開源專案-Bootstrap,綜合了 HTML/CSS/Javascript 框架技術,來呈現 Web Page 的動態呈現與彈性 Layout 控制 (有些意外,微軟竟然也採用了開源專案)。
軟體思維顧問

專職軟體輔導與教育訓練的獨立顧問。輔導企業資訊單位如何有效組織系統開發與維護;輔導開發人員達成有效的專業分工。傳授如何把軟體作軟 (Keeping Software Soft)的技能,得以提昇系統的彈性/延展,並進而創造系統的再利用價值。

Personal