Recommandations
Recommandations pour l'orienté-objet
Pas d'orienté-objet là où F♯ est bon
Inférence marche mieux avec une expression telle que fonction(objet)
que objet.membre
Hiérarchie simple d'objets
❌ Éviter héritage
✅ Préférer type Union et pattern matching exhaustif, + simple en général
En particulier les types récursifs comme les arbres, épaulés par fonction
fold
https://fsharpforfunandprofit.com/series/recursive-types-and-folds/
Égalité structurelle
❌ Éviter classe (égalité par référence par défaut)
✅ Préférer un Record ou une Union
❓ Envisager égalité structurelle custom / performance
https://www.compositional-it.com/news-blog/custom-equality-and-comparison-in-f/
Orienté-objet recommandé
Encapsuler état mutable → dans une classe
Grouper fonctionnalités → dans une interface
API expressive et user-friendly → méthodes tuplifiées
API F♯ consommée en C♯ → membres d'extension
Gestion des dépendances → injection dans constructeur
Dépasser limites des fonctions d'ordre supérieur
Classe pour encapsuler un état mutable
Interface pour grouper des fonctionnalités
serialize
et deserialize
forment un groupe cohérent → Les grouper dans un objet
💡 Préférer une interface à un Record
Paramètres sont nommés dans les méthodes
Objet facilement instanciable avec une expression objet
API expressive
Méthode
Add
surchargée vsadd2
,add3
Une seule méthode
Log
avec paramètre optionnelretryPolicy
API F♯ consommée en C♯ - Type
Ne pas exposer ce type tel quel :
💡 Pour faciliter la découverte du type et l'usage de ses fonctionnalités en C♯
Mettre le tout dans un namespace
Augmenter le type avec fonctionnalités du module compagnon
👉 L'API consommée en C♯ est +/- équivalente à :
Gestion des dépendances
Technique FP
Paramétrisation des dépendances + application partielle
Marche à petite dose : peu de dépendances, peu de fonctions concernées
Sinon, vite pénible à coder et à utiliser 🥱
Technique OO
Injection de dépendances
Injecter les dépendances dans le constructeur de la classe
Utiliser ces dépendances dans les méthodes
👉 Offre une API + user-friendly 👍
✅ Particulièrement recommandé pour encapsuler des effets de bord :
Connexion à une BDD, lecture de settings...
Techniques FP++
Dependency rejection = pattern sandwich
Rejeter dépendances dans couche Application, hors de couche Domaine
Puissant et simple 👍
... quand c'est adapté ❗
Monade Reader
Pour fans de Haskell, sinon trop disruptif 😱
Limites des fonctions d'ordre supérieur
Mieux vaut passer un objet plutôt qu'une lambda en paramètre d'une fonction d'ordre supérieure dans certains cas :
Lambda est une commande 'T -> unit
'T -> unit
✅ Préférer déclencher un effet de bord via un objet :
type ICommand = abstract Execute : 'T -> unit
Arguments de la lambda pas explicites
❌
let test (f: float -> float -> string) =...
✅ Solution 1 : type wrappant les 2 args
float
:f: Point -> string
avectype Point = { X: float; Y: float }
✅ Solution 2 : interface + méthode pour avoir paramètres nommés :
type IXxx = abstract Execute : x:float -> y:float -> string
Lambda "vraiment" générique
✅ Solution : wrapper la fonction dans un objet
Dernière mise à jour
Cet article vous a-t-il été utile ?