Skip to content

Instantly share code, notes, and snippets.

@gbougeard
Created August 13, 2014 15:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gbougeard/0efc2d07497aa6363de2 to your computer and use it in GitHub Desktop.
Save gbougeard/0efc2d07497aa6363de2 to your computer and use it in GitHub Desktop.
Règles métiers et abstraction
Etant donnée la structure de données T suivante :
(id, type, montant) où type est soit AE (A emporter) ou SP (sur place).
Etant données les régles métiers suivantes pour un calcul de TVA :
RM1 : pout toute donnée T de type AE, la TVA est de 5%
RM2: pour tout donéne T de type SP la TVA est de 10%
1 - Comment implémentez-vous l'application de ces règles métiers sur
une liste de données T issue d'une base de données
2- Idem mais en entrée et en sortie on a du json
@elecharny
Copy link

@bartavelle Tâche mécanique donc pénible. Bien sûr avec les IDE dont on dispose, c'est généralement pris en charge automatiquement, mais tu as parfois besoin de te taper la modif dans un éditeur de texte pur.

La règle métier est spécifique à chaque objet. Le fait d'avoir un gros switch en lieu et place de méthodes dédiées n'est aucunement un avantage, surtout en terme de lisibilité si ta méthode métier fait plus que prix x 1.05. Rien ne t'oblige par ailleurs à coller les parties communes dans la classe mère, mais si tu le fais, le risque d'oublier un des cas dans une des alternatives de ton switch est bien borné.

Non, tu n'est jamais obligé d'écrire un accesseur en Java. Les champs des classes peuvent être mis en visibilité public (beurk), protected (et accessibles par les classes héritées) voire en package protected (et accessibles par les classes de même package.

@bartavelle
Copy link

En haskell en tout cas et j'imagine dans plein d'autres langages le compilo t'indiques si tu oublies un cas dans un switch, donc tu ne peux pas oublier de cas ...

@bartavelle
Copy link

Ce que je veut dire par le fait que c'est une tâche mécanique, c'est qu'elle est certes rébarbative, mais surtout qu'il n'est pas possible de la rater (car sinon ça ne compilerait plus). L'aspect encapsulation n'est pas non plus une spécificité des langages objets, on peut reproduire exactement les mêmes propriétés en fonctionnel, en n'exportant pas les constructeurs en Haskell par exemple.

Le problème de cette approche par héritage est que ça ne compose pas. Disons que je veuille écrire une méthode qui calcule le chiffre d'affaire mensuel. Avec la solution que tu proposes, j'ai deux classes filles "sur place" et "à emporter", qui ont chacune une méthode getPrice et getPriceWithTaxes. Du coup j'ai le choix entre avoir :

  • une méthode statique chiffreAffaireMensuel(List<Commande> commandes, Bool avecOuSansTaxes), mais c'est franchement affreux
  • deux méthodes statiques chiffreAffaireMensuelSansTaxes et chiffreAffaireMensuelAvecTaxes

Admettons maintenant que je sois comptable et que je souhaite avoir le détail après que diverses autres taxes aient été prélevées, et le seul moyen de m'en sortir sans hurler c'est justement d'introduire un "objet fonction".

Et si je veux ajouter une taxe, je dois modifier les classes SP et AE. Donc je ne peux pas la livrer comme une bibliothèque sans y adjoindre des tonnes d'options qui permettront à l'utilisateur final de s'en servir dans un contexte non prévu.

Et comme on est vendredi, j'ajouterais que c'est pour cette raison que toutes les libs Java qui rencontrent du succès de retrouvent transformées en usines à gaz, justement en raison de ce problème de non composabilité.

@BernardNotarianni
Copy link

-module (tva).
-export ([calcul/1]).

calcul (List) ->
    [ tva (I,T,M) || {I,T,M} <- List ].

tva (_, Type, Montant) ->
    taux_tva (Type) * Montant.

taux_tva (ae) ->
    0.05;
taux_tva (sp) ->
    0.10.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment