將 ASP.NET 網站移轉至 IIS 7 時碰到的問題

9/28/2009
總算有機會把原本在 IIS 6 上面跑的 Web 專案移轉到 Windows Server 2008 + IIS 7 環境,但部署完成後,瀏覽網站時卻發生錯誤:

Request is not available in this context.


Framework Design Guidelines 筆記 (4): 低門檻原則

9/23/2009
關鍵詞彙
  • Framework(框架;類別庫)
  • The principle of low barrier to entry(低門檻原則)
低門檻原則指的是:
框架必須提供一個較低的入門門檻,讓初學者可以透過簡單的小實驗來學習這套框架。 (p.21)
然而,一套類別庫要做到功能強大、完整,同時又要易學易用,卻不是那麼容易。像 .NET Framework 這類比較大型的類別庫,裡面的類別非常多,為了方便學習、查找,就一定得要有適當、合理的分類和命名,否則可能寫了好多好用的工具,卻藏在類別庫中某個很深層的角落沒人發現。這分類的關鍵,主要就在 namespace 的運用。

因此,若要設計出容易學習的 API,應做到下列幾點(p.22-23):
  • 平常寫程式經常用到的類別要能很容易找到,而且成員的數量要適中。比如說,一個 namespace 裡面包含 500 個型別,結果其中只有少數幾個是真正關鍵或常用的。這種齊頭式平等的分類方式不僅不易學習,在撰寫程式的時候也多少會帶來困擾(IntelliSense 一次列出一拖拉庫的成員清單)。
  • 要讓開發人員隨手捻來就能立即使用。如果使用某個類別之前,還得先建立其他類別的 instances、設定一堆必要的屬性、以及寫很多初始化的程式碼,那麼,初學者為了寫一點實驗用的小程式就得大費周章,可能試個幾次就打退堂鼓了。
  • 要很容易找到錯誤的原因,以便迅速解決問題。例如,API 應該儘量考慮可能發生的 exceptions,並且在例外發生時丟出清楚的錯誤訊息,讓程式設計師能夠從訊息來判斷哪裡出了問題。
關於最後一點,我個人的感受特別深,因為印象中我總是經常重複這樣的牢騷建議。十年前碰到隱藏錯誤或訊息曖昧不明的情況,十年後似乎也沒有太大的改變,還是得不斷拜託寫底層元件的人不要再丟出「發生錯誤了!」這種只有神才知道原因的訊息。(更別提 catch 區塊裡面什麼都沒有的寫法)

據我瞭解,支持「精簡錯誤訊息」的一個主要考量是:end users 根本看不懂那些底層的詳細錯誤訊息;顯示太詳細反而造成使用者的困擾。

我想問題的關鍵在於:錯誤訊息是有分類型或等級的。一般使用者的操作錯誤,應用程式自然很容易顯示最精簡、易懂的訊息(例如:請先選擇這個,再按那個),那是比較偏向 warning、information 之類的告知訊息。而寫底層 API 的設計師要處理的卻是比較特殊的「例外狀況」,這些例外狀況所引發的錯誤訊息雖然對 end users 來說沒太大用處,但卻是維護人員接到電話或 e-mail 時一個非常重要的線索。把這個線索隱藏起來,就像鴕鳥把頭埋進沙堆一樣,對解決問題真的一點幫助也沒有。

詳細描述錯誤訊息只是設計 API 的最基本要求而已,Chris Sells 認為,好的錯誤訊息除了描述 what,還要提示如何解決:
In my own programming, I dearly love error messages that say what I did wrong and how to fix it. All too often, all I get is the former, when all I really care about is the latter. (p.23)

相關文章

審校碎碎念(二):靈活的翻譯?

9/20/2009
例 1:These techniques do not replace other approaches to software testing but can significantly increase testing effectiveness, help identify and reduce redundancy, and also reduce the susceptibility of the testing effort to the pesticide paradox.

Greenfield 是綠海還是綠地?

9/08/2009

Framework Design Guidelines 筆記 (3) : 情節驅動設計

9/04/2009
這是 Framework Design Guidelines 2nd edition 筆記的第 3 篇,基本介紹和表示法請參閱第 1 篇第 2 篇
關鍵詞彙
  • scenario-driven design(情節驅動設計)
  • use cases(使用案例)
  • test-driven development, TDD(測試驅動開發)
以下開始內容摘要,我自己的話用暗橘色標示
==========================================
情節驅動設計的原則

我們建議框架設計師先就框架使用者(按:我們常說的 app programmers)所欲處理的主要情節來撰寫程式碼,之後再根據這些範例程式碼來設計合適的物件模型。

此做法有點類似 TDD 或使用案例驅動的設計方式,但 TDD 算是比較重量級的方法,因為它除了驅動 APIs 的設計之外,還有一些別的目標;使用案例則是從較高的層次來描述情節,而不是從個別 API 呼叫的角度來思考。(scenario、use case、requirement、function,這幾個名詞也許是因為涵義相近或有重疊之處,翻譯成中文時常見有混用的情況,例如把 scenario 稱作「需求」,把 use case 稱作「功能」等等,如此固然「平易近人」,在某些場合卻可能過於含糊籠統。作者在書中對 scenario 和 use case 有比較明確的界定,閱讀時不妨留意一下。)

框架設計原則

設計框架的第一步,必須先從一組使用情節,以及實作這些情節的範例程式碼開始。

Krzysztof Cwalina:對此原則,我有句話要補充:「想要設計一個好框架,除此之外沒別的辦法。」如果這本書只能介紹一個設計原則,我一定會選這個。

框架設計師經常犯的錯誤,是先以各種設計方法論來設計物件模型,然後為這些設計好的 API 撰寫範例程式。問題是,大多數的設計方法(包括物件導向設計)都是以可維護性為主要考量,而未著重在 API 的易用性;它們非常適合用來設計僅供內部使用的程式架構,但不適合用來設計大型框架的共用 API 層。
  • DO 先為主要情節撰寫範例程式碼,然後再從這些範例程式發展出對應的物件模型。
舉例來說,假設要設計一個 API 來計算某段程式的執行時間,你會先寫出類似下面的情節程式範例(有點像虛擬碼,注意裡面同時有 C# 與 VB 語法):
// scenario #1: 計算執行時間
Stopwatch watch = Stopwatch.StartNew();
DoSomething();
Console.WriteLine(watch.Elapsed);

// scenario #2: 重複使用 stopwatch
Dim watch As Stopwatch = Stopwatch.StartNew()
DoSomething();
Console.WriteLine(watch.ElapsedMilliseconds)

watch.Reset()
watch.Start()
DoSomething()
Console.WriteLine(watch.Elapsed)

然後,根據這些程式碼發展出以下物件模型:
public class StopWatch
{
public static StopWatch StartNew();

public void Start();
public void Reset();

public TimeSpan Elapsed { get; }
public long ElapsedMilliseconds { get; }
...
}

也就是說,情節驅動設計就是從 API 使用者的角度出發,先想想看會怎麼用這些 API,並寫下範例程式碼。這些範例程式碼等於是 API 物件模型的需求規格,而接下來的工作就是根據這些範例程式碼來設計符合該需求的物件模型(類別)。

這種設計方式,也可以說是由上而下,從外(外部需求)到內(內部實作)吧!

相關文章

.NET Framework 4.0 新功能:Code Contracts

9/03/2009
MSDN Magazine 2009 年 8 月號CLR Inside Out 專欄主題是 .NET Framework 4.0 的新功能:Code Contracts,由 Melitta Andersen 執筆。正如其名稱所揭示的,這項新功能的目的即在於進一步支援合約式設計(design by contract)的概念。


Framework Design Guidelines 筆記 (2) : 漸進式框架

9/01/2009
摘自:Framework Design Guidelines 2nd edition by Krzysztof Cwalina & Brad Abrams
Key Terms
  • progressive framework: 漸進式框架
表示法
  • DO: 表示強烈建議、務必遵守的設計原則。
  • CONSIDER: 建議考慮這麼做。
  • DO NOT: 禁止事項。
  • AVOID: 儘量避免的做法。
=============================
  • DO 設計框架時要兼顧功能強大與容易使用。

    如 Alan Kay 所說:「簡單的東西就要有簡單的設計,而碰到複雜的情況時也應該要能應付。」(Simple things should be simple and complex things should be possible.)
  • DO 設計時應考量廣大開發人員的各種程式設計風格、需求、以及不同的技術水平。
  • DO 設計時應考量支援各種程式語言。
Krzysztof Cwalina:設計框架給跟你相似的使用者是很簡單的,而要設計給跟你不同的使用者就非常困難了。許多 APIs 都是由領域專家所設計,但老實講,只有領域專家覺得它們好用。

Brad Adams:我們在設計 APIs 時往往只考慮到自己,而非客戶的需要。
漸進式框架

一套框架要能同時兼顧各類開發人員、需求、和程式語言,是相當困難且昂貴的事業。以往,開發軟體元件的廠商是針對特定開發族群和特定需求來提供多種解決方案,例如微軟的 Visual Basic、MFC、ATL 等等。

這些特定用途的 APIs 雖然強大好用,卻有個主要缺點:當開發人員要從目前的技術領域移向另一塊領域時,學習曲線會非常陡峭,因為那等於是要學習另一套新的東西。

比較好的解決方式,是提供所謂的漸進式框架(progressive framework)。這種框架的特色是兼顧各類型的開發人員,且適用範圍較廣,從比較簡單的需求到進階的應用都能應付。

.NET Framework 即屬於漸進式框架,它有單一的程式撰寫模型,支援廣泛類型的應用需求與技術層次,學習曲線也較為緩和,能夠由簡入繁、循序漸進。

相關文章
技術提供:Blogger.