F# - 工厂方法设计模式

发布于 2024-11-01 02:49:10 字数 734 浏览 0 评论 0原文

下面是我使用 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# 应用程序中使用?

Below is my attempt at implementing the factory method design pattern using F# whilst trying to make it a little more functional (i.e. not a straight OO implementation). Below is what I came up with:

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

Is this an appropriate implementation of the factory method design pattern? Is the pattern used in real world F# applications?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

倒数 2024-11-08 02:49:10

我不确定工厂方法设计模式在函数式编程中的用处有多大。
该模式的目标是隐藏对象的创建,以便您可以仅使用对象的抽象表示。

  • 当您以函数方式使用 F# 时,大多数时候您将使用具体表示。例如,这使您能够在滑板类型上进行模式匹配。
  • 当然,F# 允许您将函数式风格与面向对象风格混合。出于某些目的,OO 风格在 F# 中运行良好。在这种情况下,你的方法看起来很合理。

您的工厂方法可以采用具体类型(例如可区分联合)作为参数,而不是字符串。那么工厂的任务就是从具体表示构建抽象表示:

// 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 将具体类型转换为抽象类型。

这与函数式编程中的常用方法非常匹配 - 您经常使用一个数据的不同表示形式并在它们之间进行转换(取决于哪种表示形式更适合特定问题)。

I'm not sure to what extent is the factory method design pattern useful in functional programming.
The goal of the pattern is to hide the creation of objects, so that you can work with just an abstract representation of the object.

  • When you use F# in the functional way, you'll use concrete representations most of the time. For example, this gives you the ability to pattern match on the skateboard type.
  • Of course, F# allows you to mix functional style with object-oriented style. For some purposes, OO style works well in F#. In that case, your approach looks quite reasonable.

Your factory method could take a concrete type (e.g. discriminated union) as an argument, instead of string. Then the task of the factory is to build abstract representation from the concrete representation:

// Abstract representation of the data
type ISkateBoard = 
  abstract Model : unit -> string

// Concrete representation of the data
type SkateBoard = 
  | Roskopp 
  | Peters

Now, a factory would be simply a function of type SkateBoard -> ISkateBoard. For example (using F# object expressions):

// 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..." }

I think that the benefit of this approach is that you can do some work on the concrete representation of the type (e.g. some calculation where you need pattern matching), but then you can use the factory to turn the concrete type into an abstract type.

This matches quite well with the usual approach in functional programming - you often use differenet representations of one data and transform between them (depending on which representation is better for a particular problem).

千寻… 2024-11-08 02:49:10

正如 Tomas 所说,使用具体类型可以让您在开始使用工厂创建对象之前清理输入并失败。

type SkateBoard = 
    | Roskopp 
    | Peters
with 
    static member FromString = function
        | "Roskopp" -> Roskopp
        | "Peters" -> Peters            
        |  _ -> failwith "no such skateboard model.."

你会发现很多面向对象的设计模式在函数式编程中消失了。

使用 SkateBoardFactory 您可以创建一个额外的函数来执行您的函数。

let SkateBoardFactory assemble model = assemble model
let SantaCruzFactory = SkateBoardFactory assemble

由于一流的功能,您可以简单地分配assemble

let SantaCruzFactory = assemble

Along with what Tomas said, using concrete types allows you to sanitize your input and fail before you start creating objects with your factory.

type SkateBoard = 
    | Roskopp 
    | Peters
with 
    static member FromString = function
        | "Roskopp" -> Roskopp
        | "Peters" -> Peters            
        |  _ -> failwith "no such skateboard model.."

You will find a lot of design patterns from OO just go away in functional programming.

With SkateBoardFactory you create an extra function to execute your function.

let SkateBoardFactory assemble model = assemble model
let SantaCruzFactory = SkateBoardFactory assemble

You can simply assign the assemble because of first class functions.

let SantaCruzFactory = assemble
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文