l

2018年11月21日 星期三

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

November 21 12:00~14:23

螢幕截圖 2018-11-21 09.56.20

▲Scrum敏捷方法實作班課程照片


時間過得好快轉眼就要跟2018說Bye Bye,又到了年底排課表的時間。以下是泰迪軟體2019年上半年課表,提供給鄉民們參考。2018年的新課程「敏捷開發懶人包:Clean Architecture嘴砲班」在明年將改版為兩天的「Clean Architecture實作班」,打嘴砲之餘也要不忘動手寫程式。


Scrum敏捷方法實作班

  • 假日班:1月26、27號(六、日)。
  • 假日班:4月28、29號(六、日)。

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

  • 假日班:1月19、20號(六、日)

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

  • 假日班:3月9、10、16號(六、日、六)。

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

    • 假日班:5月3、4、5號(五、六、日)。

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

    • 假日班:1月12(六)。
    • 假日班:5月18(六)。

    Clean Architecture實作班

    • 平假日班:4月19、20號(五、六)。

    單元測試實作班

    • 假日班:2月23、24號(六、日)。
    • 假日班:5月25、26號(六、日)。

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

    • 假日班:6月1、2號(六、日)。

      軟體重構入門實作班

      • 假日班:3月22、23、24號(五、六、日)


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

      螢幕截圖 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

      ***

      友藏內心獨白:2019年也要繼續努力。

      2018年10月24日 星期三

      此流程非彼流程

      Oct. 24 22:14~23:07

      螢幕截圖 2018-10-24 23.07.10

      ▲工作中的阻礙


      幾年前有一次機會參加一個行政團隊的sprint review與retrospective會議。這個團隊剛開始接觸Scrum,他們對於Scrum的理解是由公司內上過Scrum課程的同仁所傳授。在review會議中,同仁甲展示他的工作成果—召募新人流程。他將這個流程視覺化,並比較舊有招募流程與新流程的差異。

      Product Owner對於這個展示沒說什麼,倒是Scrum Master問了很多問題。Scrum Master以前是行政部門主管,跑Scrum之後轉為Scrum Master。

      ***

      Review結束之後,在retrospective會議Scrum Master請團隊成員各說出三個好的與三個有待改善的項目。

      同仁甲:我覺得Scrum Master要求我們將自己工作流程視覺化這一點很好,讓我比較容易看出現有流程有問題的地方。有待改善的地方就是關於校園招募這部分,我覺得吸引學生來填寫資料的誘因還不夠,這部分的流程以後還可以加強。

      就在每位同仁都發表意見之後,Scrum Master請Teddy提供一些建議。

      Teddy:我想請問你們知道retrospective會議的目的是什麼嗎?

      Scrum Master:知道啊,就是流程改善啊,讓我們可以越做越好。

      Teddy:你說的沒錯。請問各位同仁,你們剛剛所提出Good與Improvement的項目,是屬於需求面的改善,還是流程面的改善?

      此時安靜了幾秒,大家你看我,我看你,對於Teddy所提出的疑問,大家一臉黑人問號的感覺。

      Scrum Master:我不懂你的問題,我們剛剛提出來的的確是流程的改善。像是同仁甲就很明確提出他在校園招募流程方面的改善建議。

      Teddy:同仁甲,請問您的主要工作是什麼?

      同仁甲:我負責招募與其他人事方面的工作。

      Teddy:所以新人招募是你提供的服務,對嗎?

      同仁甲:這是我的工作,要說是我提供的服務也可以。

      Teddy:你們是行政團隊,不像開發團隊需要寫程式,做出可動的軟體。你們所提供的「服務」就是你們的user story

      Scrum Master:所以你是說,我們剛剛都在討論「需求的改善」?

      Teddy:沒錯。

      同仁甲:可是我們討論的明明是「流程改善」啊,以我來說,我談的是招募流程改善。

      Scrum Master:啊,我知道了。我們實作的「需求」,是對公司提供某種服務。我們討論的都是這些服務的流程,就好像軟體功能怎麼被使用的流程一樣,這是屬於需求的範疇。

      Teddy:沒錯。

      Scrum Master:我還是有一點不明白,retrospective所謂的流程改善,是什麼流程?

      Teddy:是團隊合作的流程,有什麼阻礙存在,讓團隊無法更快、更好的交付價值給客戶。

      Scrum Master:可以舉個例子嗎?

      Teddy:例如,我觀察到你們每個人所負責的工作彼此獨立,無法互相幫忙。這對你們來說會是一個問題嗎?如果有同仁請長假,他所負責的工作會不會無法進行?你們在提供服務的時候有沒有遇到什麼阻礙?是否很清楚用人單位的需求?會不會經常發生找到人被RD打搶等等問題。

      Scrum Master:如果撇開Scrum不談,難道我們不能找時間討論我們提供服務的流程嗎?為什麼要侷限在retrospective所規範的活動範圍?

      Teddy:團隊當然需要時間來討論供服務的流程,也就是你們團隊的需求。在Scrum框架中,你們可以在product backlog refinement workshop討論,也可以在sprint planning討論,但不適合在retrospective討論。

      Scrum Master:可是我就是不想被框架限制住啊。

      Teddy:你會在告別式的時候包紅包嗎?

      Scrum Master:啊?當然不會啊,我沒那麼白目。

      Teddy:那你為什麼要在retrospective討論需求改善呢?如果你在這個活動討論需求,請問你要在什麼活動討論「工作流程改善」?Sprint planning嗎?不會吧。

      Scrum Master:是不會啦…

      ***

      友藏內心獨白:先學會走再看看要怎麼飛。

      2018年10月22日 星期一

      Scrum Master的兩個魔咒

      Oct. 22 13:21~14:20

      螢幕截圖 2018-10-22 14.18.00

      ▲兩個搗蛋鬼


      Scrum「大濕」

      對於Scrum而言,Scrum Master是一個很神奇的存在。正所謂「好的Scrum Master讓你上天堂,不好的Scrum Master讓你住套房」。這個角色似乎成為Scrum成敗的關鍵因素,理論上你的Product Owner和開發團隊甚至整個公司一開始很爛都沒關係,在Scrum Master的輔助之下,透過持續改善的過程,Product Owner和開發團隊的不足之處都可以慢慢地變好。

      理論上…

      ***

      自組織魔咒

      Scrum的開發團隊是自組織團隊(請參考〈自組織〉),因此有些Scrum Master會採取所謂的「主動不做任何事」的模式,從旁觀察團隊。當團隊遭遇問題時讓團隊成員自行解決,既使解決的過程產生各種大大小小的失敗也視為學習所需付出的必要成本,Scrum Master儘量不要跳出來幫團隊解決問題。

      這一招對於已經具備「自我餵食」能力的團隊成員可能會很有效,但如果團隊成員尚未具備「自我覓食」能力之前就貿然將其放生,最後結果可能不是放生而是放死。從生物的角度來難,當個體還屬於幼年時期,需要的是更多父母親的照顧,然後在個體成長的過程中慢慢培養自組織的能力。

      曾經有朋友告訴Teddy,他離開Scrum團隊的原因居然是因為看不慣Scrum Master主動不做任何事的行事風格。團隊也想要自組織、靠自己的力量排除阻礙,但問題是團隊目前就是無能(尚未具備此能力),都跟你發出求救訊號你還置之不理,身為Scrum Master總不能只靠主動不做任何事這一招打通關吧?!

      ***

      寶媽魔咒

      為了讓團隊運作順暢,impediment removal(阻礙排除)佔了Scrum Master最多時間,這種情況在初導入Scrum的團隊中特別明顯。

      屏幕截图 2017-05-11 01.46.58

      ▲節錄自《Essential Scrum》,


      雖說Scrum Master需要幫助排除阻礙,但幫助不等於自己動手做,而是讓團隊具備自己排除阻礙的能力。有些過於積極與熱心的Scrum Master可能會認為處在「幼年期」的團隊尚未具備「自我覓食」的能力,如果放任他們自生自滅,將會落入自組織魔咒而無法自拔。因此Scrum Master開始扮演一位認真的新手媽媽,對孩子照顧的無微不至。

      在不知不覺中,團隊只要遇到無法解決的問題全部丟給Scrum Master幫忙處理,久而久之Scrum Master變成寶媽,而團隊成員則變成了媽寶。

      Teddy認識一位技術很強的Scrum Master,在團隊剛導入Scrum時扮演寶媽的角色,自己動手幫助團隊解決幾個關鍵的技術問題,讓團隊在導入Scrum初期,在兵荒馬亂的過程中增加關鍵穩定軍心的助力。而在團隊熟悉敏捷開發精神與Scrum框架之後,慢慢淡出舞台,切換到主動不做任何事的模式。

      ***

      沒有一定的形狀

      好的Scrum Master,沒有一定的樣子。不要看到別人主動不做任何事,以為回家後照做就會成功。別人的Context與你的Context不一樣,無腦照抄解決方案,到時候失敗再來哭哭討拍,抱怨Scrum不適合台灣人乃至整個亞洲人的特殊體質。

      套句PPT上鄉民常說的一句話:「正妹不是不給約,而是不給你約」。反思一下,這是正妹(方法)的問題呢,還是自己(團隊)的問題。

      ***

      友藏內心獨白:要先確定是不是正妹。

      2018年10月17日 星期三

      增進學習力的三個練習

      Oct. 17 22:13~22:47

      螢幕截圖 2018-10-17 22.09.28


      Teddy在北科上課時經常指定學生回家閱讀教科書或技術文章當作家庭作業,隔週上課再討論閱讀內容。大部分的學生並不擅長抓住內容的重點,閱讀經常只停留在字面上的涵義。

      Teddy不是什麼閱讀專家,但多年來發覺把握以下三個重點,可以幫助自己在閱讀技術文章時看到不同層次的問題,也可以提升自己的「教學力」。

      • 1. 定義:對於重要的名詞或概念,能否用簡潔的字句說出它的定義?例如,試著說出以下名詞的定義:多型(polymorphism)、迭代與增量(IID)、敏捷、Scrum、軟體架構、設計模式。
      • 2. 比喻:能否用一般人聽得懂的方式說明重要的名詞或概念?例如,用下圖的磨豆漿來解釋迭代與增量就比較容易讓鄉民們理解。

      螢幕截圖 2018-10-17 22.29.34

      ▲圖片節錄自 https://goo.gl/YgiMyr


      • 3. 找問題:名詞或概念通常代表某種產品或解決方案,也就是建築師Alexander所說的Form。學了一堆名詞與解決方案,如果不知道它們用來解決什麼問題,很容易發生吃錯藥的情況。就好像學了一堆design patterns但卻不知道每一個pattern要解決什麼問題,所以就很容易誤用pattern。

      有一個很簡單的自問自答練習,可以幫助自己發覺名詞與解決方案背後所要解決的問題是什麼。只要問自己:

      If X is the solution, what is the problem?

      例如:

      • If polymorphism is the solution, what is the problem?
      • If IID is the solution, what is the problem?
      • If Agile is the solution, what is the problem?
      • If Scrum is the solution, what is the problem?
      • If software architecture is the solution, what is the problem?
      • If the design pattern is the solution, what is the problem?

      ***

      只要把握住這三個簡單的重點,相信可以把技術文章看得比別人更透徹。

      ***

      友藏內心獨白:桌子要解決什麼問題?

      2018年9月19日 星期三

      擁抱改變,遠離Hard Code

      September 19 08:37~09:12

      Steve Jobs and the Apple Lisa

      ▲圖片來源在此


      寫死(Hard Code)

      幾天前一位朋友在Facebook上發問:「如何對非資訊人員解釋寫死(hard code)?」

      維基百科對於寫死的解釋如下:

      寫死(英語:Hard CodeHard Coding)是指在軟體實作上,將輸出或輸入的相關參數(例如:路徑、輸出的形式或格式)直接以常數的方式撰寫在原始碼中,而非在執行期間由外界指定的設定、資源、資料或格式做出適當回應。一般被認定是種反模式或不完美的實作,因為軟體受到輸入資料或輸出格式的改變就必須修改原始碼,對客戶而言,改變原始碼之外的小設定也許還比較容易。

      ***

      以上解釋,清楚明白,資訊人員一定看得懂,但對非資訊人員可就不好說。昨天Teddy在讀《溫伯格的軟體管理學:第一級評量》看到一個例子:

      一間荷蘭公司買了六台Apple Lisa電腦,想試看看能否推廣到整個實驗室使用。誰知Lisa的列印功能被寫死只支援美國標準規格的信紙,不支援歐洲標準規格的信紙,而且使用者也無法自行設定信紙大小(因為信紙大小寫死在程式中)。最後六台電腦全被退貨。

      ***

      適合(Fitness)

      在Lisa的故事中溫伯格提到:「一個系統換到新的環境,品質也會改變。……在某些美國人眼中Lisa是一種高品質的電腦。很少有歐洲人這麼認為。」。

      以上這個觀念可以用建築師Alexander的pattern框架來解釋,如下圖所示:

      螢幕截圖 2018-09-19 08.58.47


      ▲同樣的Form(Lisa電腦),移到不同的Context(美國或歐洲),原本的好品質/好設計,就可能變成爛品質/爛設計。所以Alexander說:「好設計是Form與Context的適合關係。」

      ***

      結論

      寫死的程式碼降低軟體系統(Form)適應不同Context的能力,只要使用的情境改變,原本可以動的程式或功能可能就無法使用。

      在大部分的情況下,開發人員請記住以下格言:

      擁抱改變,遠離Hard Code

      ***

      友藏內心獨白:什麼是Lisa電腦?

      2018年9月18日 星期二

      報恩

      September 18 08:58~10:39

      螢幕截圖 2018-09-18 10.38.19

      ▲窗外的浪浪吃飽就睡,何時會上演「貓的報恩」XD


      故事一

      好幾年前參與第一個Scrum團隊的產品開發,該軟體產品必須支援很多軟體與硬體平台,牽涉到韌體與驅動程式,還要與一些特殊的嵌入式系統溝通。這些軟、硬體平台數量眾多,不但經常改版,並且附贈不少bug。

      當時Teddy遇到一個很頭痛的問題:「怎麼設計軟體架構?」因為跑Scrum,不能用傳統瀑布式開發那一套,先花個幾個月收集需求,再花個幾個月設計架構。當時關於在敏捷開發中如何設計軟體架構的資料非常少,能找到的資料也只是提個大方向:「敏捷開發中軟體架構是隨著每個迭代週期長出來的」。

      在無計可施之下,Teddy想起念書時在物件導向分析與設計(OOAD)課程學到的RUP(Rational Unified Process;統一軟體開發流程)。RUP的三大支柱:Use Case DrivenArchitecture CentricIterative and Incremental Development(IID),是不是能在Scrum中使用?

      ***

      敏捷開發方法原本就是迭代與增量,把use case driven換成user story driven,如此一來套用architecture centric的作法似乎也是非常自然的一件事。

      RUP把軟體開發分成四個phase:InceptionElaborationConstructionTransition。在elaboration結束時大約完成最重要的百分之二十use case,此時軟體架構雛形也大致成形。聽起來很簡單,實際上要在Scrum中套用此原則也不難,唯一需要注意的一點是:「你怎麼知道這最重要的百分之二十use case(user story)是什麼?」。

      跑Scrum當然你會有Product Backlog,但這是一個內容隨時間異動的產品功能代辦清單。如果Product Backlog裡面只有接下來1~2個sprint所需要的詳細user story內容,有可能「看得不夠遠」,導致於軟體架構在每個迭代中不斷地(大幅度)修正。所以必須依據專案的特性,包含專案大小、上市時間、複雜度、不確定性等因素,自行判斷需針對這最重要的百分之二十的user story(百分之二十只是一個概念,不一定就是百分之二十,在敏捷開發中這個數字也許越低越好),需要做多少事前設計(up-front design),才能讓團隊的軟體架構成形。

      ***

      故事二

      N年前台灣政府砸錢推廣CMMI,當時Teddy還在念書,因故到校外上了介紹CMMI的課程。在學校也修了個人軟體流程(Personal Software Process),體驗了一學期「沒人性」的度量與改善之軟體開發方法XD。

      Teddy所認識接觸過CMMI的台灣軟體工程師,幾乎每一個人對它的評價都是「罵聲連連」。CMMI本意良善,可惜在台灣的落實方式變成一種快速拿牌的「文件化流程」。為了長官的績效,為了亮點,原本的精神所剩無幾,徒留形式。

      這一陣子Teddy花了一些時間閱讀溫柏格的《溫柏格的軟體管理學》這一套四本「老書」。溫柏格在書中提出「軟體工程文化模式」,包含以下幾個等級:

      • 模式0:渾然不知型的文化(Oblivious)
      • 模式1:變化無常型的文化(Variable)
      • 模式2:照章行事型的文化(Routine)
      • 模式3:把穩方向型的文化(Steering)
      • 模式4:防範未然型的文化(Anticipating)
      • 模式5:全面關照型的文化(Congruent)

      模式1~模式5基本上就對應到CMMI Level 1~CMMI Level 5。針對處於不同軟體工程文化模式的公司或團隊,遇到問題時有不同的反應方式。溫柏格這四本書利用幾個簡單的模型(model)來介紹他的軟體管理學,包含:系統性思考、軟體工程文化模式、控制模型、薩提爾的人際溝通模式。

      這四本書(中文版)加起來約2200頁,但因為以前 被迫 學過一點CMMI的皮毛,沒想到N年後居然出來報恩,讓Teddy比較讀得懂這一套書。

      ***

      結論

      有些人覺得從事軟體開發工作不須要念研究所,大學畢業就很足夠了。因為台灣的研究所教的內容與社會脫節,還不如早早出社會從實戰中學習。也有些人盲目念研究所,只因為鄉民都念了我沒念好像怪怪怪。

      不論哪一種情況,大學或研究所教育,雖然求學的當下看起來很多都跟「社會脫節」,但世事難料,就看每個人對於所謂的「社會」的時空定義是什麼。

      很多時候,基本功夫做好,才是伴隨自己一生的最佳夥伴。

      ***

      友藏內心獨白:溫故知新。

      2018年8月24日 星期五

      我沒有被盜帳號之Scrum新詩

      August 24 18:09~18:41

      螢幕截圖 2018-08-24 18.40.47


      好詩、好詩

      前幾天在搞笑談軟工Facebook社團貼了一首詩:

      我的目標

      我想要愛你,而不控制你;
      欣賞你,而非評斷你;
      與你一起,而不侵犯你;
      邀請你,而非強求你;
      離開你,無須多言歉疚;
      批評你,而非責備你;
      並且,幫助你,但不看輕你。
      如果,我也能從你那裡得到相同的,
      那麼,我們的相會就是真誠的,
      並且,會豐盈彼此。

      朋友看到嚇了一跳,以為Teddy被盜帳號。這首詩的作者是已故家庭治療大師Virginia Satir(維琴尼亞 薩提爾),出版於《Making Contact》。上面的翻譯是取自於簡中版《與人聯結》,以下為繁中版的翻譯,與簡中版稍微有點差異:

      我的目標

      我想要愛你,而不抓住你
      感激你,而不評斷;
      參與你,而不侵犯
      邀請你,而不要求;
      離開你,而不歉疚
      批評你,而不責備;
      並且,幫助你,而不是侮辱。
      如果我也能從你那裡得到相同的
      那麼,我們就會真誠地相會
      而且,豐潤了我們彼此。

      ***

      與人接觸

      讀到這首詩的第一個反應:「耶,這不是理想ScrumMaster的內心獨白!應該列為ScrumMaster必背新詩。」但後來想一想,不只是ScrumMaster,每個人都可以把薩提爾的「我的目標」當成自己的目標。

      如同《薩提爾的家族治療模式》中所提到:生存的姿態,不需要討好、指責、超理智和打岔;只需要一致。

      提高自己的價值感,保持一致性,你也可以達到薩提爾的目標。

      ***

      友藏內心獨白:所有的問題都是人的問題XD。

      好的理論就是最好的實踐

      August 23 23:28~24:00;August 24 00:~00:28

      螢幕截圖 2018-08-24 00.13.27

      ▲貼上封印的實務做法將使電腦無法洩露資料… (黑人問號???)


      施展不開的苦惱

      Teddy有一個很認真學習的朋友,有機會就到外面上課進修。最近這位朋友告訴Teddy他在學習上的一個困擾…

      朋友:我上了很多課程,尤其是實戰班,我都有好好的練習。只要我回公司之後,在工作上遇到的問題跟上課時所教的問題一樣,我就能夠處理。但是,只要稍微有點不同,我就不知道要怎麼處理。

      聽完朋友的敘述,Teddy的第一個反應就是—「你只是照著人家教你的特定招式練習,你根本沒有真的學會啊。」這種學習模式,只要情境稍微改變,原本罐頭式的解決方案很可能就派不上用場了,而你又不知該如何調整原本的罐頭,讓它在新的情境中派上用場。

      ***

      理論和實務

      理論和實務,經常被視為學習天平上的兩端。理論給人的感覺就是抽象、嘴砲、和社會脫節、無法實戰等。實務給人的感覺就是具體、立即可上手,就好像武俠小說中吃了天山雪蓮一樣,立刻增加一甲子的功力。

      實務就好像例子(example or instance),非常具體、容易理解且容易照做。如果實務所描敘的情境(context),與問題(problem)和你工作上所遭遇的相同,便可立即套用。但通常越具體、越實戰的實務,其適用的情境也越特定(越窄)。所以,同一種「類型」的問題,可能衍生出數種甚至數十、數百種例子。如果沒有理論基礎的支援,沒有建立分析問題的框架或模型,需要靠自己慢慢地累積各種實戰經驗,然後再抽象化成為自己腦中的解題模型。這是一個冗長的過程,很多人還沒走完這個過程就放棄了,永遠都在「學例子」,而沒有學到例子背後的共通理論基礎。

      ***

      建立收納知識框架

      這幾天在某本書(這幾天看的書比較多,忘了哪一本。應該是溫柏格的某本書中引用另外一個人的話,要再找一下)讀到一句類似的話:

      好的理論就是最好的實踐,因為它放諸四海皆準。

      真是太有道理了。如果你的學習過程,發現自己都在忙碌的收集流行術語,以及參加各種經驗分享,搞到最後自己越學愈心慌。此時就應該停下來思考一下,你有看到人家背後的理論基礎、框架或模型嗎?

      舉個Teddy自身的例子,Teddy博士論文的題目是「Java例外處理設計與重構」。一開始Teddy並不是研究這個題目,而是先研究pattern language,幾年後改研究design by contract裡面的contract specification。design by contract其實包含了contract specification與exception handling,但當時Teddy覺得exception handling太難,雖然有很多程式範例與所謂的best practices,但就是缺少一個理論框架,所以這一大堆例子與best practices在實際應用的時候經常互相衝突或不足夠完整解決問題。柿子挑軟的吃,所以Teddy一開始只研究contract specification。

      後來陰錯陽差,花了許多時間研究exception handling,也建立了一個理論框架(很簡單的理論XD)來解釋例外處理設計的問題。有了這個框架,分析與設計應用系統的例外處理就變得很有系統化。

      ***

      要怎麼從別人的教學中建立知識框架?最重要,也是最簡單的一點,就試看看教學者有沒有給你源頭參考資料。有些人強調自己的內容就是「原創」,但事實上這個世界真的「原創」的知識非常少,絕大部分都是建立在前人的知識體系上增加價值。好的實例,應該要建立在某些理論基礎之上。上課時可以不談這些理論基礎,但必須要提供參考資料,讓學習者課後有機會可以藉由進一步學習理論基礎來建立收納知識的框架以及培養自我解決問題的能力。

      小心「斷水流式」的第二手 (第或N手)知識傳遞,無法追源溯流的知識只能在非常特定的情況下使用,跟「呼名大法」(請參考〈自我感覺良好神功(1):呼名大法〉)相去不遠矣。

      ***

      友藏內心獨白:巨人知道你站在他的肩膀上嗎?

      2018年8月21日 星期二

      自我感覺良好神功(1):呼名大法

      August 21 09:14~10:16

      螢幕截圖 2018-08-21 09.18.24

      ▲前天在Facebook發了上面這則短文,有朋友跟Teddy反應,這文pH值太低,讓人看了「不蘇胡」,是不是又在暗中酸人?


      呼名大法

      ▼前天讀了《溫伯格的軟體管理學:第一卷》,p.73這段話,才知道「呼名大法(name magic)」這種說法。當下有感而發,改寫書中的句子才在Facebook貼了那段文。

      螢幕截圖 2018-08-21 09.23.24


      呼名大法讓Teddy想起很多往事。其一,多年前有一陣子design thinking很流行,有一次Teddy跟一位朋友開會,會議中對方不斷 呼叫 提到design thinking,好像它是一種解決任何問題的萬靈丹。因為Teddy才疏學淺,完全不知道design thinking是什麼,於是弱弱問了一聲:「什麼是design thinking啊?」

      沒想到對方突然停了三秒,然後笑笑地說:「其實我的專長也不是design thinking,而是service design」,就這樣結束這回合。

      類似例子不勝枚舉,有一次在會議中聽取簡報,報告者不斷強調:「我跟XXX和YYY(兩個中央政府單位)的關係非常好,我已經跟他們都談過了,把產品推到全國幾百個ZZZ單位絕對沒問題」。

      此時Teddy弱弱問了一聲:「請問你已經談好幾個單位了?」此時對方才說:「談過一個,但A、B還有C也都非常有興趣。」就這樣結束這回合。

      其他舉凡像是:買書不看書,然後告訴別人「啊,這本書我也有」;開口閉口必稱某某大神是你的老師或朋友;自稱年薪幾百萬的矽谷工程師;Google/Apple/Microsoft的員工(或前員工),大概也都有點呼名大法的味道。

      一言以蔽之,呼名大法就是A Name Without Quality(有名無實)。

      ***

      人人都會呼名大法

      雖然Teddy看似在批評呼名大法,但其實這個招式Teddy自己也常用(遮臉),相信大家也都用過。

      呼名大法的用途其實很多,包括:

      • 讓學習者自己心安,形成短時間增加大量能力的表象
      • 抬高身價,意圖使人覺得自己好棒棒
      • 跟上潮流,潮到出水
      • 增加聊天話題
      • 因為弄假成真而促成一些事情發生(可能是好事,也可能是壞事)

      成本低、效益大的好招式,不用嗎?

      ***

      破解呼名大法

      有一個很簡單的方式可以知道對方是真的懂,還是在施展呼名大法:請對方解釋「名字」的意義。大部分施展呼名大法的人這一關就過不了,但還是有些功力高強的人可以跟你扯上幾句。這時候只要再補上「為什麼」,就可以讓呼名大法現出原形。

      ***

      結論

      社會在走,「名詞」要有。技術日新月異,怎麼可能把所有的東西都學會?偶而施展呼名大法,可以讓對話順暢,而不糾結在一些非重點項目。但認真討論事情時,切記勿把別人的力量當成自己的力量,否則說得難聽一點,呼名大法就變成唬爛的一種形式。

      ***

      友藏內心獨白:先嚇嚇他。

      2018年8月20日 星期一

      薩提爾變革模型

      August 20 21:29~22:28

      螢幕截圖 2018-08-20 21.14.43

      ▲薩提爾變革模型,節錄自《溫伯格的軟體管理學:第四卷》 p.67


      薩提爾變革模型

      這兩年台灣談敏捷(Agile)的人與組織越來越多,嘴砲派、實務派、反對派、隕石派、佛系派等紛紛崛起。從狹義的軟體開發,到廣義的食、衣、住、行、育、樂,似乎萬事皆可敏捷。

      談敏捷,就不能不談改變。敏捷談的是靈活性,如何在不斷改變的環境中獲得成功。無論是個人還是組織,要增強對改變的適應性,就不得不回應改變,也就是自己也要持續改變。

      改變所帶來的成長總是伴隨著痛苦,因此變革失敗的例子不勝枚舉。在《溫伯格的軟體管理學:第四卷》中,介紹「薩提爾變革模型」,可以運用這個模型來分析變革應採取的行動。

      「薩提爾變革模型」指出發生變革的四個階段:

      • 近期現狀階段(舊有現狀):個人或組織的現況,通常表示某種穩定與平衡的成功狀態,大家都熟悉現有的做法。

      組織會一直停留在這個階段,一直到「有人」攪亂一池春水,才會打破現有的平衡。這個「有人」,通常是外來事件或外部人員,並不在系統控制者的控制範圍內。例如,外部顧問的加入、重要成員離職、競爭對手發布比我們更好的產品。

      • 混亂階段:既使組織想要推遲改變,但最終因為無法逃避的外部因素,導致只好承認現況無法應付未來的挑戰。之後系統進入混亂階段,原本熟悉的工作模式與方法不再適用,但新的做法卻還未被確定。在此階段人們嘗試各種可能性,甚至走回頭路尋找更早期的成功模式。
      • 整合與實踐階段:經過一段兵荒馬亂的時期,有些新的構想與方法存活下來,似乎可以應付新的挑戰。但組織還不確定,需要更多的實踐與改造,才能讓組織有效適應新的方法,提高組織的績效。
      • 新現狀階段:整合與實踐階段成功便進入新現狀階段,組織重新獲得平衡,不熟悉的工作模式變得熟悉。

      ***

      有什麼用

      這個模型告訴我們幾件有趣的事:

      • 牛頓運動定律說:「靜者恆靜,動者恆動」。組織停留在近期現狀階段的力量往往非常強大,由組織內部自發性所引發的變革往往十分困難。因為組織與個人會不斷地否定問題,迴避改變的必要性,這也就是薩提爾所說的熟悉總是比舒適更有力量。畢竟,待在舒適圈的力量真的太強,只要舒適圈依然存在,又何必做出改變呢。所以,要讓組織脫離舊有現狀,經常需要藉由外部力量來推動。
      • 當外部力量介入,組織正在嘗試找出新的工作模式時,此時的混亂階段不宜帶入更進一步的改變,否則組織將會因為無法接受過多的改變,因而放棄走回原本的老路子。例如,組織想要導入Scrum,在團隊剛開始接觸Scrum的前3~6個月內,已經被敏捷精神與Scrum框架搞得一個頭兩個大,此時若持續導入新的工程技術,例如TDD,可能使得團隊無法負擔,最後決定還是用原本的開發方式比較「有效率」。
      • 在整合與實踐後期導入新的變革會比在新現狀才導入要來得好,因為到了新現狀之後,不久新現狀就會變成組織的舊有現狀,此時引入變革的阻力又多了起來。

      ***

      結論

      鄉民們可以試著幫自己學習新事物或組織引入新方法的過程對應到薩提爾變革模型,看看目前處在什麼階段。如果一直處在舊有現況,是不是需要帶來一些外部衝擊,就算目前組織現況是「一攤死水」,好歹也可以引起一些漣漪。

      有些人很喜歡到處上課,有活動就參加,不吝惜投資自己。但會不會讓自己一直處在混亂階段,而沒有時間去沉澱與實踐所學的技能?

      這些都是值得思考的議題。

      ***

      友藏內心獨白:變革需要時間,就跟自己開發瀏覽器一樣。

      2018年8月15日 星期三

      為了快,你損失了什麼?

      August 15 14:33~16:14

      螢幕截圖 2018-08-15 16.15.02


      問題

      三不五時會聽到來自不同公司的朋友提起他們sprint planning meeting的進行方式…

      在會議進行的時候,我們分別請UX/UI設計師與程式設計師分組估算他們各自擅長的工作,以便減少會議的時間。反正雙方人馬都不懂對方的工作性質與內容,一起討論實在是很沒效率。

      這樣子做,好嗎?

      ***

      緬懷大師

      2018年8月7日,也就是一個禮拜前,軟體工程界大師Gerald M. Weinberg(傑拉爾德‧溫伯格)以85歲高齡過世。溫伯格一生寫了很多書,以生活化、輕鬆且風趣的筆法說明艱澀無趣的軟體工程觀念與方法。他的過世,著實是軟體工程界的一大損失。

      在溫伯格與Donald C. Gause合寫的《Exploring Requirements: Quality Before Design》(中文版《從需求到設計:如何設計出客戶想要的產品》)書中提到:

      發現什麼不重要,重要的是發現(探索)的過程…探索需求的工作事實上就是建立一個團隊。

      沒錯,探索需求的工作事實上就是建立一個團隊。只為了「快」就將Scrum團隊依據「專長」畫分成小組,讓小組各自討論得出估算值。這種做法只比讓專案經理或團隊主管一人制定時程要來得好一點,但卻失去了Scrum建議組成跨職能團隊(cross-functional team)的目的,變成「跨職能團隊中的元件小組(component group)」。

      ***

      大師開示

      在溫伯格的書中接著提到,若以下任一條件不符合,專案就很可能失敗:

      1. 了解需求要件
      2. (大多數都)貫徹始終參與專案
      3. 知道如何使團隊有效運作

      Exploring Requirements: Quality Before Design》這本書是1989年出版,距今29年前,相信那時候Scrum應該還沒有正式誕生。有跑過Scrum經驗的朋友請回顧一下,這三點是否也都包含在Scrum之中呢?

      ***


      友藏內心獨白:不需要做的事情,就不需要把它做好。

      2018年8月10日 星期五

      【敏捷開發懶人包:Clean Architecture嘴砲班】九月平日班首發團招生中

      August 10 14:00~15:20

      螢幕截圖 2018-08-10 15.19.07


      2018年最新課程

      俗話說「水清無魚、嘴賤無敵」,誰說嘴砲不能當一位好工程師?!對於身為技術主管或有志成為技術主管的你,沒時間寫code卻不能不跟上最新軟體架構潮流。

      你的需求Teddy看到了,經由Teddy濃縮再濃縮、提煉再提煉的【Clean Architecture嘴砲班】,最適合沒時間深入瞭解的你。由Teddy為你展示Clean Architecture的日月精華,再一起透過最後的精選Clean Architecture專案設計與程式碼評論練習,帶你邁向說得一口好程式的主管行列XD。

      ***

      課程大綱。

      • 軟體架構的定義與目的。
      • 從範例學整潔架構。
      • 整潔架構三原則:
        • 首部曲:分層原則。
        • 二部曲:相依性原則。
        • 三部曲:跨層原則。
      • 邁向Clean Architecture。
      • 嘴砲實戰練習:
        • 精選數個網路上實作Clean Architecture之範例專案,讓學員實際練習評論這些專案的架構設計。
        • 實作細節討論。
      • 回顧。

      ***

      課程效益

      • 一日之內掌握《Clean Architecture》(中文版《整潔的軟體設計與架構》)這本書的重點,讓別人誤以為你已經看完了整本書  為日後深入學習奠定基礎。
      • 了解架構審視(architecture review)所需關注的焦點。
      • 應用分層原則、相依性原則、跨層原則於自己的軟體開發專案中。
      • 透過多個clean architecture 專案的architecture review與code review實際演練,強化嘴砲 架構分析能力,

      ***

      課程費用

      • 原價NT$11,000元。
      • 首發團早鳥優惠: NT$8,900(2018年8月22日前報名並完成繳費)
      • 首發團2人團報,每人只需:NT$7,900。

      地點:台北市(近台北車站)。上課日2018年9月4日(週二) 09:30-16:30,共六小時 。

      image

      ***

      友藏內心獨白:意圖使人家覺得自己好棒棒。

      ***

      相關文章閱讀

      2018年7月27日 星期五

      阿嬤覺得你冷

      July 27 10:09~11:11

      螢幕截圖 2018-07-27 11.10.19

      ▲有一種趕,叫做司機覺得你趕


      前言

      有一種冷,叫做阿嬤覺得你冷。有一種敏捷,叫做長官腦中的敏捷。

      ***

      故事一

      去年年中有一位學員跟Teddy分享他們跑Scrum的經驗…

      學員:我們跑Scrum已經一年了,我對團隊的表現很滿意。

      Teddy:喔,怎麼說?

      學員:因為我們團隊的產能很穩定,可預測性很高。

      Teddy:你們是有經驗的Scrum團隊嗎?

      學員:不是,我們一年前才剛開始接觸Scrum。

      Teddy:所以你們新的Scrum團隊在這一年中的產能可預測性都很高?!

      學員:對啊,這一年來,團隊的velocity都是50個story points,只有一個sprint稍微低一點42個story points。

      Teddy:你們需求都沒改變嗎?

      學員:有啊,這就是我覺得Scrum好的地方,我們團隊可以很敏捷的擁抱改變又維持固定的產出。

      學員:有了穩定的產出我們做release plan就很簡單,照著計劃完成進度中的工作,沒什麼大意外,對老闆與客戶都很好交代。

      Teddy:這樣啊,你說你們在跑什麼,waterfall嗎?

      學員:不是啦,是Scrum!

      友藏內心獨白:啊不就好棒棒。

      ***

      後來經過側面了解,原來是他們公司大老闆在團隊跑Scrum之前曾經跟團隊精神喊話…

      大老闆:我們團隊有五個人,一個sprint兩個禮拜,每個人每天做一點(1個story point)應該不過分吧?

      從此之後大家的產出就變得很穩定了XD 。

      ***

      故事二

      幾年前有一位新創公司的老闆來上Teddy的Scrum課程,幾個月後在某個場合遇到他…

      Teddy:上完課之後你們回去有開始試跑Scrum嗎?

      老闆:有啊,而且成效很不錯。

      Teddy:喔,怎麼說?

      老闆:跑Scrum之後工程師都自願加班。

      Teddy:啊,自願加班?!

      老闆:對啊,以前專案時間是我估的,工程師抱怨說我估的時間太少,他們做不完,怪我逼他們加班。跑Scrum之後,時間都是團隊成員在sprint planning的時候估出來的。現在sprint結束之前user story做不完,團隊成員也沒話說,就會自願加班把沒做完的user story給做完。

      Teddy:我上課沒這樣教吧?

      老闆:是沒有,但是Scrum不是一種流程框架嗎,每個團隊可以依據不同狀況自行調整啊。我覺得我們現在這種調整很好。

      友藏內心獨白:啊不就好棒棒。

      ***

      結論

      這1~2年「敏捷」在台灣突然有一種大爆發、大流行的趨勢,各種活動很多,有興趣的人也變多。

      這種狀況,讓我想起電影達摩祖師傳中,達摩大師傳衣缽給慧可時對他說:「在我過世二百年後,衣缽傳至六祖,便不須再傳,因為在那個時候,禪宗法門已傳遍各地,不過,知道的人多而行道的人少,說理的人多而悟理的人少。」

      不過達摩大師最後說:「你不可輕視執迷不悟的人,任何人在一念之差,都會棄惡從善。」這種毅力,應該只有得道高僧能做得到。

      Teddy不是大師,只是工程師,離這個境界還差很遠。

      ***

      友藏內心獨白:那個…那個誰,給我一根棍子先。

      2018年7月6日 星期五

      Clean Architecture(6):架構三原則三部曲—跨層原則

      July 6 09:52~10:58

      螢幕截圖 2018-07-06 10.58.15

      ▲直接跨層XD


      前言

      將軟體架構分層並且確認相依性嚴格遵守由外往內(由低層往高層)的這兩個原則之後,接下來會面臨到另一個問題:「物件跨層時該怎麼辦?」。

      ***

      跨層範例

      ▼請參考下圖,AddHostController呼叫AddHost Use Case,它再呼叫Entity層的Host物件,並獲得一個Host物件。接著AddHost Use Case直接把Host物件往外傳給AddHostController。

      螢幕截圖 2018-07-06 10.05.10


      上面這個例子有兩件事情需要討論:

      • 內層物件可否跨層往外傳:舉例來說,位於Entity層的Host物件可以直接跨層(跨過Use Case層)傳給AddHostController嗎?依據相依性原則,上述情況還是有遵守「外層相依於內層」的規定,只不過AddHostController跨過Use Case這層相依於Entity層的Host物件。Teddy並未在《Clean Architecture》書中看到可否「跨層相依」的描述,而網路上國外鄉民所實作的範例,有些直接跨層相依,有些則是會將Host物件在AddHost Use Case轉過一次再傳給AddHostController(請參考稍後討論的Use Case雙向介面)。
      • 外層如何將資料傳給內層:假設AddHostController從瀏覽器收到使用者所填寫的「新增Host表單」,並將其內容轉成一個JSON物件。如果AddHostController直接將這個JSON物件傳給AddHost Use Case,將會破壞相依性原則,因為如此一來AddHost Use Case就相依於屬於應用程式框架的JSON物件。

      ▼直接把JSON從Controller往Use Case傳遞違反了相依性原則(假設JSON函式庫是由網頁應用程式框架所提供)

      螢幕截圖 2018-07-06 10.29.56

      ***

      定義雙向介面

      ▼如下圖所示,《Clean Architecture》書中建議Use Case需要定義「雙向介面」,簡單來說就是定義Use Case的Input與Output介面與參數的資料型態。

      螢幕截圖 2018-07-06 10.32.55

      Use Case本身提供Input介面與資料型別實作,外層的Controller要將參數傳給Use Case時,必須負責把參數型別轉成Use Case所定義的Input介面。

      Use Case的Output介面則由Presenter所實作(Presenter是Model-View-Presenter設計模式裡面的那個Presenter),呼叫Use Case時Controller會傳入Presenter物件,Use Case則將透過Presenter物件輸出資料。


      ▼看一個程式範例片段,HostController的getHosts函數呼叫FetchHosts Use Case得到所有host的列表,它首先產生HostListPresenter物件與FetchHostsInput物件,並將它們傳給FetchHosts Use Case。FetchHosts Use Case從FetchHostsInput物件獲得搜尋物件的參數資料,並將找到的資料傳給HostListPresenter。

      螢幕截圖 2018-07-06 10.40.21


      ▼FetchHostsUseCase介面定義

      螢幕截圖 2018-07-06 10.45.04


      ▼FetchHostsInput類別。請注意,如果嚴格依據《Clean Architecture》書中的圖示,應該先將FetchHostsInput定義成一個介面,然後再讓FetchHostsUseCase提供這個介面的實作。在此Teddy偷懶簡化這個步驟,直接將FetchHostsInput設計成一個具體類別。

      螢幕截圖 2018-07-06 10.45.49

      ▼FetchHostsOutput介面

      螢幕截圖 2018-07-06 10.48.20


      ▼HostListPresenter

      螢幕截圖 2018-07-06 10.49.15


      ▼FetchHostsUseCase實做

      螢幕截圖 2018-07-06 10.52.54

      ***

      結論

      《Clean Architecture》整本書雖然有多達34章,如果可以掌握分層、相依性與跨層這三個重點,在實作Clean Architecture時應該就沒什麼困難之處。

      ***

      友藏內心獨白:還有一個Missing Chapter沒討論…

      2018年7月5日 星期四

      Clean Architecture(5):架構三原則二部曲—相依性原則

      July 5 16:17~17:23

      螢幕截圖 2018-07-05 17.21.14


      前言

      軟體架構依據「距離I/O遠近」分層之後,接下來遇到一個問題:「如何管理各層之間的相依性?」。在《Clean Architecture》書中,把這個規則稱為相依性原則(Dependency Rule)。

      ***

      低層相依於高層

      《Clean Architecture》書中所定義的相依性原則只有如下的短短一句話:

      Source code dependencies must point only inward, toward higher-level policies. (程式碼相依性必須只能往內,指向更高層級的策略。)


      ▼如下圖所示(圖片來源在此),內圈(較高層級)的元件不能知道(相依)任何外層的元件。也就是說,外層的函數、類別、變數或任何有名字的軟體實體,都不能出現在內層的元件之中。相依性只有一個方向,就是由外往內,由低層往高層。

      CleanArchitecture

      ***

      煩人的實作細節

      相依性原則本身非常簡單,但實務上在系統中要完全落實此原則有許多細節要注意。

      ▼例如下圖中位於Entities層(最高層)的Host類別,依據相依性原則它不能相依於任何位於此層以外的「任何東西」。為了將Host物件儲存於資料庫中,Teddy使用了javax.persistence package裡面的annotation(@Entity、@Table、@EmbeddedId、@Column等)。

      螢幕截圖 2018-07-05 16.34.14

      雖然這些annotation是 Java Persistence API(JPA)標準的一部分,但它們的實作是由Hibernate所提供。嚴格來說,上面的程式違反了《Clean Architecture》的相依性原則。

      如果不用annotation,也可以用XML檔案來註記,把對hibernate-jpa-2.1-api的相依性從原始碼中移除。但廣義的來講,雖然在原始碼中Host不直接相依於hibernate-jpa-2.1-api,但透過XML設定檔案還是間接的相依於hibernate-jpa-2.1-api,Teddy認為兩者效用實際上是差不多,只是把「顯性相依」轉成「隱性相依」,並沒有好到哪裡去,甚至更糟糕。

      ***

      要完全把Host對hibernate-jpa-2.1-api的相依性拿掉,一個常見的作法是定義另一組針對持久化(Persistence )所需的物件,例如針對原本的Host物件的持久化需求另外定義一個HostEntity類別,如此一來原本Host類別中JPA annotation就可以移到HostEntity之中,然後再透過Hibernate把HostEntity直接存到資料庫。

      但這種做法又衍生另其他問題,首先,必須另外撰寫物件負責把Host轉成HostEntity,以及把HostEntity轉成Host。這種物件稱之為Mapper

      其次,HostEntity要擺在哪一層也是需要考慮一下,很顯然不會擺在Entities這一層。因為Repository通常被Use Case所使用,所以放在Use Cases層似乎很合理:當要儲存Host時,Use Case先產生或是獲得一個Host物件,然後呼叫Mapper把Host轉成HostEntity,在透過Repository將HostEntity存到資料庫。反之,要讀取Host時,Use Case透過Repository從資料庫讀取HostEntity,再把它轉成Host。

      但是這麼做其實還是違反了相依性原則,因為Use Case相依於外部的hibernate-jpa-2.1-api。忙了大半天其實是白忙一場XD。

      ***

      另一種作法是,不透過任何JPA annotation來簡化物件永久化的問題,只定義Repository介面,然後透過main元件注入Repository介面的實作。Repository介面的實作程式碼位於Interface Adapter層,也就是《Clean Architecture》架構圖裡面的Gateways。它再透過相依性注入的方式,獲得不同持久化框架的實作,如此一來便符合相依性原則。

      但是,原本只要貼一貼annotation就可以把透過持久化框架(例如Hibernate)達到持久化的目的,現在為了嚴格遵守相依性原則,程式碼變得麻煩好多。這就是在實作上必須注意與取捨的地方。

      ***

      結論

      滿足相依性原則可以獲得兩大好處,首先,因為高層的物件不再相依於框架等低層的物件,所以測試碼可以單獨測試,大幅簡化測試的工作。

      其次,系統的核心功能位於Entities與Use Cases這兩層(蛋黃區與蛋白區),要更換I/O或是應用程式框架「理論上」變得簡單很多。例如,如果要將Web-Based UI換成Android App,只需異動最外面兩層(Framework & Drivers與Interface Adapters),便可直接銜接原本的Use Cases與Entities。

      ***

      友藏內心獨白:跟有潔癖的人住在一起家裡肯定很乾淨,但你可能會被對方煩死。

      2018年7月4日 星期三

      Clean Architecture(4):架構三原則首部曲—分層原則

      July 3 14:38~15:58

      螢幕截圖 2018-07-03 16.08.32


      前言

      《Clean Architecture》這本書一共有34章,全部讀完也是有點累。今天Teddy幫鄉民們整理一下重點,總地來講Teddy認為Clean Architecture有三個最重要的原則,將分三集逐一介紹這三個原則。今天先談「分層原則」。

      ***

      階層式架構

      軟體架構就是軟體的形狀(shape),而形狀是由多個元件及其互動所構成。這些元件通常會依據其功能加以分類,以便於管理、擴充與維護。


      階層式架構就是一種很常見的分類方法,常見的階層式架構長成下面這樣 (詳細說明可參考https://goo.gl/Tjq75M):

      螢幕截圖 2018-07-03 14.55.57


      既然稱為階層式架構,一定有上、下層之分。請問上圖階層式架構中,誰是上層、誰是下層?

      一般直覺的看法:Presentation Layer畫在架構的最上方,所以它是最上層,而Database Layer在最下方,所以它是最下層。這種解讀有一個問題,因為在階層式架構中,越上層的人(元件)通常擁有越核心的商業邏輯(business logic)。如果Presentation Layer是最上層,那豈不是代表它擁有最核心的商業邏輯?這也不對啊,因為大家都知道,儘量不要在Presentation Layer放置商業邏輯,因為那將使系統擴充、維護與測試變得更加困難。

      ***

      定義高層與低層

      《Clean Architecture》書中關於分層有一個非常明確的定義:「離I/O(輸入、輸出)越遠的元件層級越高,離I/O越近的層級越低」。這其實也很容易理解,在公司中,櫃台小姐離I/O(接電話、接待訪客)最近,通常層級比較低。董事長、總經理離I/O很遠,層級最高(通常看高階主管的辦公室位置離大門遠近就可猜出層級高低XD)。

      ▼Port and Adapter不把階層式架構畫成常見的垂直形狀,而是畫成圖1中的六角型。

      螢幕截圖 2018-03-15 17.39.22


      ▼《Clean Architecture》書中則是畫成同心圓(圖片來源在此)。

      CleanArchitecture


      ▲上圖中,蛋黃區(Entities)是架構中層級最高的一層,而最外圈屬於I/O層,是層級最低的。

      《Clean Architecture》書中有四個預設的階層,分別是:

      • Entities:也就是傳統物件導向分析與設計所說的domain model object。
      • Use Cases:Entities這一層存放著核心商業邏輯,也就是在這個領域中,不同應用程式都用得到的物件。而Use Cases則代表應用程式邏輯,也就是應用程式的功能。Use Cases扮演著controller的角色,呼叫Entities或是Repository物件提供應用程式對外的服務。
      • Interface Adapters:將外部資料與呼叫介面透過此層轉呼叫Use Cases,如此一來Use Cases就可以與I/O或是應用程式框架無關。
      • Frameworks and Drivers:此層包含了應用程式框架,例如如果Java程式使用了Spring Framework,則Spring Framework就位於這一層。資料庫,或常見的MVC Framework也都位於這一層。通常大家在這一層所寫的程式都只是為了把應用程式框架與內部的Interface Adapters或Use Cases串起來的膠水程式,鮮少有複雜的商業邏輯會位於這一層。

      ***

      結論

      依據「元件距離I/O遠近」分好層級之後,高、低層之間的界線就非常的清楚。層級分明之後,接下來衍生出另一個問題:每一層之間的相依性要怎麼管理?如果層與層之間的相依性沒有好好管理,僅僅是分層你的架構還是很可能會一團亂。

      下一集「相依性原則」將說明這個問題,下次見。

      ***

      友藏內心獨白:真正的高層都是坐在離I/O很近的大門口XD。

      2018年7月3日 星期二

      LG gram 15Z980-R.AAS9U1 (2018) Amazon 購買與使用心得(下)

      July 3 09:39~11:45

      螢幕截圖 2018-07-03 11.43.37

      ▲LG gram 15吋比MBP15吋略寬、長度略短


      開箱

      ▼快遞送來時的箱子。

      螢幕截圖 2018-07-02 22.59.18


      ▼打開後有點傻眼,白色的紙箱上居然有很多黑色的指紋。

      螢幕截圖 2018-07-03 09.42.07


      ▼而且很明顯地筆電的封條已經被拆開,這種情況只有兩種可能:(1)拿到別人退貨的商品;(2)商家自行拆封安裝RAM與硬碟。不管是哪一種情況,至少也把盒子擦乾淨一點吧…Orz。

      螢幕截圖 2018-07-03 09.44.00


      ▼打開盒子。

      螢幕截圖 2018-07-03 09.47.30


      ▼內裝很單純:筆電、電源線、一條無三小路用的USB-A轉100M的網路線。這肯定是清庫存,都什麼年到了還配100M的有線網路,直接用WIFI還比較方便。有線網路好歹也給個1G吧。

      螢幕截圖 2018-07-03 09.50.36


      ▼用單手就可以輕鬆打開上蓋。

      螢幕截圖 2018-07-03 09.55.21


      ▼鍵盤的排列方式,沒有注音符號好像比較清爽一些。

      螢幕截圖 2018-07-03 09.56.34


      ▼開機,第一次開機會執行Windows 10安裝。這是Teddy第一次買Windows 10筆電,之前都是在MBP中安裝Parallels跑Windows 10。

      螢幕截圖 2018-07-03 09.57.49


      ▼安裝過程就不用看了,這是筆電內建的兩顆SSD硬碟。查了一下型號是海力士的M.2硬碟

      螢幕截圖 2018-07-03 10.00.08

      ***

      始用狀況—優點

      這台筆電主是Teddy帶出門上課使用,平時在家裡還是用原本的MBP。筆電有兩顆512G SSD,C碟裝系統,D碟裝資料。Teddy把Dropbox設到D碟,目前空間分配還夠用。雖然內建的SSD速度並不是特別快,但Teddy也沒要用它做什麼偉大的事,暫時就先這樣。

      把軟體都裝好後,還沒有機會帶它去上課。先說一下目前的使用感覺,先看優點:

      • 重量非常輕。這也是Teddy購買它的主要原因之一。
      • 續航力(理論上)應該很長。官方數據是16.5小時,打個五折至少也可以用的8小時。目前還沒機會帶去上課,過一陣子在報告實際使用續行狀況。
      • 開機速度很快,從按下開機扭到登入Windows約需20~25秒。從睡眠狀態按下電源鍵不用3秒就可喚醒(真的有在睡眠嗎?!)。
      • 電腦機身不會很燙,拔掉電源之後放在大腿上使用都OK。
      • LG 的軟體做得很好,重裝Windows之後只要下載LG Update Center軟體,就會自動幫你抓所有的驅動程式。
      • Windows 10的手勢操作,在切換虛擬桌面這一點和MacOS很類似(這可能是Teddy最常使用的手勢XD),所以原本在MBP上的「上課使用體驗」:一個桌面開PowerPoint秀簡報、一或多個桌面開IDE看程式碼、一個桌面開時鐘倒數計時,換到Windows 10筆電還是差不多。
      • 喇叭音效還不錯(沒有MBP好但也不錯了)。
      • 開啟一個130頁的PowerPoint只要二點多秒,播放投影片中嵌入的影片或外部連結影片也都很順暢。
      • 效能不是頂尖但尚可接受。LG gram開啟IntelliJ專業版約需16秒,MBP則只需10秒多一點點。LG gram的速度比MBP慢可能是SSD速度的關係,不過也還在可以接受的範圍。目前還沒有在LG gram寫程式的機會,日後有機會在分享coding的感覺XD。
      • 可重複使用type-c轉接器。原本給MBP使用Apple原廠的type-c轉VGA + type-a + type-c充電轉接頭,接在LG gram的Thunderbolt 3 type-c連接埠上可以投影。

      螢幕截圖 2018-07-03 10.58.57


      接上Teddy原本給MBP使用的CalDigit Thunderbolt 外接盒之後,可以支援雙外接螢幕顯示。


      • 支援Thunderbolt 3 type-c連接埠充電。在筆電送來的第一天,就被Ada給整台踢到桌下。螢幕背蓋刮了一條痕跡,非常纖細的充電器接頭也因此斷掉了…Orz。還好可以透過type-c連接埠充電,不然Teddy真的要哭哭了。

      螢幕截圖 2018-07-03 11.02.00


      ▼當事貓在此,可能要教導Teddy世事無常,不可入相的道理,所以每天努力地搞破壞。

      螢幕截圖 2018-07-03 11.04.45


      • 觸控螢幕功能可透過軟體關閉。觸控螢幕雖然方便,但有時候不小心碰到反而造成困擾。不想使用這個功能可以透過軟體關閉觸控螢幕。

      ***

      始用狀況—可以更好

      接下來談一下Teddy認為還可以更好的地方:

      • 觸控板小小一塊,雖然堪用但按下去「咖咖」的聲音和MBP的觸控板比起來差了一截。
      • 亮面觸控螢幕,稍微手碰一下就會在螢幕上留下痕跡。
      • 不知道是不是輕薄筆電的緣故,Teddy覺得LG gram的USB type-a與type-c連接埠在拔插時都很緊,要用點力。
      • 內建的SSD如果可以用料好一點,選用速度比較快的硬碟就更好了。
      • 內建的HDMI應該是 HDMI 1.4(規格書沒寫,Teddy也查不到),實際測試結果只可輸出4K 30Mz。

      ***

      結論

      Teddy沒有用過其他Windows 10的筆電,也許其他筆電也有相同的優點但Teddy無從得知。所以Teddy的評論只可視為從MBP轉移到LG gram的一種感受,同時具備輕薄與長效這一點目前看起來是無庸置疑的。

      但也許等Teddy開始在LG gram上面寫程式,又會嫌它速度太慢也說不定XD。

      ***

      友藏內心獨白:魚與熊掌何時才可兼得?!