F # - Factory Method Design Scheme

Below, I tried to implement the factory method design pattern using F #, trying to make it a little more functional (i.e. not a direct OO implementation). Below 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 a suitable implementation of a factory method design pattern? Is the template used in real F # applications?

+4
source share
2 answers

I'm not sure how useful the factory pattern template is in functional programming. The purpose of the template is to hide the creation of objects so that you can only work with the abstract representation of the object.

  • When you use F # in a functional way, you will use specific views most of the time. For example, this gives you the option to match a template by type of skateboard.
  • Of course, F # lets you mix a functional style with an object-oriented style. For some purposes, the OO style works well in F #. In this case, your approach seems quite reasonable.

Your factory method may take a specific type (e.g., a discriminated union) as an argument instead of a string. Then the factory’s task is to build an abstract view from a specific view:

 // Abstract representation of the data type ISkateBoard = abstract Model : unit -> string // Concrete representation of the data type SkateBoard = | Roskopp | Peters 

Now the factory will be just a function like 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 the advantage of this approach is that you can do some work on a specific type representation (for example, some calculation where you need pattern matching), but then you can use a factory to turn a particular type into an abstract type.

This is in good agreement with the usual approach to functional programming - you often use different representations of individual data and transform them among themselves (depending on which representation is better for a particular problem).

+4
source

Along with what Thomas said, using specific types allows you to sanitize your input and crash before you start creating objects with the factory.

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

You will find many design patterns from OO that simply disappear into functional programming.

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

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

You can simply assign assemble due to first class functions.

 let SantaCruzFactory = assemble 
+4
source

Source: https://habr.com/ru/post/1348083/


All Articles