学习笔记-涛讲F#(中级)
这一系列的视频主要讲了F#设计模式的实现,没有太多其它内容,笔记内容主要是转载Snippets tagged design patterns的代码用于备份。设计模式相关的概念可参考设计模式:23种设计模式全面解析,本文不做太多介绍。
适配器模式
从不兼容的类型调用方法——原文链接
type Cat() =
member this.Walk() = printfn "cat walk"
type Dog() =
member this.Walk() = printfn "dog walk"
let adapter() =
let cat = Cat()
let dog = Dog()
let inline walk (x : ^T) = (^T : (member Walk : unit->unit) (x))
walk(cat)
walk(dog)
适配器模式的主要功能是由 inline 这行函数实现的,调用时直接使用 adapter() 即可。inline不可省略——因为内联函数可以具有静态解析的类型参数,而非内联函数不能。
责任链模式
以下示例要确保此人的年龄在 18 到 65 岁之间,体重不超过 200 并且足够高(>120)——原文链接
type Record = {
Name : string;
Age : int;
Weight: float;
Height: float;
}
let ChainOfResponsibility() =
let validAge (record:Record) =
record.Age < 65 && record.Age > 18
let validWeight (record:Record) =
record.Weight < 200.
let validHeight (record:Record) =
record.Height > 120.
let check (f:Record->bool) (record:Record, result:bool) =
if result=false then (record, false)
else (record, f(record))
let chainOfResponsibility = check(validAge) >> check(validWeight) >> check(validHeight)
let john = { Name = "John"; Age = 80; Weight = 180.; Height=180. }
let dan = { Name = "Dan"; Age = 20; Weight = 160.; Height=190. }
printfn "john result = %b" ((chainOfResponsibility (john, true)) |> snd)
printfn "dan result = %b" ((chainOfResponsibility (dan, true)) |> snd)
责任链模式的主要功能是由 check函数+函数正向组合运算符>> 实现的,check函数的输入一个处理者函数和一个处理结果,如果已有的处理结果为false则直接返回,否则调用处理者函数更新处理结果。
关于元组的两个操作:
- fst:返回元组的第一个元素
- snd:返回元组的第二个元素
命令模式
重做撤消场景的命令模式——原文链接
type Command = { Redo: unit->unit; Undo: unit->unit }
let result = ref 7
let add n = {
Redo = (fun _ -> result:= !result + n);
Undo = (fun _ -> result := !result - n) }
let minus n = {
Redo = (fun _ -> result:= !result - n);
Undo = (fun _ -> result := !result + n) }
let cmd = (add 3)
printfn "current state = %d" !result
cmd.Redo()
printfn "after redo: %d" !result
cmd.Undo()
printfn "after undo: %d" !result
注:ref 表示可变引用的类型,使用函数[!]和[:=]以获得和设置此类型的值。
另外一种 redo-undo 实现将命令分组在 Do/Undo 类别下,参考 Redo-Undo II 的命令模式。个人觉得对命令分组并不好,每次扩展命令的时候都要改分组部分的代码。
策略模式
根据环境或者条件的不同选择不同的算法或者策略来完成目标功能——原文链接
let quicksort l =
printfn "quick sort"
let shellsort l =
printfn "shell short"
let bubblesort l =
printfn "bubble sort"
type Strategy(sortFunction) =
member this.SortFunction with get() = sortFunction
member this.Execute(list) = sortFunction list
let strategy() =
let s = Strategy(quicksort)
s.Execute([1..6])
strategy()
工厂模式
简单工厂模式的实现——原文链接
type IA =
abstract Action : unit -> unit
type Type =
| TypeA
| TypeB
let factory = function
| TypeA -> { new IA with
member this.Action() = printfn "type A" }
| TypeB -> { new IA with
member this.Action() = printfn "type B" }
单例模式
饿汉式单例模式的实现——原文链接
type A private () =
static let instance = A()
static member Instance = instance
member this.Action() = printfn "action"
let DesignPatter1() =
let a = A.Instance;
a.Action()
其它内容
剩下的设计模式准备等到视频出来后再转载,后面的Type Provider太过专业很少用到,后面遇到实际应用场景时在学习。