内容简介:Decorator Pattern 是 OOP 中著名的 Design Pattern,尤其可在不改變 interface 的前提下,動態對原有物件增加功能,F# 既然是 Function First Language,就讓我們以 function 的角度重新實現 Decorator Pattern。macOS High Sierra 10.13.3.NET Core SDK 2.1.101
Decorator Pattern 是 OOP 中著名的 Design Pattern,尤其可在不改變 interface 的前提下,動態對原有物件增加功能,F# 既然是 Function First Language,就讓我們以 function 的角度重新實現 Decorator Pattern。
Version
macOS High Sierra 10.13.3
.NET Core SDK 2.1.101
JetBrains Rider 2017.3.1
F# 4.1
User Story
假設你在處理訂單,訂單的折扣方式有兩種
- 超過 1000 元,則
全館八折
再滿千送百
- 不到 1000 元,則
全館八折
Task
直接使用 FP 的思維完成需求。
Definition
Decorator Pattern
在不改變原有 interface 的前提下,動態增加原有的功能
首先思考 Decorator Pattern 的本質:
- Component 與 decorator 之間的 interface 必須相同
- Component 可自由組合 decorator
只要能達到這兩個目標,就算完成了 Decorator Pattern。
OOP 思考方式
- 為了讓 component 與 decorator 的 interface 要相同,所以必須訂出共同的 interface
- 由於 decorator 必須包含原本 component 功能,因此 decorator 必須以 state 方式保存原本 component
- 由於各 decorator 都必須透過 constructor 保存原本 component,因此將共用 constructor 抽出來由
AbstractDecorator
實作
FP 思考方式
- Component 與 decorator 都是 function,不用事先定義 interface,反正只要 interface 不同,在 Pattern Matching 一定會編譯錯誤
- Component 與 decorator 都是 function,既然 interface 都相同,只要是用 Function Composition 產生新的 function 即可
Implementation
PriceDecorator.fs
namespace OrderLibrary module PriceDecorator = let discountPrice price = price * 0.8 let rebatePrice price = price - 100.0
以 discountPrice()
表示 全館八折
。
以 rebatePrice()
表示 滿千送百
。
由於 component 與 decorator 基本上都是 double -> double
的型別,可以廣義視為 decorator。
OrderService.fs
namespace OrderLibrary open PriceDecorator module OrderService = let getPrice price = match (price > 1000.0) with | true -> (discountPrice >> rebatePrice) price | false -> discountPrice price
根據商業邏輯:
超過 1000 元,則 全館八折
再 滿千送百
因此將 discountPrice()
與 rebatePrice()
以 >>
compose 成一個新的 function,就相當於 全館八折
再 滿千送百
在 FP 只要使用 Compose Function,就相當於 OOP 的 Decorator Pattern,在 F# 只需 >>
,但 C# 卻要 interface 與 abstract class 的搭配才能實現
Program.fs
open System open OrderLibrary [<EntryPoint>] let main argv = 1200.0 |> OrderService.getPrice |> printfn "%f" 800.0 |> OrderService.getPrice |> printfn "%f" 0 // return an integer exit code
將各種 price 以 Pipeline 方式傳給 OrderService.getPrice()
計算,並將結果傳給 printfn()
顯示。
Summary
回想 Decorator Pattern 的本質:
- Component 與 decorator 之間的 interface 必須相同
- Component 可自由組合 decorator
由於 component 與 decorator 的 interface 相同,可以廣義視為 decorator,雖然沒有特別定義 interface,但 discountPrice()
與 rebatePrice()
的 signature 都是 double -> double
,若 function 的 signature 不同,在 Pattern Matching 就會編譯錯誤,與原本 Decorator Pattern 定義 interface 的本質相同。
原本 OOP 的 Decorator Pattern 可以透過 new
自由組合 decorator object,但 FP 可透過 >>
自由組合 decorator function,與原本 Decorator Pattern 的自由組合 decorator 本質相同。
Conclusion
- Decorator Pattern 本質就是 object 的組合,但 object 的組合沒 function 簡單直覺,所以才需要搭配 interface 與 abstract class,但若純 function,只要使用 Function Composition 即可簡單完成
Sample Code
完整的範例可以在我的 GitHub 上找到
以上所述就是小编给大家介绍的《如何使用 F# 實現 Decorator Pattern?》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- RecyclerView使用指南(一)—— 基本使用
- 如何使用Meteorjs使用URL参数
- 使用 defer 还是不使用 defer?
- 使用 Typescript 加强 Vuex 使用体验
- [译] 何时使用 Rust?何时使用 Go?
- UDP协议的正确使用场合(谨慎使用)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
C程序设计题解与上机指导
谭浩强 / 清华大学 / 2000-9-1 / 19.50元
《C程序设计题解与上机指导(第2版)》是和谭浩强编著的《C程序设计》(第二版)(清华大学出版社1999年出版)配合使用的参考书,内容包括:(1)《程序设计》(第二版)一书的习题和参考解答,包括了该书各章的全部习题,共约150题,对全部编程题都给出了参考解答;(2)上机指南,详细介绍了在当前广泛使用的Turbo C集成环境下编辑、编译、调试和运行程序的方法,并简要介绍了Borland C++的使用方......一起来看看 《C程序设计题解与上机指导》 这本书的介绍吧!