l

2012年1月31日 星期二

什麼是物件導向(4):Inheritance

January 30 19:27~20:45

終於來到物件導向觀念介紹的最後一集inheritance(繼承),且看課本第57頁的定義:

If class B interits class A, then both the operations and the information structure described in class A will become part of class B.

接著課本解釋幾個與inheritance相關的名詞:

  • Generalization:一般化,把好幾個不同的classes共同的特性抽離出來集中放到一個class中,然後讓原本的那些classes去繼承這個新的class。這種過程叫做generalization。感覺有點botton-up的方式來建構繼承架構。
  • Specialization:特殊化,這個名詞一聽就知道跟generalization相反,也就是說假設鄉民們要新增一個class到現有的系統中,先找到一個既存的class其功能與資料和這個準備新增的class類似,然後讓這個準備新增的class去繼承原有的這個class,然後在這個新的class身上增加專屬於他自己的行為或資料。一個被特殊化的class其行為已經跟他的祖先不同了,換句話說,特殊化違反了Liskov Substitution Principle
  • Ancestors:祖先,在一個繼承架構中,某個class A之上的所有classes稱之為A的祖先。Ancestors又稱作superclasses(父類別)。。
  • Descendants:後代,在一個繼承架構中,某個class A之下的所有classes稱之為A的後代。Descendants又稱作subclasses(子類別)。
  • Direct descendant:直屬後代,直接繼承自某個class A的那個class稱之為class A的direct descendant或是child。
  • Direct ancestor:直屬祖先,若class A為class B的direct descendant,則class B就稱為class A的direct ancestor或是parent。
  • Abstract classes:祖先類別在設計的時候,其主要目的若是要讓其他類別繼承,則我們通常稱這樣的祖先類別為abstract classes。關於這一點雖然課本上這樣解釋,但是實務上我們會說一個無法產生instance的class就稱之為abstract class。
  • Concrete class:和abstract classes相反,一個類別其設計之主要目的就是要讓人產生instance,則稱此類別為concrete class。實務上只要是能產生instance的類別都稱之為concrete classes。

***

這在邊Teddy先插花補充一的觀念,雖然在課本中並沒有提到,但是現在鄉民們可能都知道inheritance分成兩種:

  • Implementation inheritance:實作繼承,子類別繼承父類別的介面以及實作。
  • Interface inheritance:介面繼承,子類別只繼承父類別的介面。

接下來回到課本的內容,課本提到使用inheritance的四種時機:

  • Reuse:透過implementation inheritance重複使用祖先類別中的行為與資料。剛開始學OO的人會認為reuse是使用繼承的主要目的,當年Teddy也是這樣認為,後來慢慢懂事之後,才發現如果光是為了reuse而使用繼承並不是一個好主意。且看GoF的Design Patterns第20頁告訴鄉民們:Favor object composition over class inheritance
  • Subtyping:一個類別(class)被視為某個型別(type)的實作就稱為subtyping(所以interface inheritance就是一種subtyping)。課本第64頁有講到一個重點:Subtyping normally occurs if the inheritance performs only an extension, rather than overriding something already defined in the ancestor.
  • Specialization:前面已經解釋過,一個類別被特殊化之後,其行為已經跟他的祖先不相容了。有時候使用特殊化目的是因為後代類別與祖先類別大部分的行為都很相似,但是有少數幾個行為不同(可能後代增加新的行為,或是移除祖先的某些行為)。因為特殊化違反了Liskov Substitution Principle,所以使用特殊化的程式通常會看到instacne of 之類的判斷式(無法做polymorphism)。
  • Conceptual:概念化,因為「概念上」某個類別屬於另外一種類別的後代,所以就使用了繼承。例如,人和狗都是一種動物,所以人和狗都繼承自動物這個類別。

這四種使用繼承的理由並非互斥的,例如,可能因為reuse的原因而套用subtyping或是specialization。根據課本的說法,subtyping是一種使用繼承比較好的理由。但是如果依據Design Patterns的說法:Favor object composition over class inheritance,吃飽沒事就不要用(實作)繼承了,但是介面繼承多用倒是無妨

***

友藏內心獨白:今天中午吃得好飽。

2012年1月30日 星期一

Scrum 是什麼(11):不信邪之流程改善精神

January 29 22:21~23:24

image

 

前情題要:

 

Teddy在「Scrum 是什麼(9):Retrospective Meeting」這一篇介紹了三種流程改善的思考方向,其實說到底廣義的流程改善也好,或是狹義的實施Scrum與agile practices也罷,都需要有一種「傻的願意相信」外加「不信邪」的精神。「傻的願意相信」的觀念Teddy已經提過好幾次了,大意是說書上教授的軟體工程方法,鄉民們自己要先「傻傻地願意相信」這些是可以奏效的方法,先嘗試照著去做,而不要在學會之前就先急著去否定這些方法。

然而,傻地願意相信只是第一步,因為有時候就算是真的傻傻地照著書本上所教的方法去做,實務上還是會遇到很多困難,導致於無法達到書本上所說的那種效果。例如,幾乎所有軟體工程與敏捷方法的書都告訴鄉民們「要寫自動化測試,要寫自動化測試」,老師在講鄉民們有沒有在聽 ?沒有嘛(翻桌)。不過這也不能怪鄉民們,實務上團隊就是沒有編列「testers」這種標準配備啊,自動化測試要叫誰寫 ?好吧,山不轉路轉,沒有testers就請programmers自己寫吧。問題又來了,programmers要嘛就是說不知道怎麼寫自動化測試,要嘛就是直接嗆說不爽寫,還有些PM(專案經理)會跳出來阻擋,理由是「寫code都來不及了哪有時間寫什麼自動化測試啊」。

正所謂「天將降大任於斯人也,必先苦其心志,勞其筋骨,餓其體膚,空乏其身,行拂亂其所為(難怪Scrum Master當久了很容易起肖),所以動心忍性,增益其所不能。」 遇到這些阻礙也當屬正常現象,請安心服用。所以,「傻的願意相信」的下一步,就是要有「不信邪」的精神。老子/老娘就不信沒有tester就寫不了自動化測試;有了這樣的覺悟,假以時日團隊自然會找出改善之道。

約十天前Teddy在寫「Single Code Base」時,把Extreme Programming Explained: Embrace Change, 2nd這本書關於Single Code Base的解釋又讀了一次,在68頁作者寫了一段話讓Teddy感觸良多:

If you have a legitimate reason for having multiple versions, look at those reasons as assumptions to be challenged rather than absolutes. It might take a while to unravel deep assumptions, but that unraveling may open the door to the next round of improvement.

***

當Teddy在開發團隊中扮演Scrum Master角色的時候,心中日思夜想的事情都是如何改善團隊的軟體開發流程。為什麼這個sprint產生的bugs特別多,為什麼bugs沒有被自動化單元測試與自動化功能測試給找出來,為什麼有一個版本的安裝程式根本無法執行,為什麼與平台相依的專案(native projects)無法在持續整合系統上面自動被建構,為什麼... ?

這麼多為什麼,也許都可以用一句「人力不足」或是「時程太趕」來交代過去,但是這樣的話就談不上什麼向上提升,只能祈禱不要向下沉淪就該偷笑了。

「基礎practices達成度」、「進階practices達成度」、「消除浪費」這三點已經幫Scrum團隊樹立了許多改善的方向或是目標,然而要如何接近這些目標每個團隊卻是要依據自己的現況與組織的文化自行調整。達成目標的過程可能很漫長,但只要抱持著不信邪的精神,Teddy相信改善的效果總是會逐漸顯現。

***

下一集:〈Scrum 是什麼(12):不要再用focus factor與unplanned items了

***

友藏內心獨白:清宮劇裡面不是常常都說要「想輒」嗎,沒輒的時候還是要想輒,這就是一種改善的精神...XD。

2012年1月29日 星期日

Scrum 是什麼(10):時程估算

January 28 23:03~January 29 00:20

螢幕截圖 2015-06-11 23.48.17

前情題要:

 

Scrum的大小活動大致上算是都交代過一遍了,今天談一 下幾天前學妹在Facebook上問Teddy的一個問題:時程估算。

***

學妹:最近我們常常被問到關於時程估計的問題,尤其是之前沒有run過Scrum的團隊,他們會想知道假設客戶一個案子來了,要怎麼去估算時間跟報價呢。我們用自己的經驗回答了,但總覺得回答得不夠有說服力。很想請教學長在這方面有沒有相關經驗可以跟大家分享呢? 謝謝!!

Teddy:很簡單啊,請問你問題的人跟Teddy聯絡...不是啦,這個問題不容易回答,基本上agile是建議不要採用「固定費用的合約」,但是實務上目前很難能夠被客戶接受。再加上如果團隊沒有run過Scrum不知道自己的「速度(生產力)」那就更難估了。你都怎麼回答別人?

學妹:這問題其實是上次學長講座結束後,後續留資料跟我們接觸的廠商訪談時候提出來的XD。首先,我們是講說通常一個有經驗的scrum團隊開發速度會趨穩定,這時候可以根據這樣的速度做估計。如果沒有經驗的話,會請他們用Commitment Based的方式,變成邊做邊調整,並且預留buffer,可是留buffer又牽扯到報價的問題。而且對方是表示對他們接案為主的小公司來說,這樣真的滿難的。所以討論到最後,對方說可能先從自己有興趣沒時程壓力的案子先run看看。我自己覺得我們回答的不好,所以最近才在想這個問題有沒有好的做法 ~"~

Teddy:要回答這樣的問題其實也很簡單,最保險的作法就是看他們原本怎麼估,就怎麼估。然後用SCRUM想辦法在估算的時程內把案子做出來。以這種方式多做幾次就會越估越準,不用說去找什麼「沒有時程壓力的案子來試SCRUM」。

學妹:哈哈哈 這樣一說突然覺得很有道理耶XD 突然想起學長寫的「Scrum 不會幫你解決問題」這篇。我想我自己也陷入那種想用Scrum幫大家解決所有問題的迷思了XDDD 謝謝學長,我會再多想想的!!

***

Teddy覺得學妹原本的回答已經很得體了。時程估算在軟體開發中本來就是一件困難的事情,問什麼 ?很簡單,因為變數太多了啊。有什麼變數?

  • 需求會變
  • 開發團隊成員會變
  • 技術會變

但也不能說因為變數太多所以就什麼也不估。估算的結果通常有兩種:「不準」以及「非常不準」。對於一個剛開始想要採用Scrum的團隊,如果客戶還是只願意用傳統的固定價格合約的方式來進行專案,那麼案子還是可以做。也沒甚麼好害怕或是擔心的,採用Scrum並不是進京趕考「一試定終身」,也不是做數學四則運算考題,第一次就要算出所謂的「正確答案」才算是成功。Scrum(所有的敏捷方法)都是一種逐步改善的過程,先把箭射出去了,再看看箭離標靶有多遠,然後修正後再射箭...縱然標靶本身並非是固定不動的(活動標靶),但依此精神長久下去所射出的箭總是慢慢地往標靶靶心靠近。

沒錯,「Scrum 不會幫你解決問題」,江湖上沒有什麼大還丹或是天山雪蓮之類的補品,吃一口就可以平白增長數十年功力。只有「傻的願意相信」,勇敢誇出第一步,然後邊走邊修正(果真如Kent Beck大叔所說的,軟體開發就跟開車是一樣的道理)。

Robert L. Glass在Facts and Fallacies of Software Engineering第31頁寫了一段大家都知道的事實:

Most software estimates are performed at the beginning of the life cycle. This makes sense until we realize that estimates are obtained before the requirements are defined and thus before the problem is understood. Estimation, therefore, usually occurs at the wrong time.

Scrum能帶來的好處,是把「計畫」這兩個字從名詞變成動詞。Scrum團隊隨時都在計畫,隨時都在調整,眼睛隨時都盯著標靶前進。Teddy前面提到的三個影響需求估算的變數,第一點「需求會變」這幾乎是無法改變的事實,所以Kent Beck大叔又告訴我們要「擁抱改變」。在Scrum的設計中,專屬的Product Owner與Scrum Master,舉辦Sprint Planning Meeting、Daily Scrum、Sprint Demo等活動,以及自動化測試、refactoring等作法,都算是用來「擁抱改變」的方法。

至於另外兩點變動因素「團隊成員會變」與「技術會變」,還是要靠「Sustainable Pace」以及「Shared Code」與「Pair Programming」等實務作法,讓提升團隊合作的能力,並且讓團隊成員有餘力可以讀書與自我成長(Sustainable Pace是很重要的)。

***

講了一堆,其實講再多鄉民們不願意去嘗試也沒用。軟體是動手做出來的,開發軟體是一種逐步改善的活動,所以,不要怕第一次估算沒做好就裹足不前。因為這就跟追女朋友一樣,不開口機會永遠是零。考慮東,考慮西的,最後又回到原本每天加班的老方法上面。團隊是否一開始就可以馬上實施「正統的Scrum」並不是重點,重點是這一狗票的敏捷方法(例如XP與Scrum)與敏捷實務作法(例如自動化測試、持續整合、Pair Programming等等)有那一些是可以拿來改善軟體開發流程,能用多少就算多少。而且要記得「開發軟體是一種逐步改善的活動」,不是說那一天心血來潮隨便挑一個敏捷實務作法來試一下乎弄過去就沒事了,而是要依據團隊與專案現況,挑選合適的實務作,對症下藥方能見效。但這藥也不能亂吃,吃錯了藥輕則花錢消災,重則可能要終生洗腎,不可不慎。

***

下一集:〈Scrum 是什麼(11):不信邪之流程改善精神

***

友藏內心獨白:這整篇哪裡有提到時程要如何估算啊?

2012年1月28日 星期六

動手整理資料(2):Synology DS411 儲存空間設定

January 26 12:35~14:38

上一集提到Synology DS411開箱與安裝硬碟的步驟,接下來要設定如何使用這些硬碟。首先連到Synology的官方網站找到DS411的軟體下載畫面,如下圖所示。要先安裝Synlolgy Assistant這個軟體,沒想到這個軟體居然有提供Windows、Mac、與Linux等三個版本,真是「揪感心」。剛好Teddy最近買了一台MacBook Air,就下載Mac版來試看看。

HD-01

 

下載之後安裝完畢執行Synology Assistant會看到如下畫面,注意「狀態」那一欄顯示「DSM未安裝」,DSM是DiskStation Manager的縮寫,應該是一個web-based application,要先安裝這個軟體才可以透過瀏覽器去管理DS411。

HD-02

點選上個畫面中的安裝按鈕,就會出現下面這個畫面,按下瀏覽按鈕選擇從Synology官網下載的DSM 3.2檔案按下一步(目前DSM最新版本為3.2,4.0版已經舉辦了beta發表會。)。

HD-03

預設管理者帳號是admin,在這個步驟可以設定管理者密碼以及DS411的名稱。這個名稱就是設定完成之後透過Windows的網芳尋找電腦時會看到的電腦名稱。最後有一個要注意的選項「安裝後建立Synology Hybrid Raid (SHR)儲存空間」,這個選項預設是打勾的。如果選擇了這個選項,系統預設會把所有安裝的硬碟作成一個號稱「可以兼顧資料保護與儲存容量的」單一個存儲空間,但是Teddy看了老半天還是沒搞懂SHR的運作原理,再加上Teddy的四顆硬碟只有disk 1與disk需要作RAID 1,其他兩顆硬碟不需要做RAID,所以就不選擇這個SHR(但是Teddy第一次安裝的時候不曉得者個選項是做什麼的,所以還是選擇了SHR…Orz)。

HD-04

接著是網路設定,這應該不用說明了。

HD-05

基本設定完成,等系統自動設定與安裝完DSM就可以開始使用了。

HD-06

安裝完成,按下「登入DiskStation」。

HD-07

輸入帳號(admin)以及剛剛設定的密碼。

HD-08

第一次登入所看到的畫面。由於Teddy在之前的設定步驟中在還搞不清楚狀況的情況下選擇了使用SHR,所以系統一安裝好就自動新增儲存空間。

HD-09

從下面這個畫面可以看到Teddy的四顆硬碟被組成一個很大的「儲存空間1」。

HD-09

但是SHR規劃出來的儲存空間並非Teddy所要的,所以把這個儲存空間給刪除了,重新建一個。使用DSM提供的「儲存空間管理員」,選擇「自訂」選項來新增儲存空間。

HD-11

 

Teddy選擇了第二個選項,不過寫到這邊才發現好像應該要選第一個選項…XD。

HD-13

 

選擇第一個選項,建立新的磁碟群組。

HD-14

 

選擇硬碟。由於Teddy只有disk 1與disk 2要做RAID 1,所以就選擇前兩部硬碟就好了。

HD-15

 

選擇RAID 1。看到這個畫面Teddy就有一個疑問,如果只有兩台硬碟,那麼選擇SHR和RAID 1會有什麼不同呢 ?還沒有時間去網路上爬文,不過總是覺得如果SHR是Synology所提供的特異功能,也許在安裝與設定畫面上應該要想辦法表現出到底哪裡和傳統的RAID有何不同之處。附帶一提,如果只是要單純使用單一台硬碟,那麼在這一個步驟選擇Basic選項就可以了。

HD-16

 

是否進行硬碟檢查,預設是要檢查。

HD-17

 

設定儲存空間配置容量。

HD-18

 

再次確定剛剛所有設定值,按下套用之後就會開始建立儲存空間。請注意建立儲存空間之後原本硬碟中的資料會消失。

HD-19

 

開始非常,非常漫長的等待,兩顆3TB硬碟作RAID 1足足等了10個小時。不知道如果不要檢查硬碟的話是不是速度會快一點 ?

HD-20

 

Teddy最後設定完成三個儲存空間的畫面,儲存空間1是RAID 1,儲存空間2和3是Basic。

HD-21

 

設定儲存空間有一點像是「格式化硬碟」的感覺,還需要新增「共用資料夾」才可以透過網路從別台電腦來存取DS411上面的資料。設定共享資料夾的方法容後再稟。

HD-22

***

看到者邊不知道鄉民們是否會有一個疑問:為什麼不全部作RAID 1或是用SHR就好了,這樣不是簡單多了嗎。因為Teddy比較膽小,之前曾經聽江湖傳言說有作成RAID X的硬碟因為電腦上面RAID controller壞掉導致硬碟上面的資料無法讀取。也許這樣的機率很低,或是只要把硬碟搬到另一台相同硬體的電腦就可以讀取了,但是萬一發生了總是很麻煩。而且做成RAID 1之後可用空間就只剩下一半,所以Teddy拿了兩台硬碟作RAID 1,把最重要的資料,例如相片,文件等放到RAID 1上面,其他比較不重要的資料,例如用電視卡錄下來的電視節目,網路上抓下來的Linux軟體ISO檔等,就放在一般儲存空間就好了。

然後,重點來了,這些放在DS411上面的所有資料,都會用軟體再複製一份到 雲端 Teddy的桌機中,這樣子一來應該算是很保險了(不要叫Teddy做什麼異地備援啊...)。

***

友藏內心獨白:不知道DS411的RAID是有硬體支援還是透過軟體模擬的 ?

2012年1月27日 星期五

什麼是物件導向(3):Polymorphism

January 26 23:01~January 27 00:23

Polymorphism,中文翻譯成「多形」,說真的這個概念當年Teddy學OO的時候搞了好久才弄懂,後來看了「課本」的定義之後,覺得寫得還滿好的,請參考Object-Oriented Software Engineering: A  Use Case Driven Approach第55頁:

Polymorphism means that the sender of a stimulus does not need to know the receiving instance’s class. The receiving instance can belogin to an arbitrary class.

再看一下55頁中另一段類似的解釋

If an instance sends a stimulus to another instance, but does not have to be aware of which class the receiving instance belongs to, we say that we have polymorphism.

翻成白話文就是說:一個訊息(message or event or stimulus)的意義是由接收者(接收到這個訊息的物件)來解釋,而不是由訊息發出者(sender)來解釋。所以,在runtime時只要接受者換成不同的物件或是instance,系統的行為就會改變。具有這樣的特性就稱之為polymorphism。還是不懂,對,很正常。不過在看一個活生生的例子鄉民們就應該懂了。

***

Teddy(sender,等一下準備送出信息的物件)走在路上看到前方有兩位名人,分別是「林志玲」與「阿美姐」(等一下準備接收訊息的兩個物件),於是大喊一聲「美女請留步(訊息)」。理論上Teddy期待只有「林志玲」會「回頭」(訊息接收者的行為),沒想到「阿美姐」也回頭了...XD。所以說,一個訊息的解釋是由接收者來決定的,而不是送出者。如果一個系統具有這樣的特性,那麼我們就說這個系統具備多型的行為。

舉個程式的例子:

List<String> list = new LinkedList<String>();

list.add(“This is a book”);

從上面這一行程式來看,我們可以說寫程式的人送了一個add這個訊息給list這個instance。從靜態程式碼來看,鄉民們一定知道list.add(“This is a book”)的行為,但是如果list這個instance不是像上面程式一樣寫死new LinkedList<String>();,而是runtime時傳入的任意符合List介面的某個instance,那麼程式的行為就無法只從靜態的程式碼得知了,而且add(“This is a book”);訊息的解釋也只能看runtime時list instance指到哪一個instance而定。

***

一般常用的靜態型別程式語言例如Java、C#,要做到polymorphism必須透過繼承,不管是implementation inheritance或是interface inheritance。有些動態型別程式語言,如果Teddy沒記錯的話像是Smalltalk(如果有錯請留言或來信幫忙更正),可以不需要靠繼承來達到polymorphism,但是在runtime如果接收者沒有支援某個訊息的話,則是會出現runtime errors。

總之,其實Teddy想講的重點是,這些老外厲害的地方,就是可以用很簡短的句子寫出某些觀念或是名詞的定義。因為除非真正了解所要描述的觀念或是名詞,否則是無法寫出這樣的定義出來。當年Teddy背下這個定義(因為考試會考啊…Orz)到現在都還依稀記得。什麼,你問Teddy記下這些定義有何用 ?Teddy也說不上來,也許哪一天鄉民們去面試不小心考了polymorphism這一題,而鄉民們恰巧看到這篇文章所以把書中的定義給寫了出來,但是主考者可能看不懂...Orz。不過這都不是重點,就以「純欣賞」的角度為能夠寫出這麼精簡定義的作者們拍拍手就好了...XD。

***

友藏內心獨白:這幾天好冷,寫到手都凍僵了。

2012年1月26日 星期四

好用的UHU萬用黏土(2):照片牆篇

January 23 23:01~23:58

前一篇提到萬用黏土的止漏用途,今天介紹一下最近幾天Kay發現的新用途,拿來把照片框固定在牆上。

話說又是幾年前在好友的辦公室中看到好友將他到世界各國旅遊的照各洗了一張,然後訂做一些相框把照片掛滿整面牆,整個感覺非常好。於是Teddy和Kay也想有樣學樣一下,但是想歸想,由於Teddy太懶於是這件工作就落在Kay身上。基本上這個「story」可以細分為五個「tasks」:

  • 挑選要洗出來的照片
  • 洗照片
  • 買相框
  • 把照片放到相框中並決定相框放到牆上的位置
  • 把相框度定在牆上

為了省錢(其實是偷懶)於是相框就直接買IKEA現成的,Kay花了很多時間在選照片,然後拿去Costco印(比較便宜不過感覺印出來的照片顏色有點說不上來的奇怪)。最後只剩下一個問題,要怎麼把相框固定在水泥牆上啊 ?不想要用釘子,如果買3M的無痕掛勾又不好看,沒想到最後Kay居然想到可以用萬用黏土來固定相框。先看一下sprint demo…啊,不對,是最後的成品(請忽略照片右方很雜亂的吧檯桌面,沒時間隱藏了)。

UHU-A

 

耶,說好的「照片牆」怎麼只有這一小塊啊?要怪只能怪Teddy和Kay去的國家不夠多,不過這不是重點啦,我們是套用agile的incremental growth精神,先試作一小片照片牆,留點以後擴充的空間。Teddy可以肯定的說,這種設計應該是有符合open-closed principle:加新 功能 照片的時候應該不需要移動舊照片的位置吧。如果真的要動到舊照片,只能說是為了套用refactoring...XD。

言歸正傳,接下來說明一下如何利用萬用黏土把照片黏到牆上,首先準備海綿寶寶若干隻,不對,是萬用黏土若干小塊。

HUH-B

 

然後用手把這些萬用黏土反覆揉捏,依據產品使用說明,反覆揉捏可以增強黏土延展性使黏著效果更佳。揉捏完畢之後把黏土黏到相框背面,如下圖所示。請注意,原本Teddy只黏了上下左右四個角落,隔夜起床之後發現相框抵抗不了地心引力的誘惑有點向下沉淪的現象,所以還是建議鄉民們依據相框的大小酌量增加黏土的分量。

UHU-C

 

然後把相框貼到牆上,用力在相框四周敲打一下使相框可以透過萬用黏土固定在牆面上(下面這張照片由於個資法的關係未經由本人同意只好打上「馬賽克」)。

UHU-D

下圖是地心引力大於萬用黏土黏著力的證明。

UHU-E

 

如果想取下照片框也是很容易的,稍微用力就像是在拔蘿蔔一樣就可以拔起來了。請參考下圖,照片框拔起來之後萬用黏土可能會黏在牆上,用手可以輕易的把萬用黏土清除,基本上不會留下什麼痕跡。照片中牆上的刮痕是Teddy前一陣子不小心刮到的,與萬用黏土無關,特此聲明...XD。

UHU-F

 

下圖是移除萬用黏土之後的牆面。

UHU-G

 

***

雖然照片是固定不動的,但整個過程不知道為什麼有種在施作task board的感覺...Orz。

 

***

友藏內心獨白:大過年的寫點別的,總不能每天都在練(軟)功吧。

2012年1月25日 星期三

好用的UHU萬用黏土(1):止水篇

January 23 21:46~22:38

幾年前Teddy還在念書的時候有一陣子很喜歡買文具,有一次在學校的文具店看到一種德國製的「 UHU萬用黏土」,看了一下產品背面的介紹:

  • 產品特點:可隨意黏貼於任何場所,防震,防水,防風吹。可重複使用,黏性不變。
  • 主要用途:黏貼海報圖畫或輕巧事務;固定物品位置如電話、電線;填補裂縫、窗緣;黏起灰塵或衣物之毛屑。
  • 使用方法:黏貼兩面必須乾淨無油汙,依黏著面積取適量黏土,同時柔捏多次後,再黏貼施壓至物品黏牢為止。
  • 售價:68元新台幣。

 

說真的這個東西Teddy當年一看到就覺得真的太神奇了,「防震,防水,防風吹。可重複使用,黏性不變」這種東西要去哪裡找啊。當時雖然沒有立即的需要,還是買了一個帶回家「保存」。目前手邊只剩下一點點還沒用完的萬用黏土,拍張照片給鄉民們參考一下。

UHU-1

買回家之後一直沒有機會拿出來使用,一直到大概1-2年前,家中浴室洗臉台下方的排水管接頭漏水,於是賢慧的Teddy拿了防水膠帶繞了排水管接頭幾圈試圖想止水。雖然漏水的現象有改善但是光靠防水膠帶無法很緊密的把漏水給全部止住,此時Teddy想起以前賣的萬用黏土,正所謂養兵千日,用兵一時,趕快拿出來止漏。沒想到效果非常的好,經過了這麼久的時間排水管漏水的問題都沒有再發生過。

HUH-2

排水管接頭處已經用黑色的防水膠帶包覆起來

HUH-3

近看可以看到一圈黃色的萬用黏土

 

***

以上用來修補排水管接頭漏水的小技巧提供給鄉民們參考一下。

***

友藏內心獨白:不知道為什麼現在看這個萬用黏土腦中就會浮出海綿寶寶的畫面...XD。

2012年1月24日 星期二

動手整理資料(1):Synology DS411 開箱

January 23 16:26~18:36

過年前幾乎家家戶戶都要大掃除,打掃「真實世界」的住家雖然辛苦但是卻只要願意出賣勞力一般來講都可以有不錯的成果。但是說起要打掃「虛擬世界」的住家,也就是電腦中的資料,那可就不是光靠付出勞力就可以搞定的。

***

數位化的資料越來越多,資料備份的問題也越來越令人頭大。早些年只要買個2.5吋的USB外接硬碟,然後利用類似SyncFree或是SecondCopy這種軟體將本機硬碟的資料與外接硬碟同步也就很好用了。但是隨著數位相機與智慧型手機的普及,隨便拍出來的高畫質影像(720p or 1080p)大小都是以GB起跳。數位照片的數量也越來越多,反正不管看到什麼先拍下來再說啦(這是一種爆料心態嗎?),不喜歡再刪掉就好了。所以,除了大容量資料備份以外,還要考慮到資料分享的方便性。

Teddy家裡有一台電腦二十四小時都不關機,專門拿來當mail server與檔案伺服器之用(Teddy內心獨白:沒事幹嘛自己搞一台mail server…Orz)。由於這台電腦只是一台用了應該超過四年的普通PC,當然不可能有什麼RAID硬體支援。Teddy會定期將這台電腦上面的資料備份至另一台Ubuntu桌機,這樣至少就有兩份資料,不用怕哪一天突然硬碟壞掉造成資料遺失。但是,隨著「多媒體資料」越來越多,檔案伺服器的硬碟已經不夠放了(已經升級過幾次硬碟),因此有些資料便被Teddy搬移到硬碟空間比較大的Ubuntu電腦中。

這樣做之後原本也相安無事,但是日子一久,Teddy開始搞不清楚到底哪裡的資料是最新的,那些資料備份了沒有,以及備份到哪裡去了(迷之音:學弟,SyncFree修好沒啊)。

原本Teddy是很不願意花錢買一台專屬的NAS(Network-attached storage)來當作檔案伺服器,為什麼 ?因為一台4Bay(可以接四台硬碟)的NAS不包含硬碟最便宜的也都要一萬元起跳,有的甚至要超過二萬,那為什麼不去Px Home買一台9999的一般電腦回來,還可以接6個SATA硬碟不是更划算。但是後來想一想現在雲端儲存與個人雲端儲存越來越流行,Teddy個人電腦都不知道換過幾台了但卻沒買用家用NAS,所以就冒著生命危險狠下心來上禮拜五下午在Px Home上面買了Synology DS411外加三顆3TB硬碟(這個產品組合比分開買DS411與硬碟要便宜個幾百塊)當作自己的新年禮物。

Synology DS411的主要規格:

  • CPU:1.6 GHz(不知道是哪家公司的,好像是ARM的CPU不過Teddy不確定)
  • 記憶體:DDR3 512MB
  • 硬碟:四台3.5吋或2.5吋SATA II
  • 網路:一個GB乙太網路
  • 最大儲存容量:12TB(四顆3TB硬碟)
  • 功耗:27.7W (運作中),13.2W(硬碟休眠)
  • 重量:2.23 KG(應該是不含硬碟的重量吧)
  • 支援下載協定:BT/eMule/HTTP/FTP/NZB

***

下定之後隔天下午一點多左右拿到包裹,打開之後看到一台Synology DS411和三顆WD綠標的3TB硬碟,至於價錢就...莫再提,想知道的鄉民們自己上Px Home上面找吧…XD。

DS411-1

 

先把DS411的箱子打開,上面有一張DSM 4.0 beta的廣告傳單,可惜活動已經辦完了,無緣參加。不過Teddy的學弟有去參加這個活動,有興趣的鄉民們可以參考「這裡」。

DS411-2

 

箱子打開之後看到主機一台,電源線一條,另外還很貼心的附上很多螺絲以及一條網路線。有附網路線這一點依該要先給它拍拍手,雖然一條網路線沒多少錢,但是如果等你東西都裝好之後才發現少了一條網路線,那就很傷腦筋了。

DS411-3

 

主機的正面,有一個塑膠保護套開機之前記得拿下來。這台主機的機身是沒有通風口的,所以應該是靠前方進風口與後方的兩個風扇來散熱。

DS411-4

 

機身後方可以看到兩個風扇,一個1GB乙太網路孔,兩個USB 2.0與一個e-SATA。

DS411-5

 

用手扭開機身背面四個角落的螺絲資後的照片,可以看到有四個硬碟插槽。

DS411-6

 

把機殼也拆開可以隱約看到主機板放在最下方。

DS411-7

 

安裝硬碟時必須把硬碟架抽出來,這個硬碟架是塑膠材質的,感覺有點省成本的嫌疑。

DS411-8

 

WD 3.0 TB綠標硬碟,這應該是目前市面上最便宜的3.0TB硬碟了。

DS411-9

 

放進去之後雙邊都鎖上螺絲,這是整個安裝過程中唯一需要用到螺絲起子的步驟。

DS411-10

 

產品中已經附了很多螺絲,直接拿出來鎖就好了。

DS411-11

 

鎖好後翻過來背面長成這樣子。

DS411-12

 

把硬碟鎖好之後輕輕往主機一推就完成硬碟安裝了。好像還有一顆螺絲可以把硬碟架和主機鎖在一起但是Teddy偷懶沒鎖。在安裝最下面那顆硬碟的時候由於會卡到風扇的電源線因此稍微比較不容易安裝,這一點要注意一下。另外,這四顆硬碟的編號應該是從上往下分別是Disk 1, 2, 3, 4,但是機殼背後卻沒有標號。要是萬一哪一天硬碟不小心壞掉,電腦軟體告訴你Disk 3壞掉了,你把機殼猜開後還不知道要拔哪一顆硬碟勒。

DS411-13

 

最後插上電源開機,主機正面最左邊那一顆是Status的燈,Status旁邊那一顆是LAN。右邊那四顆是HDD1,2,3,4的燈。中間那個亮藍色光的按鈕是電源開關。

DS411-14

 

機器裝好之後回頭一看地板,只能用「杯盤狼藉」來形容...Orz。

DS411-15

 

***

硬體開箱與安裝到此結束,之後就用用軟體從遠端去設定DS411的硬碟模式(是否使用RAID)與分享目錄及帳號權限。今天先講到這裡,軟體設定等Teddy搞熟了之後再跟鄉民們報告。

***

友藏內心獨白:為了打掃虛擬世界花了快30張小朋友,這...過完年之後某人看到這台不知有何反應...XD。

2012年1月23日 星期一

什麼是物件導向(2):Object, Class, Instance

January 21 22:58~January 22 00:10

鄉民們看到這篇的日子應該是大年初一,先跟大家說聲新年快樂。

這次要介紹在物件導向技術中三個經常容易搞混的名詞,分別是object、class、instance。首先看一下Object-Oriented Software Engineering這本書對於這三個名詞的定義:

  • Object:An object is characterized by a number of operations and a state which remembers the effect of these operations.(p.44)
  • Class:A class represents a template for several objects and describes how these objects are structured internally. Objects of the same class have the same definition both for their operations and for their information structures.(p.50)
  • InstanceAn instanceis an object created from a class. The class describes the (behavior and information)structure of the instance, while the current state of the instance is defined by the operations performed on the instance.(p.50)

以下為上述定義翻成白話文再加上一點Teddy個人補充的資料:

  • Class是用來定義object的一種東西,class的內容包含了動作(operations)與資料(data)。
  • 動作(operations)、方法(methods)和行為(behaviors)可以看作同義詞。理想上一個object的狀態只能透過動作去改變它。
  • 一個object就是某個class的instance,換句話說可以把object和instance看作是同樣的東西。只是在某些場合大家比較習慣用object這個說法,其他場合則是會用instance。例如,

List<String> a = new LinkedList<String>();

List<String> b = new LinkedList<String>();

你可以說「a、b兩個ojbects各指到一個LinkedList類別的instance」或是說「a、b兩個ojbects各指到一個 LinkedList類別的object」,但是如果程式變成下面這樣:

a = b;

那麼說成「a、b兩個ojbects都指到一個相同的LinkedList類別的instance」,或是更簡單一點「a、b都指到同一個instance」會比「a、b都指到同一個object」意思要來的清楚一點。

  • 資料成員(data members)和屬性(attributes)是同義詞,都是用來儲存物件的狀態。如果一個class沒有任何資料成員,這個class所產生的所有objects看起來就會是一模一樣的東西。也就是說,可以把一個沒有狀態的class變成一個static class,不用產生任何instance就可以呼叫該class的operations。
  • 物件與物件之間的關係可以簡化成兩種:aggregation和association,請參考GoF Design Pattern, pp.22-23。

***

看到這邊不知道鄉民們會不會有一個疑問:同樣的東西幹嘛搞出不同的說法啊?這就是「阿斗仔」厲害的地方啦。

***

友藏內心獨白:「九x共識」跟「一x各表」算是同義詞嗎?

2012年1月22日 星期日

什麼是物件導向(1):簡介

January 21 19:58~21:38

談了好幾次軟體設計與軟體架構,Teddy今天突然想到好像一直假設鄉民們都很懂OO(Object-Orientation 物件導向)。不管這個假設是否成立,在兔年尾龍年初的時期就來幫鄉民們複習幾個基本的OO觀念吧。

鄉民甲:應該是沒料可寫了吧。

Teddy:這是新年特別節目啦。

***

話說又是N年前的事情,當時Teddy還在念五專電子科,應該是專二還是專三的時候,當時C++很流行,由於Teddy當時已經學會了一點C的皮毛想說接著學C++應該也是「順理成章」的事情。沒想到雖然只是多了兩個「++」符號,兩個語言的差異還真大。原來C++只有在「程序導向(Procedure-Orientation 」和C語言差不多,但是對於學習C++所需的物件導向觀念Teddy則是完全不懂。

在當年那個「反共抗俄 資訊與物資匱乏 」的年代,Teddy可是花了不少冤枉錢買了一堆看完之後還是不知所云的書。請不要說:不是google一下就有答案了?別說google,那個年代WWW都還沒發明勒…XD。

總之,重點是,後來好像是專四還是專五的時候,有一門忘了是什麼課,剛好有一位剛從國外拿到PhD的老師居然很好心的印了一份講義講了一點OO的觀念。請注意,Teddy五專念的可是電子科,當年能在這麼「硬」的科系學到這麼「軟」的觀念,現在想起來覺得那一學期的學費沒有白交了...XD。

當初那份講義早就不知道消失到哪裡去了(應該已經重新投胎好幾次了),後來不曉得過了多久Teddy才發現原來那份講義就是Object-Oriented Software Engineering: A Use Case Driven Approach(1992年出版)這本書的第三章。這一章一共有個小節:

  • 3.1 Introduction
  • 3.2 Object
  • 3.3 Class and instance
  • 3.4 Polymorphism
  • 3.5 Inheritance
  • 3.6 Summary

這次先整理幾點3.1 Introduction所提到的重點:

  • Object-orientation is a technique for system modeling. Using OO, we model the system as a number of objects that interact.(物件導向是一種系統塑模技術。使用物件導向我們將系統塑模成若干個彼此互動的物件。)
  • OO提供了兩點很重要的好處:Understanding(理解性)與Modifications(修改性)。

換句話說,OO的目的是一種讓開發人員可以用來model(塑模、設計)軟體系統的技術。如何model?透過把系統視為由許多彼此互動的物件所組成。使用OO技術所設計的系統可以提高可了解性與可修改性(這兩點都是non-functional requirements)。

總之,如果要用一句話來形容,用以說:OO是一種用來設計可了解性與可修改性系統的技術

***

友藏內心獨白:這一篇要測試一下設定張貼日期的功能。

2012年1月21日 星期六

Scrum 是什麼(9):Retrospective Meeting

January 21 10:41~ 12:18

螢幕截圖 2015-06-11 23.29.23

前情題要:

 

在兔年年尾終於來到了Scrum最後一個活動Retrospective Meeting,還記得Scrum雙重回饋機制的那張圖嗎?Retrospective Meeting的目的就是要提供團隊一個反省與檢討「軟體開發流程」的機會,要如何反省與檢討呢?

 

image

 

Teddy的作法是將會議切成兩個階段:

  • 感謝:第一個階段是請每一個團隊成員輪流表達對於其他團隊成員的謝意,詳細進行方式請參考「Retrospective Meeting 之我謝謝你」。 Teddy個人覺得這個活動的正面力量非常強大,可以讓團隊成員養成一種互相幫忙的風氣,強烈推薦Scrum團隊採用。有一點要補充說明一下,基本上感謝的範圍與對象是在這個sprint中幫助自己的同一個團隊成員(跟你一起開retrospective meeting的人),但是有時候團隊成員會「出軌」感謝其他部門的人,這也是OK。
  • Good and Improvement:第二個階段是要列出這個sprint中關於開發流程上,哪些做法是好的要繼續維持,那些地方是有待改善的,以及討論出下個sprint的改善項目;活動進行方式請參考「Retrospective Meeting = 許願池」。

***

最近一次Teddy去參加ezScrum講座的時候有一位朋友問Teddy一個問題:「你們團隊實施了三年多Scrum,難道不會遇到retrospective meeting的時候發現沒有事情需要改善的困境嗎?」

這個問題問得很好,在軟體開發上可以改善的事情實在太多了,如果遇到不知道要改善什麼的時候很可能是Scrum Master沒有用心觀察團隊開發活動或是團隊成員太忙(通常是瞎忙)以至於腦袋空空想不出有什麼可以改善的。可從下列項目來思考改善的方向:

  • 基礎practices達成度:團隊目前對於基本agile practices的功力練到了第幾級,是否還有更上一層樓的空間。例如,自動化單元測試的line coverage達到多少百分比了?如果有寫自動化單元測試但是不知道line coverage多少那麼可以先從在持續整合系統加上test coverage工具開始改善起。假設已經有test coverage但是line coverage只達到50%那麼可以把改善目標訂成「將line coverage提升至52%」。如果line coverage以及到達很高的水準,可以考慮提升branch coverage或是其他各式各樣的code coverage。如果自動化單元測試已經做得很好了,那麼團隊有做自動化功能測試嗎?除了測試以外還有很多可以改善的基本practices,例如pair programming實施狀況、有沒有導入持續整合、有沒有做到ten-minute build等等。
  • 進階practices達成度:進階practices顧名思義就是上乘的武功秘笈,看過武俠小說的鄉民們一定都知道上乘武功像是玉女心經、九陰真經、六脈神劍這一等級,練武的時候是很容易走火入魔的,除了練武者需要有一定的武功底子以外,最好能找一個清靜沒人打擾的地方專心修煉。當團隊默契與成員的功力到了一定程度之後,可以視狀況逐步修練這些上乘武功。這一類的招式有shared code、single code base、daily deployment (continuous delivery)、real customer involvement、incremental deployment等等。
  • 消除浪費:消除以下七種浪費可以當作改善的目標,包含Partially Done Work (In-Process Inventory)Extra Features (Over-Production)Relearning (Extra Processing)Handoffs (Transportation)Task Switching (Motion)Delays (Waiting)、Defects (Defects)。

想要了解有哪些值得一試的agile practice可以參考《Extreme Programming Explained, 2nd》這本書。至於如何消除浪費請參考《Implementing Lean Software Development: From Concept to Cash》。

***

Retrospective Meeting是用來討論開發流程的議題,有時候團隊成員會把「產品改善」的意見與「流程改善」混為一談,當這種情況發生的時候Scrum Master要提醒團隊成員不要忘了Retrospective Meeting的目的,把焦點轉回到流程改善上面。

***

下一集:〈Scrum 是什麼(10):時程估算

***

友藏內心獨白:這一篇是用Windows Live Writer寫的...Mac上面有沒有其他好用的寫部落格軟體啊?