F # - Фабричный метод проектирования шаблонов - PullRequest
4 голосов
/ 14 апреля 2011

Ниже приведена моя попытка реализовать шаблон проектирования фабричного метода с использованием 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 #?

Ответы [ 2 ]

4 голосов
/ 14 апреля 2011

Наряду с тем, что сказал Томас, использование конкретных типов позволяет дезинфицировать ваш ввод и дать сбой, прежде чем вы начнете создавать объекты на своей фабрике.

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
4 голосов
/ 14 апреля 2011

Я не уверен, в какой степени фабричный метод шаблон проектирования полезен в функциональном программировании. Цель шаблона - скрыть создание объектов, чтобы вы могли работать только с абстрактным представлением объекта.

  • Когда вы используете F # функциональным способом , большую часть времени вы будете использовать конкретные представления. Например, это дает вам возможность сопоставить шаблон по типу скейтборда.
  • Конечно, F # позволяет смешивать функциональный стиль с объектно-ориентированным стилем. В некоторых целях стиль ОО хорошо работает в 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, чтобы превратить конкретный тип в абстрактный тип.

Это вполне соответствует обычному подходу в функциональном программировании - вы часто используете различные представления одних данных и выполняете преобразования между ними (в зависимости от того, какое представление лучше для конкретной задачи).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...