星期三, 6月 14, 2006

如果怕賠錢,就不要開公司就不會賠錢了

今天看到一篇舊的討論,獨孤木發起的 一個既有的系統想要進行architecture的調整,你們認為該怎麼做比較好呢? 有點長,中間有許多明言,例如:"如果怕賠錢,就不要開公司就不會賠錢了"、"好公司通常都是大公司。因為好,所以有機會變大"等等。

怕以後找不到,所以先摘結論下來,獨孤前輩,請莫怪。

問題:

你現在的工作是要把一套系統從Notes轉到J2EE下面,你是一個project manager,你在進行planning時,有什麼該特別注意的地方呢?

1.這種調整architecture的案子,跟一般全新的專案有什麼不一樣呢?
2.有什麼risk是要特別注意的呢?
3.假設如果要整個案子porting到J2EE下面,根據你的估計,整個做完要花兩年,三千萬。客戶說,我們今年只有一千萬,明年後年還各有一千萬。在這種預算有限的狀況下,你會建議客戶怎麼做?
如果要分期上線,你建議怎麼區分不同的release?依功能面,還是照其他的層面?對他們最大的效益是什麼?
分好幾個phase(大的iteration)來release的話,會有什麼要考慮的?

------------------------------------------

背景說明:

1你面對的系統,沒有up-to-date 的design document,只有一套正在running 的系統。

2.user除了想要把現有系統的功能轉過來以外,還想包一些enhancement在scope裡面。這些系統因為現在還在operate,所以得要考慮data migration,也要考慮怎麼做parallel run。

------------------------------------------

參考答案(截至目前為止的回應加上我自己的參考答案)

1.1 沒有現成的design,那麼在做頭一個release時,會需要做現有系統的reverse engineering。
關於reverse engineering應考慮下列問題:
• reverse engineering會不會遇到什麼困難?
• 有沒有什麼tool?
• 要花多少effort?
• 有沒有適當的人選可以做這件事情?
• 如果沒有的話,有沒有什麼backup plan?
• risk高不高?
• 這在第一個release是否是個must?

提到backup plan,resource不足時,除了找外界的人來輔導內部員工以外還可以考慮外包。關於外包應考慮下列問題:
• 你要找幾個外包?
• 你找得到這些外包商嗎?
• 怎麼把東西包出去給他們?彼此之間要怎麼切割?
• 如果包出去,可是有人結不了案怎麼辦?
• 包給5個外包商,中間良莠不齊,有幾個永遠沒辦法準時交件時,你的plan是什麼?
• 你又要怎麼樣去管理這些外包?有沒有什麼明確的management plan& mechanism?
• risk會不會太高?

1.2 integration test時間與scope應該要足夠cover夠多的scenario。

1.3 除了integration test以外,還應該要規劃平行測試與平行運轉時間。這幾個item應該會在schedule上面有顯著的影響。

1.4 應該要特別注意data migration相關規劃。schedule應該要包含完整的分析資料/測試程式的時間。(離題一下,data migration的程式,應該先對轉出的資料格式進行嚴格的檢查。很多系統的資料都不乾淨。需要整理。)

project 一開始,對於data migration的planning一定不清楚,應該要在data migration測試開始進行時,重新review data migration schedule以及launch schedule。那時應特別依據data 的volume推估migrate資料實際會耗費的時間。

如果每個phase都需要migrate data,migrate data的順序性,應該在initial planning時勾勒出方向,detail等到data migration相關utility開始implement時,需要重新檢討這個plan。

1.5 分多次release,開發經費會往上竄升。主要是因為project duration會因此而拖長,change request會進來的機率也會變高。而每次要給user做UAT,都會有相衍生的cost會發生。如果一次做要做三年的東西,分成三個phase去做, 時間可能會拉長為4~5年。經費可能會升高為於原有的兩倍以上。

要考慮建立測試環境可能會衍生的成本。在第二年你的問題會變成是,1.要解頭一年上線系統的bug。2.要開發新系統。這可能需要兩組人。(這是另一個經費往上升的原因)。

你 有新系統,也有舊系統,這是頭一個phase的狀況。到了phase 2,你有phase 1做好的系統,跟phase 1時改成可以跟新系統talk的舊系統,還有phase 2想要取代的新系統。在你在做測試的時候,已經在operate的東西如果出問題還要有地方測試。這時候可能會有很複雜的測試環境問題。

需要測試環境,就要準備相對應的軟硬體。會同時需要多個測試環境,有很多個測試環境,就要有人專門來負責管理這些環境。這通常也是另一個時間跟金錢會往上攀升的原因。所以建置測試環境所需要的時間/人力/成本,應該做通盤規劃。

1.6 如果team不大,可以考慮採用下列方法來plan resource。
對於小team來說,分工要分的很清楚確實比較困難。遇到這種狀況能做的,不是先預測有沒有人會走,有沒有沒有經驗的人會來,通常是會先去搶想要的人頭。接著開始plan sunny day scenario。

先假設已經被抓到,確定會進來的人都會待到結案,需要的人都會出現。算出來的schedule還有經費乘以一個倍率。(我建議考慮乘以2以上的數字)得到的數字,是你的底線。
各種event,遇到了再說。

1.7 最後這點最重要。每一個phase有沒有清楚明白地定義出跟其他phase無關的驗收標準。(最好是不要環環相扣喔,否則會影響cash flow喔。)

2.1 如果這是個non-stop mission critical的案子,光是這一點就是high risk。

2.2 沒辦法一個phase做完,所以一定會有新舊系統並存的時刻,這需要特別考慮兩套系統並行的問題。這會是一個很大的risk。

Design/review 時,應特別著重在兩者介面是否規劃清楚。Integration test時間與scope應該要足夠cover夠多的scenario。此外,如果兩套系統的技術差異很大,例如從cobol轉成j2ee,那麼有沒有相 關的人才就會有很大的影響。

2.3 data migration所需要migrate的data volume如果很高,schema又很複雜,risk就會跟著很高。

2.4 第一個phase因為要做reverse engineering,data migration,還有新架構的建置與部份程式的開發,所以resource usage與schedule都很有可能會是high risk。

2.5 如果這是個pilot project,technical上的未知也很多,那麼技術上也會是high risk。最好先做技術上的POC(proof of concept),確定想法確實可行。

3.1 先假設三年分三個phase launch。開發期間可能會有小的release,會有小的iteration。不過為了討論上的方便,這裡通通用waterfall的方式來討論。主要會從release給客戶的時間來推敲。

3.2 因為user頭一年只有一千萬的經費,要拿到這筆錢,通常就得要有一個可以驗收的東西。所以頭一年最少要有一個release可以上線。

3.3 integration test,parallel run加上unit test,對於這種轉換architecture的系統來說,可能要預留50%以上的時間進行測試。

3.4 一開始做planning/sa時,architect/designer應該要開始建立architecture baseline,並做出一些proof of concept。

3.5 通常第一個phase最難做,因為包含了reverse engineering跟data migration,這是一定會吃resource的。所以可以deliver的東西最少。可是user也最想要在第一個phase看到不一樣的東西。所 以建議scope時的溝通是很重要的。

如果第一個release要給user覺得花錢是有回報的,可能是要把一些user覺得比較critical的enhancement放進去。不過這可能會影響第一個phase的schedule。這也是在第一個階段要討論,跟user達成共識的東西。

可是如果你保留了50%的時間進行測試,通常也表示只有50%的時間留給SA/SD/Coding。如果一開始做SA時,designer同時也在做POC,那麼SA+SD應該要佔30%+的時間,coding大概就只有20%-的時間。

user可能會希望enhancement先上,特別是這種經年累月的系統,通常會有很多可以改善的地方。

可 是加入越多現在不存在的功能,在phase 2, phase 3提出新的change request的機率也會變高,並且在第一個phase的loading也會重很多。除了migrate data/reverse engineering/parallel run以外,還要跟user敲requirement,確定新的feature,並且經過漫長的測試期間。這樣overall的risk會變高。

在客戶滿意跟降低風險之間,通常得要有一個平衡點。我建議透過市場機制來解決這個兩難。也就是說,同樣的功能在不同的phase做,其實成本是不一樣的。

當你把問題的複雜程度攤開來以後,那時得要跟客戶討論經費跟schedule的部分。你要漲價,得要有一番道理。最少目前常見的定價策略都是成本(人月*薪水)加上固定成數的利潤 = 報價。而我的看法基本如下:

在phase 1做,可能你底層的架構還沒調整好,就要硬著頭皮去寫,這樣成本應該會比較高。在後面的phase來做,成本會變得比較低。最少你手上可能已經有一堆東西 可以參考/reuse了。所以在不同的phase implement的話,收不同的價錢,看user要那個phase上。反正重賞之下必有勇夫。收多一點錢,就擔多一些風險,這是天經地義的事情。

3.6 既然都會有新舊系統共存的問題,所以不一定是phase 1=>新舊共存,phase 2=>全部更新,phase 3 =>enhancement。實務上可能會在phase 1,2都有一些enhancement,而且即使到phase 2 launch,舊系統依然存在。這樣可以舒緩phase 1, 2的壓力,並且降低risk。

通常可以考慮by功能面切phase。 除此之外,還可以考慮從architecture的角度來思考。例如原本是vb寫成的client server program,可以改成front end依然是vb,可是底層改用ejb…的方式去做。只是如果是從architecture的角度思考,還要做poc就是了。

照功能 面切割的話,優先考慮,當然是商業面的問題。Business requirement優先。接著才是從技術角度出發。可以依照現有系統與系統之間的coupling還有dependency來思考。跟別人越無關的東 西,可以越晚上線。越接近源頭的東西,越有關的東西,要在越前面的phase上線。

Qing的答案:

1.這種調整architecture的案子,跟一般全新的專案有什麼不一樣呢?

答: 使用者對於需求比一般全新的專案清楚很多. 他們知道過去系統能做什麼
事情, 而且對於長期以來, 這套系統所缺乏, 而他們所期待要有的需求, 也有
相當的概念. 所以, 對於捕捉需求來說, 會比一般全新的專案來得容易.

2.有什麼risk是要特別注意的呢?

答: 新的架構是否實際可行. 通常會先做 POC. data migration 的工作常常會被
忽略. 例如, 只叫一個小毛頭來做之類的. 對 development team 來說, 在這個
專案裡, 是不是擺進來太多新的東西. 例如不只是新的軟體架構, 甚至包括新的
開發方法論. 當然, 對任何專案來說, 放進愈多新的元素, 風險就愈高, 這是必
然的 -- 除非這個專案的目的就是要試驗.

3a.假設如果要整個案子porting到J2EE下面,根據你的估計,整個做完要花兩年,三千萬。客戶說,我們今年只有一千萬,明年後年還各有一千萬。在這種預算有限的狀況下,你會建議客戶怎麼做?

答: 要看客戶的心態而定. 成本, 時程, 品質, 和範圍四根桿子. 如果成本, 時程
, 品質都被固定住了, 那麼顯然可以調整的就是範圍. 客戶想放什麼東西在範
圍裡, 很難說. 通常系統必備的功能, 一定要放進來. 轉換架構後的效應,
也應該被彰顯出來. 可能是可容納 volume 變大了, 可能是效率變好了, 可能是
Web-based 化了, 很難說, case by case, 端視轉換架構的目的為何.

3b.如果要分期上線,你建議怎麼區分不同的release?依功能面,還是照其他的層面?對他們最大的效益是什麼?

答: 如 3a 的答案所述, 要看客戶的心態而定. 如果轉換架構的目的是為了效率,
那麼能夠在第一階段彰顯出效率的提升, 就是會最大的努力目標.

3c.分好幾個phase(大的iteration)來release的話,會有什麼要考慮的?

答: 在參考答案中寫的很好, 錢要收的到. 此外, 似乎還需要更細的 context
才能回答.

星期二, 6月 06, 2006

對抗PChome垃圾信運動

對抗PChome垃圾信運動

http://mypower.webaq.com/pchome-junkmail/

Ubuntu 6.06 LTS

昨天把NB上的Ubuntu 5.10升級到6.06 LTS,完全使用線上安裝,真是太帥了 目前Windows沒有辦法做到這種程度的線上升級吧!

因 為昨天升到半夜才裝好,今天才有時間測試,果然不負眾望,比以前更快,效果更好。我的顯卡是SIS,在5.10剛進X會有些雜訊,這版已經完全正常。 Firefox用1.5.0.3,希望能盡快升到1.5.0.4。加上Sun合作,成為唯一內建官方JVM的Linux,這點讓使用者方便太多。

我用的仿OSX的Theme雖然沒有Aqua那麼美,但目前的速度與穩定性,算是user friendly的OS。前陣子FreeBSD才說要改善桌面環境,Ubuntu是很好的學習對象,當然,最好的仍是Mac。

星期一, 6月 05, 2006

Mock Object Pattern

Mock字面上的意思就是膺品,也就是假貨。Mock Object是產生一個與原來class相同的物件。

用途是在Unit Test時,測待class可能有相依的元件,在不易使用或呼叫的情況下,使用Mock Object取代這些元件;例如Business Logic元件會呼叫DAO元件,在此時使用Mock Object可以省掉許多麻煩與時間,直接將值回傳,避免資料庫裏的資料與當初設定時不同。

範例:

原來class:
publci class Transaction
{ ... }
Mock Object class:
private class MockTransaction extends Transaction
{ ...}

Mock Object就這麼簡單,可以提昇Unit Test的效率。
但隨著系統的發展及變更,Mock Object會跟著越來 越多,反而造成Mock Object維護不易,因此聰明的程序員就想出用AOP來節省時間,最後開發出Mock Object工具。

參考資料:
Unit testing with mock objects
MockObjects.com
Java:
EasyMock
MockCreator
jMock
Virtual Mock Objects using AspectJ with JUNIT
.Net:
Mock Objects to the Rescue! Test Your .NET Code with NMock
NMock

星期日, 6月 04, 2006

Null Object Pattern

在寫程式時,有時候需要傳回空值,例如員工資料查無此人時,但是傳回null常會造成不方便並容易會出錯。這種時候,可以導入Null Object以避免此情形,Refactoring : Introduce Null Object

參考:Null Object Design Pattern

但在"Agile Software Development"第17章中,建議不要直接有NullCustomer,而改用Customer.NULL這種做法。寫法如下:

public interface Customer
{
public boolean buy(Object o);
public static final Customer NULL = new Customer()
{
public boolean buy(Object o) { return false};
}
}

這種做法,可以確保只有單一的null customer。

星期六, 6月 03, 2006

又一個炒作?

認識我的人都知道,平常我很低調,不過因為朋友提到,就順便寫下來,也作為一個預言。

今天同學阿瑋提到一個新聞:"Web 2.0/紅透半邊天!網站服務爭相推~",
我的想法和他一樣,都是在炒作。

Web 2.0是Oreilly提出的,誠如文中蕃薯藤營運長蕭景登所言,Web 2.0是一個概念。但是,Google有本事弄出個AJAX,至少讓使用者的感覺改變。Hemidemi算有一些,但是今天吵得最大聲的PXHome呢? 我不做評論,開頭就說過我很低調,不像暗黑殺手。我只能說,會有人出來罵。

Firefox 1.5.0.4

昨天看到Firefox 1.5.0.4出現,當時還不能自動更新,今天果然出現自動更新。最好的消息是,許久以來在OS X上Spaces貼Link會crash的bug修好了

MonoState Pattern

很久沒介紹Design Pattern,所以再找一個國內比較少人用的Pattern:MonoState

平時若希望只有唯一物件時,最常想到的就是Singleton,但是Singletone通常都有一個getInstance的method,用起來和一般物件不同。而MonoState的運作方式與一般物件相同,所以可以寫給菜鳥PG使用,他們也不會知道這是靜態的值。

說了優點,當然也要說缺點,主要是物件會有建構與解構的動作,效率一定比Singleton差一些。

用 途:與Singleton相同,不限制用getInstance存取時。我所想到的一個用途是在寫Multithread程式時,鎖定的機制用。Java 的synchronized或C#的lock都必須對一個物件instance鎖定,因此若需要某個固定物件時,用MonoState作為Mutex就很 好用。

範例:

Java:

public class MonoState
{
private static String mutex="mutex";
public MonoState(){};

public String getMutex()
{
return mutex;
}

public void setMutex(String mutex)
{
this.mutex = mutex;
}
}

C#:

public class MonoState
{
private static string mutex="mutex";
public MonoState(){};

public string Mutex
{
get { return mutex; }

set { mutex = value; }
}
}

參考資料:
http://www.informit.com/guides/content.asp?g=cplusplus&seqNum=147&rl=1
http://codebetter.com/blogs/darrell.norton/archive/2004/02/05/6644.aspx
http://www.devx.com/getHelpOn/10MinuteSolution/16361/1954?pf=true

利用高科技作弊的大學生

剛看到CNet"利用高科技作弊的大學生",讓我想到大學時代許多同學無所不用其極的作弊方式。當時有人縮印四次的國文課文,還有一些匪夷所思的新奇招式。後來讀研究所就沒有人作弊,大概因為連寫的時間也不夠,而且其他同學的答案也不見得正確。
這篇有一段: 「如果這些人把做這些事的時間花在讀書上,」拉斯維加斯內華達大學工學院系主任Ron Yasbin生氣地說到:「應該就可以全部拿A。」 我也覺得如此,3年前去考SCJP時,並沒有特別去找考古題,完全憑對Java的瞭解去考也還好。不過我真的對考試不太行,記得只考七十幾分吧。
若從物競天擇的角度來看,作弊並不一定會帶給人負面的成長,反而是一種求生存的手段。Life will find a way. 火影忍者有一集就是在中忍考試時測驗他們作弊的能力,扯遠了...
作弊的本質就是為了求Pass,和高科技一點關係都沒有,用計算機或簡訊只是增加證據,還不如抄在手上,一摸就不見。現在覺得作弊真是沒什麼用的東西,想辦法訓練自己靜下心看書、練速讀之類還比較有用。
我觀察班上的第一名都是具有高度集中力,能夠在短時間吸收知識。IQ高不一定有用,重點是在於努力,我這位同學IQ140以上,還是沒有上台大呀...
考試要高分還是得靠考古題才行,可惜這點我到研究所畢業才領悟。如果你有子女,要考高分一定要叫他們多做題目,不要像我傻傻地只看課本,連五專那種選擇題都考不好。

孟岩:對於技術術語專業化的思考

孟岩:對於技術術語專業化的思考
沒想到大陸把transaction翻作事務,比較起來,台灣稱為交易貼切多了。

原文為簡體,若看不懂,請改用Firefox裝新同文堂翻譯。