Quantcast
Channel: 軟體設計與分析 | Kenmingの鮮思維
Viewing all 31 articles
Browse latest View live

「軟體需求分析與塑模」- 區分功能性需求與非功能性的需求

$
0
0

本文收錄於 我的電子書「軟體需求分析與塑模 – 第一章、需求分析概觀」。

所謂的功能性需求 (functional requirements) 即是使用者需要系統能為他做什麼。這往往是顯而易見的,因為,使用者可以清楚的看到系統為他服務並會有回應。例如在一個訂購系統中,功能性需求有:

  • 系統接受顧客的訂購 (系統功能-place order),並且會通知倉管該產品庫存量是否充足。
  • 系統會對前一日的訂購在當夜會產生統計報表 (系統功能-process order summary report)。

系統的功能性需求源自於開發或維護中系統的問題領域 (problem domain)。例如「電子商務系統」,功能性需求有「處理訂購」、「追蹤訂購」…等。

功能性需求需直接滿足於使用系統的操作人員或相關利益關係人 (stake holder),它是屬於系統的「顯性價值」,是與企業的需求有直接的關聯。

功能性需求的分析技術即為本書內容的重點。各類軟體開發方法論均有提供如何分析系統功能的技術。例如 Agile (敏捷式) 的「user story」、SCRUM 的「backlog」,以及行之有年的「use case (使用案例)」。本書的系統功能分析主以「使用案例」的分析技術來捕捉系統功能性需求。它既能包容其它需求分析的技術,又能很順暢橋接到結構設計與程式寫碼實作,這在後續的章節即會詳述,並會以案例研討的方式舉例說明。

非功能性的需求 (non-functional requirements) 往往是使用者所感受不到系統有直接提供服務並有回應。非功能性的需求是總體 (global) 的、模糊 (fuzzy) 的一些因素而導致系統整體的良好運作。例如:

  • 系統要能處理超過1千人以上線上訂購書籍的效能 (performance issue)。
  • 系統為了要能應付日增的交易處理,所以必須要能具備延展性 (scalability issue)。
  • 系統的登入 (logon) 須具有密碼加密的機制 (security issue)。

系統的非功能性需求源自於開發或維護中系統的解題領域 (solution domain)。例如「電子商務系統」採以「JEE (Java Enterprise Edition) + Spring Framework」的實作解題技術框架。

非功能性需求是屬於系統的「隱性價值」。它不容易被直接感受到,只有當碰到系統整體性的震盪 (如多人操作存取時的效能與穩定問題、帳戶安全性問題)時,系統的品質問題與危機意識等才會浮現出檯面。

一般非功能性需求較被列為實作面的考量,例如下列幾個實作議題:

  • 多人上線時的交易效能與穩定性。
  • 安全性的考量。
  • 分散式溝通議題。
  • 延展性議題。
  • 異地備援/災難重建議題。

非功能性需求並非採以上述所提及的系統功能分析 (如 use case) 技術,一般它可能僅以清單列表的方式註記並列為系統的一種約束 (constraint) 即可。


「軟體需求分析與塑模」- 企業層級系統塑模的範疇

$
0
0

本文收錄於 我的電子書「軟體需求分析與塑模 – 第二章、企業流程的分析與塑模」。

把企業/組織當成系統作需求分析,其系統功能的實現 (realization),由於涵蓋作業的時間長,且會有多類角色的參與者 (participant) 參與期間,以組成一連串的協力活動 (activities)。

而關於企業多人使用的資訊系統,如 MIS (Management Information System)、ERP (Enterprise Resource Planning)、電子商務 (e-commerce)、電子服務平台 (e-service platform) …等,也常需先分析與描述為達成企業某一特定目的 (specific goal) 需求時,原來傳統人工作業的活動,這往往是未來為分析資訊系統功能的前置引導作業。

所以對於「活動」流程的表達,必然是對於企業本身、企業層級的資訊系統等的系統需求分析,是一種必要的開發儀式。

前一章節已提及,單一特定目的作業流程適於採用 UML 活動圖 (activity diagram) 記錄;而表現多個作業流程之間的關聯性,則適於採以「erikson-penker」uml 流程擴充圖來表達。本章節針對這兩種設計圖,就語法與操作應用上作詳細的說明。

另外特別強調的,需求分析師在描述作業流程,盡量不要加入「資訊系統」的參與, 原因有二 [註1]:

  1. 不容易界定資訊系統的開發/維護範圍。
  2. 不容易瞭解會有幾個資訊系統的參與。

[註1] 資訊系統範圍的界定與系統的切分,係由擔任系統整體架構規劃的架構師 (architect) 所負責。需求分析師在初期並不容易瞭解資訊系統的責任,所以最好不要在作業流程的表達加入資訊系統的角色,以免容易造成混淆。

所以作業流程,適合描述的是傳統的人工作業,也就是所有的參與者必定是「人」或「組織」所擔任的角色 (role)。

至於資訊系統的系統功能 (system functions) 分析,會採以較適合的塑模技術,例如使用案例模型,這在後續章節即會詳述。

企業流程與資訊系統功能的分析與描述,這裡採以「MSS」三層次的塑模分析方法,如此可以有效表達在人工與資訊系統的「活動-系統功能」間的關係,並得以讓設計圖表現得簡潔,自然能形成一種層次分明、井然有序的設計框架。

  • M-Multiple Process (跨多個作業流程)。
  • S-Single Process (單一作業流程)。
  • S-System Function (資訊系統功能)。

「軟體需求分析與塑模」- 跨多個作業流程的塑模

$
0
0

本文收錄於 我的電子書「軟體需求分析與塑模 – 第二章、企業流程的分析與塑模」。

每一個作業流程,有各自不同特定的企業目的 (specific business goal)。例如:

  • 訂貨流程的特的目的為讓交易有效率且安全可靠。
  • 出貨流程的特的目的為及早可將貨品交付到客戶手中。
  • 採購流程的特的目的為從供應商取得低成本、高品質的商品。

企業經營者/高階管理者、系統相關的利益關係人 (stakeholder)、乃至於系統開發團隊,希能透過這些作業流程看到較巨觀 (macro view)、更具整體的全貌 (Whole View),如此可得以有效地作整體性的架構規劃與設計。

跨多個作業流程,就是流程範圍更為廣泛,參與的人更多,所涵蓋的時間更長。而且往往因為現實上基於功能執掌,還是不同部門或不同地點就有不同的作業規範與範疇,但彼此這些作業之間仍需要連串在一起。

由Erickson以及Penker所提出的一個活動圖的擴充型態(stereotype),稱之為「Erikson-Penker 企業擴充模型」(Erikson-Penker Business Extension)。(《Business Modeling with UML: Business Patterns at Work》, Manus Penker & Hans-Erik Erikson, 2000, p.57),該設計圖形最適切用來描述跨多個作業流程之間的關聯與各自的企業目的。

這個圖形中,主要是將與作業流程相關的重要人、事、物以及這個流程所要達成的目標做一個連結;不過有關企業流程的內部細節,通常在這張圖中不會有過多的介紹,以免失焦 (內部的活動細節會由 uml 活動圖表達)。

Erikson-Penker企業擴充模型簡介

下圖即對 Erikson-Penker (底下簡稱火箭圖) 的企業擴充模型的重要元素作說明。

圖、Erikson-Penker 企業擴充模型的主要圖形元素

 

  • 處理(Process)

    在這張擴充模型中,「處理」代表一連串有意義的工作流程(Workflow),在一個處理中,通常要達成一個或多個的「目標」,以指出該「處理」在企業上的意義為何。

    「處理」是該擴充模型的核心,在處理中,會有「輸入」、「輸出」以及「參與」。通常一個「處理」會搭配一張明細的「活動圖」以描述該工作流程的細節。

    「處理」的圖示是一個「
    圖、Erikson-Penker 處理圖示
    」的圖形。
  • 目標 (Goal)

    「目標」是 Erikson-Penker 企業擴充模型與一般傳統的「輸入-處理-產出」(Input-Process-Output; IPO) 模型最大的差異處。在每一個「處理」中,最好能夠明確表達出該「處理」所「達成」(achieve) 的「企業價值」為何?而這個「企業價值」,可以用一個「目標」來代表。

    「目標」的圖示是標準UML物件圖示的一個「擴充型別」(stereotype):「
    圖、Erikson-Penker 目標圖示
    」。
  • 達成 (Achieve)關係

    「達成」關係主要是連接「處理」與「目標」間的關係。

    「達成」關係的圖示也是「相依」圖示的擴充型別:「
    圖、Erikson-Penker 達成圖示
    」。
  • 事件 (Event)

    「事件」指的是對企業而言,在特殊的時間點,會引發一連串企業內部反應的外部行為(happening)。通常來說,對於「處理」而言,「事件」是最常被當作是「處理」的重要「輸入」(input)的來源。

    事件的圖示是「
    圖、Erikson-Penker 事件圖示
    」。
  • 資訊(Information)

    「資訊」指的是對企業而言,有意義的一群資料的集合。「資訊」可以是「處理」的「輸入 (input)」、處理的中介「參與 (supply)」,甚或是「處理」的「產出 (output)」。

    「資訊」的圖示為一個平行四邊形「
    圖、Erikson-Penker 資訊圖示
    」。
  • 物件 (Object)

    「物件」指的是在企業中確實存在的實體物品,有可能是一張特定的實體表單,也有可能是一個特定的產品。相同地,「物件」也可以是處理的輸入、參與或是產出。

    「物件」的圖示是標準的UML表示法:「
    圖、Erikson-Penker 物件圖示
    」。
  • 參與者 (Worker)

    「參與者」指的是企業中的特定的「角色」或「組織部門」。對於「處理」來說,「參與者」只會是中介參與。

    「參與者」的圖示為「
    圖、Erikson-Penker 參與者圖示
    」。
  • 相依(Dependency)關係

    「事件」、「參與者」、「輸入物件」以及「輸入資訊」與「處理」之間的關係都是屬於「相依」關係,這代表著「處理」與這些重要元素間具備「參考」關係。

    「相依」的圖示是標準的UML圖示:「
    圖、Erikson-Penker 相依圖示
    」。
  • 供應 (Supply)關係

    「處理」過程中,若有需要的「資訊」或是「物件」時,則兩者之間的關係是屬於「供應」關係。

    「供應」關係的圖示是UML「相依」圖示的一個擴充型別:「
    圖、Erikson-Penker 供應圖示
    」。

 

案例-進銷存系統的進貨/退貨作業流程

下圖為某商場的進銷存資訊系統關於「進貨-退貨」作業流程圖。可以看出該火箭圖表達了兩個主要的作業流程:

  • 「進貨流程」:係由供應商提供進貨商品的事件而啟動該作業流程。
  • 「退貨流程」:係經由客服部門提供退貨商品的事件而啟動該作業流程。
圖例、進銷存系統進/退貨作業流程

 
進貨/退貨會區分為兩個作業流程的主要原因即為:各有著不同的「達成目標」。

  • 進貨流程的主要達成目標在於:增進進貨效率與品質。
  • 出貨流程的主要達成目標在於:保障客戶權益與提昇商品退貨處理效率。

諸多軟體分析人員,常常忽略了這種「目標導向」的分析方式,因而在流程分割時,往往缺乏了一個依循的標的,而往往落入細節而忘卻了整體規劃的核心。

除此之外,對於跨多個作業流程的表達 (使用火箭圖),其最大的特色就在於其描述了企業中重要的人、事、物與流程的關係。在這個階段,並不會牽涉到流程的細節。

事實上,若是到分析流程細節時,因為重點反而要擺在「流程」本身,因此除了參與流程的角色外,其他包括事件以及實體的物件 (包括表單、資料等) 都不會呈現在流程圖中,這也可以讓流程的分析設計人員可以分不同的層次來進行分析。

軟體技術人員最愛卻也是尾大不掉的萬用 Database Manager 物件

$
0
0

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

上星期我在教授 TDD.NET 測試驅動開發課程。其中有位學員分享他們公司會計系統的部分程式碼 (沒有機密性議題),想知道這該如何撰寫單元測試 (Unit Test Code)。

我先用 EA (Enterprise Architect) UML 工具掃描程式碼反轉為 類別 (Class) 圖,老天!數百個 Windows Form (每一個 Form 他們稱為 Report) 全連接到一顆共用的 DB Manager,封裝了基本的 CRUD 行為,再存取資料庫。剛掃進來時還真嚇了一跳跳,那個 Form 的連線,有如積體電路般密密麻麻的共同連接到如同就是 CPU 地位的 DB Manager!

2tier universal db manager

這肯定就是典型技術人員的傑作,用許多稀奇古怪的實作方式,讓所有的表單 UI 程式,傳進來 SQL 敘述,然後再去存取資料庫。看似方便簡單,但這顆萬用的 DB Manager 已經被約束了特定的實作技術與特定的資料庫,所以當然無法抽換,原來他們使用 ADO.NET 的連線,現在是不可能換成 Entity Framework;不僅如此,內部程式碼的擁腫肥大,當時的技術人員一離開,幾乎達到無法維護的地步。


還有,他們許多相關於會計的企業邏輯,都零散分佈在表單程式,或用 "艱澀難懂的 SQL 字串" 包起來,可說是毫無組織可言。想要改成 Web 版?想要擴展或修改功能?那當然只有重寫一途!

有趣的是,前桌另一位算是較為資深的同學無奈說道,他們公司的程式碼基本結構也是如此。 !^^

所以,這樣到底如何撰寫所謂以 "類 (Class)" 為單位的單元測試程式呢?

答案是:沒有辦法!也沒有意義!! (雖然勉強來說技術還是可行的)

要我的話,我寧願重寫!嗯,這字眼不好聽,就叫 "重整" 好了。 注意!重整與重構 (Refactoring) 可是完全不同喔,重構的前提是建基在有單元測試程式碼的前提下。

怎麼辦!?這位年輕的學員才剛從某機構的就業養成班結業沒多久,對軟體業這行可還是充滿了憧憬。但如今接到這種超級燙手 (前述的資深技術人員已離職) 的系統維護,這可如何是好?

我建議他比較有機會的緩衝方案:

1. 既有的系統維護,逐步理出共用價值最高的企業邏輯,將之抽離出來放在自行設計的共用 Service 物件上,並且馬上就要為其撰寫單元測試程式。
2. 新開發的功能,務必至少以小功能模組 (Small Functional Module)為開發/維護範圍,一開始就抽離出屬於該模組相關邏輯的 Service 物件,然後還是用原來習慣的方式設計 DBManager 物件,但被收斂侷限在該模組內,如此讓其的共用耦合性盡量降低。

3tier functional module structure

現在這位學員的軟體設計能力尚不足,若待逐漸對結構面的設計觀念提升 (當然要實作面配合),這也才比較有機會施以後續的結構重整-也就是重構的實踐了。

先以小功能模組為單位的開發 (會計 Domain 不了解,如果以人事來說,例如 考核、出缺勤、請假等功能模組,甚至還可以再更細部的模組分解),讓其有著基本的 3-Tier (Presentation、Business Logic、Data Source) 分層結構,如此未來的延展性才有機會。

當然更講究來說,可以參考個人所規劃的 Enterprise MVC (版內檔案區有 Model 檔可下載參考,或以其當關鍵字可參閱原來有撰寫的文章) 分層結構框架。如此系統的彈性、延展性更好,更有機會創造系統的再利用價值。

「軟體需求分析與塑模」- 單一作業流程的塑模

$
0
0

本文收錄於 我的電子書「軟體需求分析與塑模 – 第二章、企業流程的分析與塑模」。

描述與紀錄單一作業流程內部的一連串活動,使用 UML 活動圖 (activity diagram) 是最為適切的。

依據 UML 三巨頭的論述,活動圖主要的目的在陳述活動與活動之間的流程控制的轉移 (control flow transition)。
Activity diagrams emphasize the flow of control from activity to activity. (《The Unified Modeling Language User Guide》, Grady Booch, James Rumbaugh & Ivar Jacobson, 1999, pp. 257)

這裡所謂的活動,可以指企業的活動,也可以指應用程式中的某個特定功能。

不過一般來說,由於「活動」的定義並不如「物件」那麼明確,因此,在進行系統設計時,一般比較不傾向於利用活動圖來表達應用程式的結構 (採用物件模型較為恰當);也因此,活動圖通常會比較適合用於表達企業活動的工作流程關係。除此之外,由於活動圖非常類似傳統的流程圖 (flow-chart),因此,活動圖也適於表達細部程式的程序性結構。

參考下圖,藉由一個請假作業流程來說明 UML 活動圖的主要圖形元素。

圖、請假作業流程活動圖的基本圖示語法

 

  • 起始點 (Activity Initial)
    起始點指的是一連串活動的開始點。在一張活動圖中,必須要且只能夠有一個起始點。
    起始點的圖示是「
    圖、活動圖-起始點圖示
    」。
  • 結束點 (Activity Final)
    結束點指的是一連串活動的終結點。在一張活動圖中,可以有多個的結束點。
    結束點的圖示是「
    圖、活動圖-結束點圖示
    」。
  • 活動 (Activity)
    活動是活動圖中最核心、最重要的一個元素。前述已提及關於「活動」的定義:一個必須履行的主要工作,為以滿足一個操作上的契約。

    活動的命名必然是「動+名詞」的詞性,以突顯它表達的是要 ”做” 的 “事情” (do something)。

    界定單一的活動是依據在某一特定期間 (specific time) 內所作的事情。

    例如:「醫院櫃台人員處理病患的掛號服務」就是一個活動。在這一特定期間內,櫃台人員在該活動的主要目的為:「處理掛號」,因此就以該目的為該活動來命名。

    許多需求分析人員對於「活動」的界定沒有一個很明確的定義,因此而導致有時活動很大,例如把子系統/模組當成活動;或者把某一個只是細部的操作細節當成活動,例如計算訂單總額。這些都相當不適切。

    另外活動必然是「服務導向 (service oriented)」,標榜的是「要做的事情」。所以也不能把資料本身當成活動主體,這也是需求人員常會出現的問題。把資料當成主體的分析方式是屬於「DFD (Data Flow Definition)」的方法論,但因過早揭露資料的細節,導致開發的複雜性提昇:而「服務導向」的方式則是把資料「封裝 (encapsulate)」於活動的內部,當確認開發的主軸後,再逐一揭露處理的細節。由簡入繁,避免陷入細節紛爭,如此可大幅降低系統開發的風險。

    活動圖中的 Activity 的表達圖示是「
    圖、活動圖圖示
    」。
  • 動作 (Action)
    「動作」必然是包含於「活動」的主體之內,以突顯每一個「動作」是「單一 (atomic)」的工作項目 (work item),一個「活動」會有一到多個「動作」。

    例如,前述櫃台人員在活動-「處理掛號」的期間內,會處理多個工作事項 (也就是多個動作),包括了查詢病患資訊、收取掛號費用與健保卡、列印單據等。

    活動圖中的 action 的表達圖示是「
    圖、活動圖-action 圖示
    」。
  • 轉移 (Transition)

    轉移代表著流程控制權 (Flow Control) 的移轉。當某一個活動結束後,流程的控制權透過 Transition 表達出其移轉給另外一個活動。

    圖、轉移的表示法

  • 決策 (Decision)
    「決策」則代表一個判斷的準則,其表現方式,則是以「 」來表示。

    圖、決策的表示法

    上圖當指定了一個分支時,此時,從分支連接出去的轉移必須要有條件判斷式,這在UML中稱之為「限制」 (Constraint),在UML中的表示法中,限制的表達方式是用一個中括弧「[]」來表示該轉移必須要有條件的限制。

  • 分派 (Fork) 以及會合 (Join)

    分派以及會合主要代表對於後續活動的同步處理。當某個活動結束後,需要同時進行兩個以上的活動(如工作流程中的會簽),則此時,必須利用「分派」來加以表達;而當某個活動必須要等待其前置的多個活動結束後方可進行,此時,則利用「會合」來表達。「分派」以及「會合」的表達圖示,都是「 」的圖形。

    圖、分派以及會合的表示法

    一般來說,在UML活動圖中,分派與會合通常會是搭配一起出現,也就是說,若是你在繪製活動圖時,加入了一個分派點,那麼,活動到了某個特定的地方,多半會有一個會合點,這對於繪製活動圖的檢核來說,是一個非常容易判別的參考點。

  • 分割區塊(Partition)
    分割區塊 (Partition) 在整個活動表達上,是一個非常重要的概念。我們可以利用分割區塊來將活動分配給對應的角色。以上述請假案例圖為例,由於表達了分割區塊,因此可以清楚地知道「處理請假事宜」的這個活動,主要是由「人事部門」這個角色的人來發動並執行
    活動圖中的 partition 的表達圖示是「
    圖、活動圖-partition 圖示
    」。

 

案例1-進銷存系統進貨/退貨作業流程的活動圖

參考下圖一為進貨作業流程的活動圖;另一為退貨作業流程的活動圖。

圖、進貨作業流程的活動圖
圖、退貨作業流程的活動圖

在繪製活動圖時,必須要特別注意一個重點,亦即:活動圖的主要核心是「活動」,因此在活動圖中,要盡可能地把「中介產出文件」(包括表單、報表等)排除在外。

繪製活動圖比較好的方式是要和領域專家直接面對面溝通,並且最好在訪談過程中直接繪製活動圖。根據活動圖覆述一次你在訪談中所蒐集到的相關資訊,如此一來,活動圖所蒐集到的資訊比較不會失真。

但要切記,在繪製活動圖時,千萬不要落入到活動的細節,活動圖所需要捕捉的,是整體業務流程的「大方向」,而非某個單一活動的準確度或是其相關的企業規則 (Business Rule),有關細節的相關描述,應該是在討論「使用案例」時才需要捕捉,若是過早介入流程細節,需求收集 (Requirement Acquisition) 很容易就陷入到分析癱瘓的陷阱,在繪製活動圖時不可不慎。

 

案例2-工作流程文字描述轉視覺化的流程活動圖

下述是一個真實的案例。客戶只給幾行的文字敘述,就希望開發單位實作出適宜該單位運作的工作簽核系統。

客服人員接到信用卡客戶要求臨時調高信用額度,客服人員詢問調整原因並向客戶詢問身份字號、出生日、聯絡住址等登錄之基本資料以確認是否本人,並調閱繳款記錄是否異常。然後詢問客戶打算調高之額度為何及調整之期間多久。確認完畢後,即送出案件,啟動客服流程。

案件送出,即通知客服後勤人員處理,客服後勤人員從工作駐列(Queue)中取得案件後,判斷臨時調高之信用額度是否為客服人員被授權的額度內,若是,則以電話聯絡客戶再確認是否有提出申請,確認完畢即結束流程。

若臨時調高之額度高於客服人員之授權,則後勤人員以電話聯絡客戶後,向客戶確認是否申請並解釋他被授權所能調整之額度,若客戶仍需超過額度,則後勤人員將案件轉呈客服主管處理,客服主管收到案件後,回電客戶確認資料並決定授權金額,確認完畢後即結束流程。

開發單位若僅依此文字描述就據此開發,很容易就產生解讀上的誤解。而若需求分析人員可以先轉化至圖形化的表達,如此可以先行與客戶單位確認需求的正確性,相關開發人員也比較容易理解而不致耗費太多時間在不必要的猜測解讀,甚而作白工。

參考下圖,上述的文字敘述其實就是在描述一段事務流程,主要的目的在於提供顧問「臨時調高信用額度」的企業服務。
這是轉化為 UML 活動圖後的視覺化呈現,是利用文字敘述,抑或是採以設計圖表達,哪種容易讓開發人員解讀,一目了然。這也是所謂「塑模 (modeling)」的威力之所在。

圖、臨時調高信用額度的作業流程活動圖

如何從巨觀的需求流程分析,可以直覺無縫的橋接至程式寫碼?

$
0
0

本文同步發表於「FB 軟體設計鮮思維」社團。

這裡採用個人所發表關於需求分析的「MSS」與 程式寫碼的「SSD」三層次分析與實作方法。

需求分析階段的 MSS 三層次

關於 MSS,可以參考原來寫的這篇:「大業務流程塑模的MSS三層次原則」。

o M(multiple) Process。
o S(ingle) Process。
o S(ystem Function)。

    以「請購-採購」作業流程 (business process)為例:
  • Multipole Process:「請購」與「採購」兩個作業流程的表達,焦點擺在「請購」作業內部的一連串活動 (activity)分析。
  • Single Process:「請購」作業流程的內部活動表達,焦點擺在「進行供應商評等及比價」的系統功能對應。
  • System Function:「採購」資訊系統的系統功能界定 (利用使用案例)。焦點擺在「比價」的系統功能實現 (realization),實現的步驟主計有「列出廠商資訊」、「評等列出優先順位供應商」、「儲存比價交易紀錄」。

程式寫碼的 SSD 三層次實作

可以參考「實作 Enterprise MVC 巨觀結構的 POC-觀念篇」內關於「控制類別」的說明。

o S(ubject) 主題。
o S(TEP) 實現主題的步驟。
o D(etail) 實作每一步驟相關的細節 (欄位明細與業務邏輯)。

    承接上述例子關於「比價」使用案例的實現。
  • Subject:「比價」使用案例-對應至「比價Control」控制類別。
  • STEP:「比價Control」類別內的 Function (Method)對應為:
    「ListSuppliers()」、「ComparativePrice()」、「SaveComparativePriceTransaction()」。
  • Detail:「ListSuppliers()」列出廠商的清單與欄位資訊From資料庫;「ComparativePrice()」處理比價的邏輯與評等;「SaveComparativePriceTransaction()」儲存本次比價的交易結果至資料庫。

關於 DDD (Domain Driven Development) 微服務的結構設計議題

$
0
0

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

最近在線上輔導了一位 技術職PM 結構設計的實現 (Realization)議題,他傳給我 DDD 的架構圖,覺得在「Domain Service」與「Domain Model」的責任界定上,觀念不是很清楚。

嗯,其實這所謂的 DDD (Domain Driven Development) 架構圖根本就是典型 3-tier (Presentation-Application Logic-Data Source) 分層結構呈現爲圓形的剝洋蔥層次而已,越是內層 (Domain Model) 越代表爲系統的核心。
DDD Onion Architecture Diagram

工程師從這張圖往往會認爲「Domain Model」是最重要的核心觀念。是這樣沒錯,但對以「需求爲導向」的專案開發性質,它卻反而沒那麼重要!況且結構設計的基礎功夫要很紮實,封裝-介面-多型 諸多「虛」的設計觀念確實能充分了解並能整合活用,沒有花上 5-10 年以上功夫,是不容易應用在現實的系統開發上的。相對於此,「Domain Service」對現實的專案開發可是更切實際,且結構設計上的觀念也會比較容易入手。

界定好「Domain Service」這一層,就可以確實封裝 (encapsulate) 「資料存取」與「邏輯運算」這兩大塊,後續才得以透過重構 (refactoring) 的手段 (前提要撰寫單元測試),讓責任的歸屬更加確實,這也是系統的「延展性」議題。簡而言之,「Domain Service」這一層,是決定系統在展示層 (presentation layer)與應用邏輯層 (application logic layer)未來是否能各自有機成長卻互不影響的主要關鍵。

我們用一個很小的案例:「放入購物車」爲實作案例,第一課先讓學員專注在「PlaceShoppingCartService (簡化爲 PlaceCartService)」這個服務類別,以及爲它撰寫「PlaceShoppingCartSericeTest」所需的測試案例 (test case) 使用 C#.NET 的實作上。

果不其然,過於沉浸於實作技術的工程師,往往會馬上想到實作的細節,卻會忽略了幾個結構設計上的原則:

  • 各類型類別的責任界定:如服務類別主要責任爲何 (方法、參數、回傳值)。
  • 命名的學問:服務/測試/資料傳遞 類別、方法、變數等命名議題。
  • 測試案例:該規劃哪些測試方法與準備測試數據。
  • 資料傳遞物件 (dto, data transfer object):如何組織資料、是否會被多個 Service 類別共用等議題。

這位學員的實作能力相當不錯,有些觀念一旦取得共識,他馬上就撰寫 C# 程式碼在 Github 上傳給我 Review 並在線上討論。不過其實在寫出程式碼前,在觀念溝通的過程中,如果先能用 UML 類別 (class)圖與物件合作的循序 (sequence) 圖表達,不需要工具,在筆記本塗鴉拍照上傳就可,這樣對觀念的表達很快就可以表現出來,而且因爲先過濾掉實作細節,反而比較能突顯討論的重點。可惜絕大部分的實作開發人員還不懂得如何使用設計圖表達設計思維,這應該也是必備的技能。

一對一的線上輔導得以教學相長。從實作的細節過程中,更能了解諸多工程師的想法與問題並可以反饋到設計的思維上;同時我也從過程中學到一些雲端開發工具的使用,對未來開發輔導與教案的整理上很有幫助。

藉由這個輔導的案例,除了練習的程式碼範例 (不涉及該學員的工作隱私),後續我也會把上述所提及的幾個結構設計原則撰文討論與分享。

關於 DDD (Domain Driven Development) 微服務的結構設計議題〉這篇文章最早發佈於《Kenmingの鮮思維》。

聊聊關於 UML 輔導個案的二三事

$
0
0

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

UML System Sequence Diagram

前兩個星期有位上過前一期「軟體架構師」課程的學員,他在某大金融單位擔任技術職PM,特地利用週末時間到我家附近,請教我關於他利用 UML 所繪製的設計圖問題。相當認真,所以我很願意陪他一同討論軟體相關議題,順道一同在肯德基吃午餐。總共花了約兩個來小時吧,該學員還要去參加他的讀書會,真是有夠認真啊,不過起碼有討論出一個比較具代表性的使用案例其實現的主要程序描述。

畫出來是否正確或合理與否是一回事,至少他肯利用 UML 表現出他的設計思維就很值得肯定,這才有機會可以指指點點與討論的。

他只畫了使用案例圖與某一結構設計的類別圖,因爲有公司機密問題,這裏就不方便貼出他的原稿。我只就他的設計給予一些建議與修正,並利用他在 Mac 所使用的 UML 工具繪製出來。

  • 工程師規劃表達系統需求功能的使用案例 (use case),往往會以「作業模組」界定爲一個使用案例。這其實不是使用案例,而是一連串活動的業務流程 (或工作流程),宜應使用 UML活動圖 (activity diagram) 來表達不同期間的作業活動,並經由多個參與的角色協同合作來完成特定的作業目的。至於 Use Case 的界定,應是以「達成某一特定操作目的 (specific goal)」來界定會比較適宜,對比企業流程的話,其實是會對應作業流程內的某一「活動」 (activity)。
    UML Use Case Diagram
  • 類別 (class) 圖有些太過度設計了,太過使用一些所謂 O.O 的技巧,反而是會造成複雜度的提昇。例如 Factory 機制,在 AP 層去設計它可能沒有意義,因爲往往在底層 Framework 就已有提供 (例如 Spring 早已利用 Container 來「生產」Bean 並控管其 Scope 與 生命週期。

    工程師必須要能確實理解設計目的爲何:爲何制定抽象的介面規格,又爲何需要去擴展 (extend) 一般性類型的行爲。而這些並非是一開始就能考量周到,而是隨着開發/維護的進程持續重構得以有機成長。

    過程中由於沒有帶筆記本,所以乾脆我就在面紙上大概繪製下類別圖與學員確認他的設計想法。 :)
    UML Class Diagram

  • 啊?循序 (sequence) 圖呢?! 學員沒有表現出來,其實我相當推薦使用案例 (表達系統功能的主題),再佐以系統循序圖 (表達系統功能實現的主要程序) 就很容易釐出後續實作與結構設計的重點。

    所以我們重新界定並捕捉一些相關於該業務流程的系統功能,再就比較具交易關鍵型的使用案例,先以系統循序圖來實現主要的程序。

    利用系統循序 (system sequence) 圖,就可以很清楚地知道該系統功能 (use case) 的主軸與主要的實現程序 (procedure),這樣在實作上其實可以很簡單直覺。至於變動性的結構議題,就可以再觀察每一條主要的訊息 (message),是否存在着業務邏輯的複雜度議題,或者是系統的邊界 (與資料庫/外部系統) 實作技術變動議題,這些就可以各別利用分層結構的框架以 Domain 的物件結構設計來有機成長了。

  • UML System Sequence Diagram

聊聊關於 UML 輔導個案的二三事〉這篇文章最早發佈於《Kenmingの鮮思維》。

使用 UML 圖表達微服務 (Microservices)的架構設計

$
0
0

Microservices Use Case Model

這裏藉由一個「放入購物車」的極小型功能案例,並利用 UML 各面向的設計圖,來表達微服務 (Microservices) 的架構規劃與設計的呈現樣貌。下列是幾個主要設計面向的設計圖 (並非是全部) 可以參考。

系統功能與實現程序

利用 UML 使用案例模型 (use case model) 與系統循序 (sequence) 圖表達「放入購物車」的系統功能與主要實現程序。

Microservices Use Case Model

Microservices System Sequence Diagram

  • 從需求模型可以看出共有兩個微服務:「Product Microservice」與「購物車 Microservice」。
  • 每一個微服務均各有資料庫,圖中可看出共有兩個。資料庫是私有倉儲,不能跨微服務直接存取 (即使位於同一區域都不行),只能透過 API 呼叫。

系統部署

利用 UML 系統部署 (Deployment) 圖表達了「Web Portal」、「API Gateway」、「Product & 購物車 Microservices」之間的系統連結。

Microservices Use Case Model

  • 系統之間的連結是透過 REST API,這是比較通用,但不是絕對只能採用該通訊協定。
  • 「API Gateway」擔任類似 Router 的轉址,係屬於底層系統伺服器 (server)層級,一般並非是由 Application Developer 開發,而是可以採用商用/開源的產品。

微服務內部的分層結構

利用 UML 套件 (package) 圖規劃了每一個微服務內部的分層結構。網路上文章大都採以垂直 Layer 的方式來表達分層,個人仍是偏好採用老派 (old-school) 的水平 Tier 分層方式,來表達出「展示 (Presentation)層」、「應用邏輯 (Application Logic)層」、「資料存取 (Data Access) 層」與「資料來源 (Data Source)層」。

Microservices Use Case Model

  • Web API 係屬於展示層 (一般是透過 Controller 的實作),負責接收 REST Client 的 Request,傳進的參數爲 JSON 資料結構。
  • 微服務內部各層物件之間的連結,可以直接傳遞 JSON 當爲參數與回傳值,或者也可以在展示層就轉換 (transform)爲 資料傳遞物件 (DTO, Data Transfer Object),兩者格式的互轉是很容易的,一般都有現成的工具物件可以直接使用。
  • 資料存取層的存取物件在微服務的術語稱爲「Repository (儲庫)」,從名字就可以得知它是多個 Service 物件功用存取的。一般在大型 (Monolithic)系統的 DAO (Data Access Object) 物件最好不要設計爲共用,會非常的龐大擁腫;但由於微服務係由 Bounded Context 或功能模組界定了領域邊界 (domain boundary),範圍已侷限,所以「Repository」的設計考量是可以共用的。
使用 UML 圖表達微服務 (Microservices)的架構設計〉這篇文章最早發佈於《Kenmingの鮮思維》。

「軟體需求分析與塑模」- 區分功能性需求與非功能性的需求

$
0
0

本文收錄於 我的電子書「軟體需求分析與塑模 – 第一章、需求分析概觀」。

所謂的功能性需求 (functional requirements) 即是使用者需要系統能為他做什麼。這往往是顯而易見的,因為,使用者可以清楚的看到系統為他服務並會有回應。例如在一個訂購系統中,功能性需求有:

  • 系統接受顧客的訂購 (系統功能-place order),並且會通知倉管該產品庫存量是否充足。
  • 系統會對前一日的訂購在當夜會產生統計報表 (系統功能-process order summary report)。

系統的功能性需求源自於開發或維護中系統的問題領域 (problem domain)。例如「電子商務系統」,功能性需求有「處理訂購」、「追蹤訂購」…等。

功能性需求需直接滿足於使用系統的操作人員或相關利益關係人 (stake holder),它是屬於系統的「顯性價值」,是與企業的需求有直接的關聯。

功能性需求的分析技術即為本書內容的重點。各類軟體開發方法論均有提供如何分析系統功能的技術。例如 Agile (敏捷式) 的「user story」、SCRUM 的「backlog」,以及行之有年的「use case (使用案例)」。本書的系統功能分析主以「使用案例」的分析技術來捕捉系統功能性需求。它既能包容其它需求分析的技術,又能很順暢橋接到結構設計與程式寫碼實作,這在後續的章節即會詳述,並會以案例研討的方式舉例說明。

非功能性的需求 (non-functional requirements) 往往是使用者所感受不到系統有直接提供服務並有回應。非功能性的需求是總體 (global) 的、模糊 (fuzzy) 的一些因素而導致系統整體的良好運作。例如:

  • 系統要能處理超過1千人以上線上訂購書籍的效能 (performance issue)。
  • 系統為了要能應付日增的交易處理,所以必須要能具備延展性 (scalability issue)。
  • 系統的登入 (logon) 須具有密碼加密的機制 (security issue)。

系統的非功能性需求源自於開發或維護中系統的解題領域 (solution domain)。例如「電子商務系統」採以「JEE (Java Enterprise Edition) + Spring Framework」的實作解題技術框架。

非功能性需求是屬於系統的「隱性價值」。它不容易被直接感受到,只有當碰到系統整體性的震盪 (如多人操作存取時的效能與穩定問題、帳戶安全性問題)時,系統的品質問題與危機意識等才會浮現出檯面。

一般非功能性需求較被列為實作面的考量,例如下列幾個實作議題:

  • 多人上線時的交易效能與穩定性。
  • 安全性的考量。
  • 分散式溝通議題。
  • 延展性議題。
  • 異地備援/災難重建議題。

非功能性需求並非採以上述所提及的系統功能分析 (如 use case) 技術,一般它可能僅以清單列表的方式註記並列為系統的一種約束 (constraint) 即可。

「軟體需求分析與塑模」- 區分功能性需求與非功能性的需求〉這篇文章最早發佈於《Kenmingの鮮思維》。

C#.NET Core CRUD 基本資料維護實作範本 –三層式架構以及可以切換 E.F Core 6 與 ADO.NET 實作

$
0
0

已經整理好 C#.NET Core CRUD (Create,Read,Update,Delete) 基本資料維護的實作範本,並已上傳至 Github 供下載:https://github.com/kenming/petstore-crud-template-csharp

關於該範本如何執行 (包括跑單元測試)、主要引導功能、開發工具與建置、類別圖展示等,已具體詳細寫在 README.md 文件。

建議要執行該應用程式前,先更改下 Sqlite 資料庫檔案路徑,然後先執行測試專案內的所有單元測試方法

關於該範本所涵蓋的一些設計思維與所對應的實作問題,版友們可以提問討論與分享想法。關於程式碼的實作細節與設計思維,我還會另撰寫文章詳細說明。

後續的版本演進我會再加上:

  • 多個表格關聯的 CRUD 實作。
  • 使用 Mock 應用在單元測試,隔離 Service 類別依賴具體 Dao 的資料庫存取。
  • 使用 Vue UI 框架整合本範例。

Brief Description

網路上看到關於基本資料維護的 CRUD 範例幾乎都是資料導向 (data oriented) 的寫法,也就是把 MVC Controller 與 資料存取綁在一起。現實上稍有規模的專案採用這種開發模式會導致系統的複雜度提升,不容易應變。

花了幾天時間撰寫了 C#.NET Core (前年有寫過 Java Spring 的版本) 關於單一資料表的 CRUD 程式碼範本,這是一個完全符合三層式架構的應用程式,同時我這個專案範本可以切換 E.F Core 與 ADO.NET 資料庫的存取實作。

關於 Java/Spring 版本,我則打算再重新改寫,架構當然與 C#.NET Core 是一樣的,只是實作的細節必然會調整下。資料庫的存取方式則打算同時提供 JDBCTemplate 與 MyBatis 的 CRUD 範本。

Features

  • 提供開發三層式 (Presentation -> Application Logic -> Datasource) 架構的 CRUD 實作範本
  • 同時提供 E.F Core (Entity Framework Core) 與 ADO.NET 資料存取方式,並可以切換資料庫存取的實作
  • 實作 E.F Core 與 ADO.NET 的 DAO (Data Access Object) 均各自有撰寫單元測試程式 (Unit Test Code)
  • 專案內嵌 Sqlite,並使用兩種實作方式:
  • File-based 為正常存取用的資料庫,提供給 View 操作
  • Memory-DB 應用在單元測試的 Create, Update, Delete ,避免影響到正常資料庫的存取行為

Development

Class Diagram

Build & Run

下載專案,使用 VS 2002 開啟 .sln 檔案,編輯「appsetting.json」檔案內關於 SqliteDB 檔案實際儲存路徑 (位於下載專案所在路徑內的 \Data 目錄):

  "ConnectionStrings": {
    "SqliteDB": "Data Source = C:\\Projects\\PetStoreCRUDSolution\\Data\\PetStoreDB.db",
    "SqliteMemoryDB": "Data Source = :memory:"
  }

Sqlite 資料庫內已新增 Product Table 與 8 筆測試用資料,DDL & DML Script 已放於專案 \Data 目錄內。另外可以安裝如 DBeaver Database Tool 連接 SQLite 並自行檢視與存取資料。

在「ManageProductService」類別內 Constructor 可以更改資料庫連結實作方式 (預設採用 E.F Core 6)

    public ManageProductService()
    {
        // default : use EF Core to connect to database.
        ProductDao = new ManageProductDaoByEFCore();
        //ProductDao = new ManageProductDaoByADO();
    }

在 VS.NET 內執行「偵錯」→「啟動但不偵錯」或直接按下【CTRL-F5】執行,即可自動啟動瀏覽器進入首頁。點選「PetStore Demo」,即可出現關於 Product CRUD 的操作。

Unit Test (單元測試)

選單「Test」→ 「Test Explore」開啟「Test Explore (測試總管)」窗格,可以一次執行所有單元測試案例,或個別針對其中一個測試方法執行。

如果要追蹤某一個單元測試執行情形 (先對某段程式碼內陳述設中斷點),可以選擇「偵錯 (debug)」方式執行單元測試。

Feedback

相關軟體思維問題,歡迎電郵或參與 Facebook - 軟體設計鮮思維 社群討論。

License

MIT © Richard Littauer

C#.NET Core CRUD 基本資料維護實作範本 – 三層式架構以及可以切換 E.F Core 6 與 ADO.NET 實作〉這篇文章最早發佈於《Kenmingの鮮思維》。
Viewing all 31 articles
Browse latest View live