下面是我尝试使用F#实现工厂方法设计模式,同时尝试使其更加功能(即不是直接的OO实现)。以下是我提出的建议:
type ISkateBoard = abstract Model : unit -> string
type SkateBoard =
| Roskopp
| Peters
interface ISkateBoard
with member this.Model() =
match this with
| Roskopp-> "Rob Roskopp..."
| Peters -> "Duane Peters..."
let assemble model : ISkateBoard =
match model with
| "Roskopp" -> Roskopp :> ISkateBoard
| "Peters" -> Peters :> ISkateBoard
| _ -> failwith "no such skateboard model.."
let SkateBoardFactory assemble model = assemble model
let SantaCruzFactory = SkateBoardFactory assemble
这是工厂方法设计模式的适当实现吗?该模式是否在现实世界的F#应用程序中使用?
答案 0 :(得分:4)
我不确定工厂方法设计模式在函数式编程中有多大作用。 模式的目标是隐藏对象的创建,以便您可以仅使用对象的抽象表示。
您的工厂方法可以采用具体类型(例如,区分联合)作为参数,而不是字符串。然后工厂的任务是从具体表示中构建抽象表示:
// Abstract representation of the data
type ISkateBoard =
abstract Model : unit -> string
// Concrete representation of the data
type SkateBoard =
| Roskopp
| Peters
现在,工厂只是SkateBoard -> ISkateBoard
类型的函数。例如(使用F#对象表达式):
// Transform concrete representation to abstract representation
let factory concrete =
match concrete with
| Roskopp -> { new ISkateBoard with
member x.Model() = "Rob Roskopp..." }
| Peters -> { new ISkateBoard with
member x.Model() = "Duane Peters..." }
我认为这种方法的好处是你可以对类型的具体表示做一些工作(例如你需要模式匹配的一些计算),但是你可以使用factory
来转换具体类型为抽象类型。
这与函数式编程中的常用方法非常匹配 - 您经常使用一个数据的差异表示并在它们之间进行转换(取决于哪个表示对于特定问题更好)。
答案 1 :(得分:4)
与Tomas所说的一样,使用具体类型可以让您在开始使用工厂创建对象之前清理输入并失败。
type SkateBoard =
| Roskopp
| Peters
with
static member FromString = function
| "Roskopp" -> Roskopp
| "Peters" -> Peters
| _ -> failwith "no such skateboard model.."
你会发现很多来自OO的设计模式就在功能编程中消失了。
使用SkateBoardFactory
创建一个额外的函数来执行你的函数。
let SkateBoardFactory assemble model = assemble model
let SantaCruzFactory = SkateBoardFactory assemble
由于头等功能,您可以简单地指定assemble
。
let SantaCruzFactory = assemble