功能性程式設計與命令式程式設計 (LINQ to XML)

本文比較與對照功能性程式設計與更傳統的命令式 (程序性) 程式設計。

功能程式設計與命令式程式設計的比較

明確建立「功能性程式設計」開發架構時,可支援解決問題的純功能性方法。 功能性程式設計是一種「宣告式程式設計」。 相較之下,多數主流語言 (包括物件導向程式設計 (OOP) 語言,例如 C#、Visual Basic、C++ 與 Java) 的設計主要支援「命令性」(程序性) 程式設計。

開發人員可以利用命令式方法撰寫程式碼,以便說明電腦為了完成目標必須採取的步驟。 這有時候稱為「演算法」程式設計。 相較之下,功能性方法包含將問題撰寫成要執行的一組函式。 您可以仔細定義每個函式的輸入,以及每個函式會傳回的東西。 下表描述這兩種方法之間的幾項一般差異。

Characteristic 命令性方法 功能性方法
程式設計人員焦點 如何執行工作 (演算法) 以及如何追蹤狀態的變更。 想要的資訊與需要的轉換。
狀態變更 重要: 非存在。
執行順序 重要: 重要性低。
主要流量控制 迴圈、條件與函式 (方法) 呼叫。 函式呼叫,包括遞迴。
主要操作單位 結構或類別的執行個體。 當做第一級物件與資料集合的函式。

雖然多數語言的設計在於支援特定的程式設計開發架構,但許多一般的語言還是有足夠的彈性,可以支援多種開發架構。 例如,包含函式指標的多數語言可用於確實支援功能性程式設計。 此外,C# 和 Visual Basic 加入明確的語言擴充功能,以支援功能性程式設計,包括 Lambda 運算式與類型推斷。 LINQ 技術是一種宣告式功能性程式設計。

使用 XSLT 的功能性程式設計

許多 XSLT 開發人員都很熟悉純功能性方法。 開發 XSLT 樣式表最有效的方式,就是將每個範本都視為可組合的隔離轉換。 執行順序完全不重視。 XSLT 不允許副作用 (除非執行程序性程式碼的溢出機制可以產生導致非純功能性的副作用)。 不過,雖然 XSLT 是一個有效的工具,但是有些特性並不是最好的。 例如,在 XML 中表示程式設計建構會使程式碼相當詳細,因此難以維護。 同時,大量依賴流量控制遞迴可能會使程式碼難以讀取。 如需 XSLT 的詳細資訊,請參閱 XSLT 轉換

不過,XSLT 已經證明使用純功能性方法將 XML 從一個組織結構轉換為另一個組織結構的值。 包含 LINQ to XML 的純功能性程式設計類似於 XSLT 的許多方法。 不過,LINQ to XML、C# 和 Visual Basic 所引進的程式設計建構可讓您撰寫比 XSLT 更容易讀取與維護的純功能性轉換。

純函式的優點

實作功能性轉換做為純虛擬函式的主要原因是純虛擬函式是可組合的:也就是說,純虛擬函式是獨立的,而且沒有狀態 (Stateless)。 這些特性帶來很多益處,包括:

  • 增加可讀性和可維護性。 這是因為每個函式都是針對完成已知其引數的特定工作而設計。 此函式不會依賴任何外部狀態。
  • 反覆開發更容易。 由於程式碼更容易重構,針對設計所做的變更通常也更容易實作。 例如,假設您撰寫一個複雜的轉換,接著了解特定程式碼會在轉換中重複數次。 如果您透過純虛擬方法重構,您可以隨意呼叫您的純虛擬方法,而不用擔心副作用。
  • 測試與偵錯更容易。 純虛擬函式可以更輕易地接受獨立測試,因此,您可以利用一般值、有效的邊緣案例以及無效的邊緣案例撰寫呼叫純虛擬函式的測試程式碼。

OOP 開發人員的轉換

在傳統的物件導向程式設計 (OOP) 中,多數開發人員都習慣以命令性/程序性的方式進行程式設計。 若要切換到以純功能性方式開發,他們必須轉換其思考方式及其開發方法。

為解決問題,OOP 開發人員會設計類別階層、著重於適當的封裝,以及根據類別合約思考。 物件型別的行為與狀態是最重要的,而所提供的語言功能 (例如,類別、介面、繼承與多型 (Polymorphism)) 則用於處理這些考量。

相較之下,功能性程式設計會考慮運算問題,做為評估資料集合之純功能性轉換的練習。 功能性程式設計會避免狀態與可變動的資料,而強調函式的應用。

幸而 C# 和 Visual Basic 不需要完全跳到功能性程式設計,因為它們同時支援命令式與功能性程式設計方法。 開發人員可以選擇哪個方法最適合特定的案例。 事實上,程式通常會結合這兩種方法。

另請參閱