2008/08/07

什麼是正確的握刀與拔刀方式?

這句話是依達我流問良峰貞義的,當劍聖收依達我流做徒弟後,第一件事情就是叫他去向良峰貞義學習正確的握刀與拔刀方式。什麼是正確的握刀與拔刀方式? 在多次的體悟後,依達我流終於答出正確的答案。

正確的握刀與拔刀,就是沒有多餘的動作,只為目標而握刀,只為目標而拔刀。當手握刀之前就已經決定,這一刀要往哪邊拔出,往哪邊揮斬,在拔刀之前一瞬間制敵機先。

以上故事是霹靂神州第17集的劇情。是啊~ 這是布袋戲裡面的劇情。不過在這段短短的劇情中,體會出幾件人生通則:專心、決心。除此之外呢? 目標!

常常在開發軟體或製作專案時,會發現功能不斷擴增,需求不斷改變,計畫永遠不足。為什麼會這樣? 因為我們缺乏明確目標,不只是身處開發者的我們,客戶與其他的第三者亦同。因為沒有明確的目標,所以對正在開發階段的項目,一邊討論需求一邊修改,產生多餘的工作打亂了原訂的計畫,使得我們無法專心致志。

螺旋開發法與 MSF 都強調階段性,在每個 iteration 中大致包含需求、設計、開發、測試的流程。在一個 iteration 中如果發現新的需求,可以排入下一個 iteration,以免打亂目前的開發節奏。堅守開發的節奏與流暢度,才能讓軟體品質節節高昇。

2008/03/20

微軟的對手

沒有一家像微軟這樣,在 4C 產業占據如此巨大的位置。這家樹大招風的公司,自來也是對手林立,然而從每個主要時期的競爭對手來看,都不得不配服微軟的多型態發展,以及窺見整個資訊產業的變遷。

從早期的個人電腦時代,IBM PC 相容機種的興起,支持眾多新興 PC 公司與 IBM 抗衡的主力就是 MS DOS 作業系統。乃至 Windows95 與 OS/2 Warp 的對抗落幕後,PC desktop 作業系統就被微軟把持到現在。

在程式開發領域,微軟是首屈一指的軟體開發商,手上的 Visual Studio 開發工具也是赫赫有名。在 VB 年代,和微軟打平的 Borland Delphi,自從 .NET Framework 興起後,節節敗退。微軟的對手後來被成了 Sun,代表 Java 一方的 Sun 曾經是微軟為可惡的惡魔。今天 Sun 與微軟簽訂了不少共同合作的協議,已經化敵為友了。接替 Sun 的地位在 Java 界繼續扮演老大哥的是 IBM,它們又再度對壘了。

不過,現在真正才要開始激烈地競爭的終端應用是 RIA,這回微軟的對手是 Adobe,Adobe 擁有 PDF 和 Flash 這兩個悠久的應用技術,微軟則回敬 XPS 和 Silverlight,目前鹿死誰手尚不可預期。

其他關於娛樂產業、遊戲機的競爭,鍵盤滑鼠的領域。都是微軟分得到一杯羹的地方。現在還吃不大開的,就屬企業核心領域,企業核心需要大型的資料庫,高階的運算系統,這一直以來是 Unix 的天下,近年來雖然被 Linux 入侵了,始終是 Unix-like 家族掌控著。微軟不會放著不管的,推出了 Microsoft Dynamic 企業系統,後端資料庫從 SQL Server 2000 演進到未來的 SQL Server 2008  可以看到十足的成長。

從微軟的對手,可以發掘資訊產業的焦點變遷,整個趨勢的轉移。同時也意味著,微軟的持續變化。我只能說,它真得是隻八爪巨獸的怪公司。

2008/03/06

Internet Explorer 8 beta1 開放下載

微軟終於開發下載 IE8 beta1 了,這是即將在 MIX08 公布的版本嗎? 微軟說明 IE8 預設的網頁繪製模式會以大多數的網頁標準為預設,另外提供 IE7 相容模式 (本來 IE7 模式是預設的) 。

可是實際使用的結果差強人意,iGoogle 網頁的三欄式版面無法呈現,GMail 的 gadget 也無法呈現。Yahoo mail 2.0 有 javascript 的問題 (Firefox 3.o.4pre 也對 Yahoo mail 感冒)。

IE8 的 javascript 執行效能有增加,但依然在市面上主要瀏覽器排名殿後,執行 SunSpider JavaScript Benchmark 成績比 IE7 要進步,我的電腦本來執行 IE7 約 17 秒 (17000ms) 完成測試,IE8 進步為 12 秒多。但是 Firefox 3.0.4pre 在 7 秒多就完成。

感覺微軟還需要大大加把勁,因為連微軟自家的網頁在 IE8 都有很多網頁版面跑掉的情形,這和 IE7beta 時期差不多,正式版出來後改進很大,期望 IE8 正式版能夠更好。

2008/02/01

學習筆記: 目標是設計軟體框架

我的新任務

從僅具有物件基礎概念,到練就一身能夠設計 framework 的能力,這中間的學習過程,我將記載於此一系列的筆記中。我所使用的技術是 .NET Framework 2.0,語言為 C#。

從 2002 年在巨匠電腦補習上 Java 課的時候,同時開始自修 C#。自此投入 .NET Framework 的技術領域。迄今已有五個年頭,對於程式設計熟稔度僅止於是個熟練的 programmer,直至遇見一位機緣結識的朋友,在他的接納下,加入他的團隊,開始真正踏入軟體設計之路,也打開了我的視野。

我發覺,使用 .NET Framework 的技術,可以很快速的開發各類解決方案,但是因為它的好用,使得我在大部分的情況下,並不會去深入探究更多的軟體設計核心。幾乎遇到的任何問題都可以在當下迎刃而解。或至少花苦工就能解決大多數的問題。總是見招拆招。這樣的結果,造成忽略許多軟體工程,也不能成就一個真正好用的軟體。

曾經,我看著幾個常用的軟體,如 foobar2000 播放器,或是類似的多媒體播放軟體,總為它的高度延伸性所折服,想不透為甚麼可以做出這麼好的 plug-in 架構,它是怎麼辦到的? 其實我早就學過了,透過介面設計,還有動態載入組件就可以達成,卻完全沒有運用過,甚至不知道如何運用,更遑論發揮其潛能了。

懵懂的我去上了一門課,軟體設計架構師精修班,在林耀珍老師的介紹中,看到許許多多的 design patterns。那時,design patterns 對我而言猶如天上群星,雖耀眼卻渺不可及。

現在我被賦予要開發一套 framework 的任務,是一件非常大的挑戰。然而人如果不把目標訂得夠大夠遠 (當然不要好高騖遠),並且施予適度的壓力,就不會想快馬加鞭奔馳而去。目前仍在起步階段的我,必須閱讀許多書本,並詢問前輩意見,才能慢慢做出一些有樣子的東西。

這過程中有許多的嘗試與心得,才發現,這種學習的心路歷程的經驗,沒有任何書本在傳遞的。而我一直認為,學習力是人類最重要的技能,在前輩鼓勵下,我開始將之一點一滴記錄,希望能夠在同輩與後進簡產生一些迴響,也希望各位前輩看到任何不足之處,予以指導與啟發。

書單

先列出目前閱讀的書籍,是這些書開始帶我進入軟體設計的領域。
1. 深入淺出設計模式 Head First Design Patterns (O'Reilly)
2. UML 與樣式徹底研究 by Craig Larman (Pearson)
3.物件導向分析設計與實作 by 葉智偉 (儒林)
4. Windows Forms 框架設計實務 by 黃忠成 (金革)
5. 應用框架的設計與實現-.NET平台 by Xin Chen (電子工業出版社)
6. UML Distilled 3rd Edition by Fowler (Pearson)
7. Framework Design Guidelines by Krzysztof Cwalina, Brad Abrams (Addison-Wesley)

2008/01/02

Visual Studio 2008 Express 免費下載

軟體開發人員眾所矚目的 Visual Studio 2008 RTM 公布了,連同 Express 版本也開放下載。喜歡搶鮮的朋友可以去 Express 開發者網站下載。更重要的是,下載後要去註冊,可以獲得許多 3rd party 的元件。包含:

  • Rad ribbonbar by Telerik — Provides an easy-to-design implementation of Microsoft Office 2007 ribbon user interface.
  • BubbleBar by DevComponents — A uniquely tabbed toolbar control with magnifying/bubbling buttons.
  • SpreadsheetGear for .NET by SpreadsheetGear — Develop Microsoft Excel compatible Windows Forms and ASP.NET Microsoft Reporting applications.

看到這些有沒有已經流口水了。

Windwos Form 開發 : MDI 設計模式 step by step

使用 .NET 開發 MDI 模式的視窗應用程式是非常容易達成的,透過視窗屬性設定 IsMdiContainer 為 true 就可以將子視窗的 MdiParent 屬性指向自己,這是最簡易的 MDI 設計方式。以下以Visual Studio 2005 示範如何建立一個 MDI 模式的視窗程式。

一、基本做法

首先在 Visual Studio 2005 開啟一個 Windows Application 專案,命名為 MdiDemo。
1. 將 Form1 變更檔案名稱為 MainForm,VS 會自動幫你將 class 名稱也一起變更。
2. 在 Design View 可以看到表單的外觀,然後將 MainForm 的 IsMdiContainer 屬性設定為 true。此時會看到表單內區域變成深灰色。
3. 從工具列拉一個 Panel 元件到表單上,並設定 Dock 屬性為 Top。
4. 接下來拉三個 Button 到 Panel 上,分別顯示為 Form1, Form2, Form3
完成以上步驟後,表單外觀如圖(一):

Figure1
圖(一) MainForm 外觀

接下來,在專案新增三個Form,分別為 ChildForm1, ChildForm2, ChildForm3,並在表單上放一個 Label 元件,如圖(二)。

Figure2
圖(二) ChildForm 外觀

如此,表單的外觀都完成了,開始在 MainForm 的按鈕事件撰寫呼叫子視窗的程式。

private void button1_Click(object sender, EventArgs e)
{
ChildForm1 frm = new ChildForm1();
frm.MdiParent = this;
frm.Show();
}

然後在另外兩個按鈕的 Click 事件中,分別呼叫 ChildForm2, ChildForm3。完成後將程式執行,並且按下 button1,結果如圖(三)。

Figure3
圖(三) 各個 ChildForm 都開在 MainForm 裡面

在 button1_Click 裡面加上一行程式碼。

private void button1_Click(object sender, EventArgs e)
{
ChildForm1 frm = new ChildForm1();
frm.MdiParent = this;
frm.WindowState = FormWindowState.Maximized; //設定視窗起始狀態為最大化
frm.Show();
}

當按下按鈕後 ChildForm 會自動放到最大,MainForm 會出現一列 MDI 視窗的控制按鈕,如圖(四)。簡單的 MDI 設計模式的便完成了。

Figure4
圖(四) ChildForm 放到最大的執行結果

二、進階處理

雖然完成了 MDI 模式,但是連續按下 button1 會發現 ChildForm1 可以被重複產生。為修正這個狀況,可以使用 Singleton 設計方式來產生 ChildForm。
首先,手動修改 ChildForm1 的程式碼。

public partial class ChildForm1 : Form
{
#region Singleton
private static ChildForm1 instance = null;

private ChildForm1() //建構子改為 private
{
InitializeComponent();
}

public static ChildForm1 GetInstance()
{
if (instance == null)
{
instance = new ChildForm1();
}

return instance;
}

//關閉視窗後,將instance設為null
private void ChildForm1_FormClosed(object sender, FormClosedEventArgs e)
{
instance = null;
}
#endregion
}


將建構子改為 private 使外部程式不能直接產生物件,必須透過 GetInstance 方法傳回實體。並且在 FormClosed 事件要將 instance 設為 null,否則當關閉 ChildForm1 後再度按下 button1 會發生"Cannot access a disposed object."的錯誤訊息。

三、模擬MDI模式

另外有一種方式可以達到類似 MDI 模式。在專案中新增加一個 MainForm2,但是不用設定 IsMdiContainer 屬性。
1. 如同 MainForm 拉一個 Panel 並 Dock 為 Top,然後放三個按鈕上去。
2. 拉一個 Panel 到表單上,命名為 ContainerPanel,Dock 屬性設為 Fill,Padding 屬性四個邊皆設定為 4pixel。
3. 拉一個 Panel 到 ContainerPanel 裡面,命名為 FormPanel,Dock 屬性設為 Fill,BorderStyle 屬性為 Fixed3D,BackColor 為 ControlDark。
完成以上步驟,MainForm2 外觀如圖(五)。

Figure5
圖(五) MainForm2 外觀

看起來和 MainForm 是不是很像。接著來看 MainForm2 的程式碼。

private void button1_Click(object sender, EventArgs e)
{
ChildForm1 frm = ChildForm1.GetInstance(); //Singleton方式取得物件實體
OpenForm(frm);
}

private void OpenForm(Form frm)
{
//設定表單屬性
frm.TopLevel = false;
frm.TopMost = false;
frm.FormBorderStyle = FormBorderStyle.None;
frm.WindowState = FormWindowState.Normal;
frm.StartPosition = FormStartPosition.Manual;
frm.Parent = this.FormPanel;
frm.Location = new Point(0, 0);
frm.Size = this.FormPanel.Size;
frm.Dock = DockStyle.Fill;
frm.Visible = true;
frm.BringToFront();
}


button1_click 事件裡面呼叫 ChildForm1.GetInstance() 方法來取得表單實體,然後調用 OpenForm 方法處理顯示表單。重點在於 FormBorderStyle, Parent, Dock 三個屬性的設定,執行起來如圖(六)。

Figure6
圖(六) MainForm2 執行結果

此種方式,在主視窗上面就不會出現 MDI 視窗的最大化最小化的控制項。(完)

Book: Framework Design Guidelines

之前看了一篇MSDN雜誌的關於LINQ發展的文章,文章說明了LINQ語法的緣由,特別是語法背面的物件技術背景。文中提到 "理想語法" 的概念,描述一個理想的資料存取語法,然後說明其中的物件技術背景,再而衍生出lambda 運算式。最後為了讓熟悉SQL語法的開發者能夠銜接,於是逐步發展成理想的LINQ語法。原文連結入下:MSDN Magazine, June 2007: LINQ 的發展及其對 C# 設計的影響

Framework_Design_Guidelines_cover最近在看 "Framework Design Guidelines" 一書,作者是參與開發 .NET Framework 的核心人員,書中說明許多 framework 的開發指引,有許多非常實用的建議。在此書第二章說明了開發 API 重要的原則: 場景驅動設計 (scenario driven design)。以使用者的角度,先編寫一些對主要使用場景來說不可少的程式碼,然後再設計物件模型來支援這些範例程式碼。

這裡所謂 "範例程式碼" 就是 "理想語法"。此書中定義的開發規範涵蓋 .NET Framework 2.0,而Anders Hejlsberg (C#與Delphi之父) 說這些規範還在指導著微軟下一代 API (WinFX (現在正式稱做 .NET Framework 3.0) ) 的開發。前後觀之,在 .NET Framework 3.5 都依循這樣的開發原則進行著。

這本書不論是對發展 API 有所幫助,對於程式開發也可獲得許多有價值的建議,值得推薦給所有的程式開發者。