l

2019年12月11日 星期三

【模式作工作坊】第二梯次

Dec.11 16:40~17:22


第一梯次的【模式寫作工作坊】於上11/30圓滿結束,原本配合AsianPLoP 2020的截稿日期,這個工作坊只預計舉辦一次。

12月初與主辦單位討論,以推廣中文模式寫作為出發點,把中文模式與主辦單位正式徵稿的活動脫鉤。主辦單位將會在AsianPLoP 2020安排一個下午的session,讓(台灣的)與會者體驗中文的 Writer's Workshop,在活動中討論用中文撰寫的模式.

Teddy預計徵求3~5篇中文模式在該session中討論,目前有三位參加第一梯次【模式寫作工作坊】的朋友有興趣嘗試。一直到明年二月底之前,Teddy會免費協助有意願者修改他們的作品。

離明年三月會議舉辦還有一點時間,Teddy計畫舉辦第二梯次的【模式寫作工作坊】。

***

工作坊簡介

模式寫作工作坊議程如下:

  • 介紹模式起源與PLoP研討會Writer’s Workshop進行方式。
  • 模式六大格式介紹,並透過閱讀模式來驗證模式格式的作用。
  • 模式寫作,介紹Pattern Language、確定寫作主題以及現場寫作與修改練習。

***

報名

  • 課程費用: 8,000元。活動由「台灣軟體工程學會」開立收據(無提供發票)。
  • 日期:2020年1/7和1/14日(禮拜二),19:00~22:00,共6小時。
  • 地點:泰迪軟體,台北市延平南路12號四樓
  • 備註:
    報名本工作坊之「本人」將可免費參加2020 Asian PLoP (報名費價值約6,000元),https://pl.csie.ntut.edu.tw/asianplop2020/

    ***

    友藏內心獨白:真的是最後一梯次了。

    2019年12月10日 星期二

    領域邏輯與應用邏輯

    Dec. 10 13:50~14:49


    名詞解釋

    在物件導向分析與設計(Object-Oriented Analysis and Design;OOAD)、領域驅動設計(Domain-Driven Design)或是簡潔架構(Clean Architecture)中,經常會看到領域邏輯(Domain Logic)應用邏輯(Application Logic)這兩個名詞。在Clean Architecture中,前者稱為關鍵業務規則(Critical Business Rule),後者稱為特定應用業務規則(Application-Specific Business Rule)。

    一般針對這兩個名詞的解釋:

    • 領域邏輯:特定業務領域(business domain)都適用的邏輯。
    • 應用邏輯:在某個業務領域中,特定應用程式的邏輯。

    一般情況下,除非很大型的系統,否則開發人員遇到的情況很可能只有開發一個業務領域中的一個應用程式。也就是說,不太容易區分這兩者,特別是對初學者而言。

    ***

    例子

    最近跟北科大資工系ezKanban團隊討論看板系統的領域模型(domain model)。原本的需求只需支援圖1中的看板系統。

    ▲圖1:看板系統範例


    為了支援圖1的看板系統,ezKanban的domain model如圖2所示。

    ▲圖2:ezKanban的Domain Model


    圖2暗示了一個領域邏輯:一個Stage(圖1中的待辦事項、分析、實作等)有一個預設的MiniStage(圖1中待辦事項底下的想法與Top 5),一個MiniStage有一個預設的SwiLane(用來放置工作卡片的物件)。

    ***

    過了一陣子,Teddy覺得一個看板系統應該有一個預設的Stage用來存放剛剛新增的Work Item(工作卡片),還有另一個預設的Stage用來存放已完成的Work Item。如圖3所示。

    ▲圖3:新的看板系統需求,一個看板有兩個預設Stage:Backlog與封存(Archive)


    如此一來,增加了一個新的邏輯:一個Board物件至少有兩個Stage,如圖4所示。

    ▲圖4:Board與Stage的關係


    圖4中的關係,應該要算是領域邏輯還是應用程式邏輯?

    很顯然地這應該是一個應用程式邏輯,因為ezKanban這個應用程式的要求,才讓Board與Stage產生這樣的關係限制。如果是其他人使用相同的domain model來開發看板系統,則不一定會對Board與Stage的關係規範這種限制。

    所以要實作圖4的邏輯,應該是放在DDD所說的應用程式層(Application Layer),或是Clean Architecture裡面的使用案例層(Use Case Layer)。

    至於圖2中Stage與MiniStage以及SwimLange的關係,屬於domain model的核心邏輯,所以在DDD裡面的Domain Layer(又稱為Model Layer)或是Clean Architecture的Entity Layer實作。

    ***

    友藏內心獨白:分層負責才會乾淨。

    2019年12月9日 星期一

    變成專家之後的學習

    Dec. 09 14:10~15:10

    ▲畫片節錄自電影「鹿鼎記」


    念博士班的時候

    有一種說法,變成專家需要一萬小時的刻意練習(請參考〈一萬個小時的練習〉)。至於鄉民們對於這「一萬小時」的數據是否買單,信或不信,不是今天想要談的重點。Teddy想要說的是,每個人都有自己「學會一件事」(變成專家)所需要的時間。這個時間,依據每個人的能力可能會有所差異,但從「正常人類」的範圍來討論,大致上應該會落在一個相差不多的區間內。

    Teddy以前在念博士班的前三年,都屬於「練功階段」,修課、準備資格考、讀書、讀論文、練習寫作e-learning patters。因為還在蹲馬步階段,嘗試弄清楚「地形地物」,當時沒能力寫出什麼偉大的論文可以拿去投稿。

    後來基本功練得差不多,漸漸發現,接觸到一個軟工相關的新題目之後,可以在18個月(一年半)左右至少寫出一篇國際研討會的論文,算是對這個題目的學習成果給一個階段性的交代。

    後來這「18個月」就變成自己學習新題目的一個時程表,每當自己覺得「好棒棒」的時候,就會提醒:「你才接觸這個題目不到半年,一定還有很多問題你自己沒遇到,不要高興太早。多讀點書和論文,多動手寫程式才是真的。」

    18個月,以一天4小時計算,一年算200個工作天,18個月有300個工作天,一共是1200小時。這1200小時就是Teddy估算在自己成為軟工專家之後,學習軟工新題目到有所小成所需要的時間。

    ***

    成立泰迪軟體之後

    成立泰迪軟體之後,前幾年所開的課都是以前工作與唸書10幾年所累積的成果。即使是「單元測試這樣學就會了實作班」與「軟體重構入門實作班」這些原本已經很熟的技術,要變成一門課,也是要近百個小時的準備。

    2020年新開的「領域驅動設計與簡潔架構入門實作班」(原本的Clean Architecture實作班),則是前後花了約三年的時間才演化成現在的版本。以前念博士班的時候比較專心,WIP比較少,所以只要18個月就可以學會一個新的題目。現在年紀越來越大,理論上「知識越來越豐富」,但因為泰迪軟體個工作本質上context switch很大,一下子講Scrum,相隔沒幾天又要講Design Pattern,接著又切換成例外處理設計。這個多不同的主題平常都要花點時間去注意現況的發展,無法像以前念書時那麼專心學一件事,所以整個lead time拉長,從以前18個月,變成現在36個月。

    ***

    結論

    這幾年在北科大兼任授課,有些學生跟Teddy反映:「為什麼同一個問題Teddy可以翻來覆去用好幾種不同的角度不斷地拿出來討論?」因為學生覺得「這樣好浪費時間,希望Teddy教快一點,他們想多學一些。」

    Teddy總是跟學生說:「你們以為已經學會了,但其實只是學到表面薄薄一層的含意。這些表面的東西,根本不用來上課,去Google就可以找到答案。上課就是要讓你們學會自己思考,養成自我批判與學習的能力。老師不可能一直跟在你們身邊,遇到問題只要跑來問老師就有答案。要練習讓自己變成自己的老師。」

    但坦白說,並不是每個人都想要當自己的老師。想要搖一搖蘋果樹就有蘋果可以吃的人還是比較多。

    變成專家是一種獲得Quality Without A Name的過程,變成嘴砲王則是一種獲得A Name Without Quality的手段。沒有對錯,端看自己的取捨而定。

    ***

    友藏內心獨白:聽到「有一批便宜的牛肉」要提高警覺啊。

    2019年12月7日 星期六

    感受作用力

    Dec. 07 09:21~10:25

    ▲使用者故事對照(User Story Mapping;USM)活動


    不是可不可以的問題

    有一個問題每過一陣子Teddy就會被跑Scrum或Kanban的朋友被問一次:「可不可以用軟體加投影機取代實體Scrum Board或是Kanban Board?

    這種問題,問「可不可以」之前,應該先問「Scrum Board或Kanban Board要解決什麼問題?」,然後再問「改用電子化之後,原本要解決的問題依然持續被解決嗎?有沒有產生新的問題?」。

    ***

    低科技,高接觸

    敏捷圈有一種說法:「Low Tech, high touch. High tech, low touch」。有好幾位跑Scrum的朋友跟Teddy提過,他們從實體Scrum Board(Task Board)改用軟體加投影機之後,原本Daily Scrum每個人都投入的狀況,變成傳統會議那種大家看著投影機「假裝有在聽」別人說話,但卻少了很多之前的互動,原本Daily Scrum每天「重新計畫」的目的因而大打折扣。

    但也有朋友告訴Teddy,他們花重本買了大觸控電視用來取代實體Scrum Board,效果比起投影機要好很多,接近實體Scrum Board。

    感受案發現場的作用力(forces),看看解決方案有沒有平衡這些作用力,你就可以判斷目前的解決方案是否合適。

    通常會想用數位工具取代實體Scrum Board或Kanban Board,不外乎:

    1. 工作環境沒有牆面可以拿來建置實體Scrum Board或Kanban Board。
    2. 不是所有人都在同一工作地點,可以直接觀看實體Scrum Board或Kanban Board。
    3. 想要保存Scrum Board或Kanban Board的歷史紀錄。

    第1點,工作環境不允許應該是要「突破」的限制而不是反過來被它限制。工作場所沒有電腦怎麼辦?總不能上班的時候把程式寫在紙上,回家再輸入自己的電腦中吧!沒有電腦公司要去買啊(或是凹員工自己帶)

    至於其他兩點,Teddy建議以實體Scrum Board或Kanban Board為主,在讓團隊成員或指派特定人員每日更新電子看板即可。聽起來好像很麻煩,實體與電子各有一份,還要手動維持同步。但實際上,同步的工作一天頂多也就花個10分鐘,是值得的投資。

    ***

    感受作用力

    今年11月的【Scrum敏捷方法實作班】 ,不知道是不是因為學員組成比較多元,包含專案經理、產品經理、開發人員、主管,在各項練習活動中都特別投入,效果也很好。

    特別是在使用者故事對照(User Story Mapping;USM)活動中,所有人一起同步討論需求。有幾位學員跟Teddy反應,和他們以往的需求討論會議有很大的差別,不只是在形式上USM比較有趣,在實質面獲得的有用資訊量也大勝傳統方式。

    但這並不能完全歸功於USM,同樣的練習活動,Teddy也遇過產出空洞使用者地圖的團隊。所以說,好的團隊成員加上用對方法,身處現場便可感受到好的力場。

    這不是風水,更不是迷信。認真做事,活在當下,便可察覺到團隊的狀況。

    ***

    友藏內心獨白:工具與方法最後都是要遺忘的東西。

    2019年12月6日 星期五

    如何閱讀模型驅動設計建構區塊的模式語言

    Dec. 06 21:40~23:10

    ▲圖1:Model-Driven Design模式語言,節錄自藍皮書


    模式語言範例

    Domain-Driven Design: Tackling Complexity in the Heart of Software》(藍皮書)Part II,「The Building Blocks of a Model-Driven Design(模型驅設計的建構區塊) 」有一張圖( 如圖1所示),代表Model-Driven Design模式語言

    這個模式語言代表DDD單一bounded context內的核心模式,今天Teddy要談一下如何閱讀這個模式語言。

    ***

    模式語言

    模式語言由建築師Christopher Alexander所發明,透過一組有方向性的模式來解決一個大的設計問題。一個模式語言最頂端的模式,代表使用這個語言的人想要「製作出來的東西」。在圖1中,模式語言第一個模式是Model-Driven Design(模式驅動設計),它本身是一個DDD模式。這是一個比較大(或是說比較抽象、比較高層次)的模式,為了落實Model-Driven Design,需要依靠它下方第一層的其他四個模式,讓Model-Driven Design更完整:

    • Service
    • Entity
    • Value Object
    • Layered Architecture

    Service模式下方沒有其他模式,代表Service模式本身不特別需要其他模式來支持它就已經很完整。Entity模式則需要Aggregate、Repository與Factory這三個模式使其完整。Entity可透過Factory來產生實例。Aggregate包含Entity與Value Object,Entity也需要倚靠Aggregate來確保資料的完整性。

    在圖1中,標示著Entity透過Repository來存取,但Teddy認為其實這個關係可以不用畫在模式語言中,因為Aggregate才會有Repository,單獨的Entity是不能透過Repository來存取。客戶端只能透過Aggregate Root來讀取Aggregate內部的Entity。

    ***

    Value Object下方則有Aggregate與Factory,這個關係很清楚,就不解釋了。Aggregate下方則有Repository與Factory,分別用來儲存與讀取以及生成Aggregate。

    ***

    Model-Driven Design下方最後一個Layered Architecture模式,比起前述其他模式都要大得多。前面幾個模式算是「設計模式」,Layered Architecture已經是「架構模式」。嚴格說起來,Layered Architecture下方還是可以展開其他模式來支持它的實作。

    還有一點要注意,在藍皮書中,對於Layered Architecture模式的描述,屬於傳統階層式架構,階層之間的相依性是由上往下,上層依賴於下層。以現在的角度來看,這種解法應該改套用dependency inversion(相依反轉)原則,拿掉上層對於下層的直接依賴。

    如果是Teddy現在來畫這個模式語言,會用Clean Architecture模式來取代Layered Architecture。

    ▲中文版《領域驅動設計》第68頁描述Layered Architecture模式的解決方案。

    ***

    最後,圖1還有一個Smart UI模式,但是它與Model-Driven Design模式之間卻出現一個X符號。Teddy在Alexander原始的模式語言中並沒有看過這種表示方法,作者的用意只是提醒讀者,Smart UI與Model-Driven Design彼此互斥。

    ***

    重畫Model-Driven Design模式語言

    ▲圖2:Teddy重劃後的Model-Driven Design模式語言


    依據以上討論,圖2是Teddy重畫後的Model-Driven Design模式語言。Teddy習慣由上而下來畫製模式語言,而非像藍皮書中由左而右繪製。自己重新整理之後,感覺比藍皮書的版本還要清爽與容易記憶 XD。

    ***

    工商服務

    對於領域驅動設計(Domain-Driven Design;DDD)與簡潔架構(Clean Architecture)有興趣的鄉民,歡迎參加泰迪軟體的領域驅動設計與簡潔架構入門實作班】。

    對於設計模式有興趣的鄉民,歡迎參加泰迪軟體的Design Patterns這樣學就會了–入門實作班

    ***

    友藏內心獨白:用模式語言思考可以看到問題全貌。

    2019年12月4日 星期三

    把問題寫成一個問句

    Dec. 04 08:29~10:25


    選擇解決方案的困難

    使用設計模式(design pattern)超過20年,也教了好幾年的設計模式。Teddy發現一個常見的問題,就是遇到設計問題時,不知道要套用哪一個設計模式

    Teddy一直覺得,讀模式除了模式名字(Name)以外,最重要的就是要知道模式要解決什麼問題 (Problem),最好能夠把問題寫成一個問句,用一句話就能說出該模式存在的目的。

    如此一來,在套用模式的時候,針對解決相同問題的模式,只要考慮他們彼此之間forces的差異,就可以判斷哪一個解決方案比較合適。

    可惜很多模式的撰寫風格並沒有明確指出模式所要解決的問題,而是使用敘述性的文字把問題與forces甚至是解決方案混在一起談論。讀者只關注到模式的解決方案,導致誤用模式的情況。

    ***

    Value Object

    ▲翻拍自《Domain-Driven Design: Tackling Complexity in the Heart of Software》,p.98 。

    上圖為《Domain-Driven Design: Tackling Complexity in the Heart of Software》(藍皮書)書中描述Value Object模式的段落,黑體字的部分指出幾點問題,這個看起來好像是Value Object所要解決的問題(從Teddy的角度來看,黑體字的部分比較像是forces,也就是問題的限制或特徵)。但是,讀完之後還是不知道如何用一句話說明Value Object的Problem。

    黑體字之後突然冒出一句「An object that represents a descriptive aspect of the domain with no conceptual identity is called a VALUE OBJECT 」,這看起來像是在說明解決方案。一下子討論問題,突然又冒出解決方案(書中下一頁才是詳細的解決方案章節),更容易讓讀者抓不住模式所要解決的問題到底是什麼。

    ***

    改寫練習

    藍皮書第五章A Model Expressed in Software提到了四個模式:ENTITY、VALUE OBJECT、SERVICE、MODULE,Teddy認為它們都要解決一個共同的大問題。因為forces不同,所以衍生出四種不同的解決方案(四個不同的模式)。

    在此Teddy試著改寫前三個模式,它們擁有相同的Context以及Problem:

    Context:你正在使用物件導向方法定義領域模型。

    Problem:你如何表達物件(領域元素)?

    ***

    ENTITY

    Forces:

    • 物件不是由其屬性所定義。
    • 兩個屬性不同的物件可能被視為相同。
    • 即使兩個物件具有相同的屬性,它們可能被視為不同的物件。
    • 弄錯物件辨識碼可能導致資料損壞。

    Solution:將物件歸類為ENTITY如果它是透過辨識碼而不是自身的屬性來區分。使此辨識碼成為模型中其定義的主要依據。使類別定義保持簡單,並專注於生命週期的連續性和標識。定義一種區分每個物件的方法,無論其形式或歷史如何皆可依據該方找到想要找的物件。將需求中依據屬性匹配物件的要求改成依據辨識碼。定義一個保證為每個物件匹配產生唯一結果的操作,可能透過附加一個保證唯一的符號來實現。這種標識方式可能來自外部,也可能是系統為系統創建的任意標識符號,但必須與模型中的辨識碼相對應。模型必須規範物件相等的定義。

    ***

    VALUE OBJECT

    Forces:

    • 物件由它們的屬性定義。你只關心它們是什麼,而不關心它們是誰。
    • 紀錄物件的識別碼至關重要,但是將識別碼附加到每個物件身上可能會損害系統性能,增加分析工作並弄亂模型,使所有物件看起來都一樣。

    Solution:當你只關心物件的屬性時,將物件分類為VALUE OBJECT。使它表達其傳達屬性的含義並賦予它相關的功能。將VALUE OBJECT視為不可變。不要給它任何識別碼,並避免為了維護ENTITIES所需的設計複雜性。

    ***

    SERVICE

    Forces:

    • 領域操作(domain operations)本質上是活動或動作,而不是事物。
    • 領域操作無法被歸屬於某個ENTITY或VALUE OBJECT的自然職責時。

    Solution:在模型中增加一個操作,作為代表SERVICE的獨立介面。根據模型的語言定義介面,並確保操作名稱是UBIQUITOUS LANGUAGE的一部分。使SERVICE為無狀態。

    ***

    以上內容大多出自藍皮書,Teddy只是把格式重新調整,抓出Context與問題。以後看到ENTITY、VALUE OBJECT、SERVICE,鄉民們第一個想到的就是「設計領域物件嘿用得到」(這是它們的Context)。接著問題就是有哪幾種領域物件的種類?依據不同的forces,可以分成三種不同的領域物件。

    如果用這種方式去思考與記憶,Teddy覺得比較不會在藍皮書中所提到的一堆模式中迷路。

    ***

    動動腦

    同樣的內容,為什麼有些人可以用很有條理的方式讓別人聽懂,有些人卻講得非常冗長,讓人越聽越迷糊?!

    模式的六大格式是一種很好的收納知識方法,鄉民們可以自己練習一下,找幾個DDD書中其他模式,把它們的問題、解決方案,以及forces抓出來。

    練習過後會產生和吃「瀨尿牛丸」的效果,人都變聰明了!

    ***

    友藏內心獨白:練習把飯菜裝進六個格子的便當盒裡面。

    2019年12月3日 星期二

    泰迪軟體2020年上半年開課時間表

    Dec. 03 16:43~17:28

    ▲領域驅動設計與簡潔架構入門實作班課程照片 (原Clean Architecture實作班)


    時間過得好快轉眼就要跟2019說Bye Bye,又到了年底排課表的時間。2020年Teddy預計新開一門【行為驅動設計與實例化規格實作班】課程,開課時間大約在2020年8月之後。

    以下是泰迪軟體2020年上半年課表,原本的【Clean Architecture實作班】,因為課程內容包含許多領域驅動設計(Domain Driven Design;DDD),所以Teddy將課名調整成【領域驅動設計與簡潔架構入門實作班】。

    Scrum敏捷方法實作班

    • 假日班:2月22、23號(六、日)。
    • 假日班:5月9、10號(六、日)。

    看板方法與精實開發實作班

    • 假日班:3月21、22號(六、日)

    Design Patterns這樣學就會了--入門實作班

    • 假日班:3月7、8、14號(六、日、六)。

      Design Patterns這樣學就會了--進階實作班

      • 假日班:4月24、25、26號(五、六、日)。

      敏捷開發懶人包:物件導向技能

      • 平日班:3月24(二)。

      領域驅動設計與簡潔架構入門實作班(舊課程名稱為:Clean Architecture實作班

      • 平假日班:2月14、15、16號(五、六、日)。

      單元測試實作班

      • 假日班:4月11、12號(六、日)。

      例外處理設計與重構實作班

      • 假日班:6月13、14號(六、日)。

        軟體重構入門實作班

        • 平假日班:4月17、18、19號(五、六、日)


        ▼看板方法與精實開發實作班課程照片

        螢幕截圖 2017-12-12 10.08.45

        ▼「單元測試實作班」課程照片。

        螢幕截圖 2017-12-12 10.14.10螢幕截圖 2017-12-12 10.15.07

        螢幕截圖 2017-12-12 10.15.26螢幕截圖 2017-12-12 10.15.51螢幕截圖 2017-12-12 10.16.10

        ▼「敏捷開發懶人包:物件導向技能」課程照片。

        螢幕截圖 2017-12-12 10.11.38

        ***

        友藏內心獨白:2020年還請鄉民們繼續支持。