Recommendations
Recommendations for object-oriented programming
Last updated
Was this helpful?
Recommendations for object-oriented programming
Last updated
Was this helpful?
Inference works better with function (object)
than object.Member
ā Avoid inheritance
ā Prefer type Union and exhaustive pattern matching
This is particularly true for recursive types. You can define a fold
function for them.
š , F# for fun and profit
ā Avoid class (reference equality by default)
ā Prefer a Record or a Union
š Alternatively, consider Struct for performance purposes
ā Consider custom structural equality for performance purposes š , Compositional IT
Encapsulate mutable state ā in a class
Group features ā in an interface
Expressive, user-friendly API ā tuplified methods
API F⯠consumed in C⯠ā member extensions
Dependency management ā injection into the constructor
Tackle higher-order functions limits
serialize
and deserialize
form a consistent group
ā Grouping them in an object makes sense
š” Prefer an interface to a Record (not possible with Fable.Remoting
)
Parameters are named in the methods
Object easily instantiated with an object expression
Advantages of OO implementation:
Add
method overloaded vs add2
, add3
functions (2
and 3
= args count)
Single Log
method with retryPolicy
optional parameter
Do not expose this type as is:
š” To make it easier to discover the type and use its features in CāÆ
Put everything in a namespace
Augment type with the functionalities implemented in the companion module
š The API consumed in C⯠is ~equivalent to:
Parametrization of dependencies + partial application
Small-dose approach: few dependencies, few functions involved
Otherwise, quickly tedious to implement and to use
Dependency injection
Inject dependencies into the class constructor
Use these dependencies in methods
š Offers a user-friendly API š
ā Particularly recommended for encapsulating side-effects : ā Connecting to a DB, reading settings...
Dependencies injected in the constructor make sense only if they are used throughout the class.
A dependency used in a single method indicates a design smell.
Dependency rejection = sandwich pattern
Reject dependencies in Application layer, out of Domain layer
Powerful and simple š
... when suitable ā
Free monad + interpreter patter
Pure domain
More complex than the sandwich pattern but working in any case
User-friendly through a dedicated computation expression
Reader monad
Only if hidden inside a computation expression
...
āļø It's better to pass an object than a lambda as a parameter to a higher-order function when:
ā let test (f: float -> float -> string) =...
ā
Solution 1: type wrapping the 2 args float
ā f: Point -> string
with type Point = { X: float; Y: float }
ā
Solution 2: interface + method for named parameters
ā type IPointFormatter = abstract Execute : x:float -> y:float -> string
'T -> unit
ā
Prefer to trigger an side-effect via an object
ā type ICommand = abstract Execute : 'T -> unit
ā Solution: wrap the function in an object
š
š , F# for Fun and Profit, Dec 2020