簡體   English   中英

F# 命令模式

[英]F# Command Pattern

我正在嘗試實現命令模式來控制機器人。 我正在使用它來探索如何在 F# 中實現命令模式。 下面是我的實現:

type Walle(position, rotate) =     
    let (x:float,y:float) = position
    let rotation = rotate
    member this.Move(distance) =
        let x2 = distance * sin (System.Math.PI/180.0 * rotation)
        let y2 = distance * cos (System.Math.PI/180.0 * rotation)
        let newPosition = (x+x2, y+y2)
        Walle(newPosition, rotation)
    member this.Rotate(angle) = 
        let newRotation = 
            let nr = rotation + angle
            match nr with
            | n when n < 360.0 -> nr
            | _ -> nr - 360.0
        Walle(position, newRotation)

let Move distance = fun (w:Walle) -> w.Move(distance)
let Rotate degrees = fun (w:Walle) -> w.Rotate(degrees)

let remoteControl (commands:List<Walle->Walle>) robot = 
    commands |> List.fold(fun w c -> c w)

let testRobot() =
    let commands = [Move(10.0);Rotate(90.0);Move(16.0);Rotate(90.0);Move(5.0)]
    let init = Walle((0.0,0.0),0.0)
    remoteControl commands init

為了提出一個功能解決方案,我選擇讓機器人的動作在每次調用后在其新的 position 處返回一個機器人的新實例(避免突變)。 我還關閉了執行操作所需的 state 的命令功能。

我很好奇人們在實現該模式時是否認為這些是好的設計決策? 或者,如果人們可以就實施該模式提供任何其他建議?

為了避免采用 OO 方式將數據與“類型”中的操作組合並將這種組合表示為“對象”,我的 POV 中更實用的方法是在模塊中分別定義數據和操作,如下所示:

module Walle = 
 type Walle = {Position : float * float; Rotation : float}

 let Move distance (w:Walle) = 
    let x2 = distance * sin (System.Math.PI/180.0 * w.Rotation)        
    let y2 = distance * cos (System.Math.PI/180.0 * w.Rotation)
    {w with Position = (w.Position |> fst) + x2, (w.Position |> snd) + y2 }

 let Rotate angle (w:Walle) = 
    let newRotation = 
        let nr = w.Rotation + angle
        match nr with
        | n when n < 360.0 -> nr
        | _ -> nr - 360.0
    {w with Rotation = newRotation}

現在您可以創建一個新的 Walle 並使用 |> function 將其傳遞給一系列轉換 Walle“數據”的函數。 這完全是關於數據和該數據的轉換,沒有對象:)。 它可能不像命令模式,因為它更適合 OO 風格。 您真的不需要 FP 中的模式,還是我們?

對於機器人示例,我寧願只使用命令式樣式,即更改機器人 object 的狀態。 因為機器人 object 通常有狀態的概念和改變狀態的動作。 從OO設計的角度來看,有些對象最好是不可變的,例如.NET中的String、DateTime,但很多都不是。

不可變對象當然有優勢。 在您問題的持久版本中,您可以保存機器人的所有過去狀態,並且可以輕松地UnDo機器人上的命令。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM