Il y a 9 ans -
Temps de lecture 1 minute
Screencast Bonus Calculator
On entend souvent dire que l’héritage c’est le mal. Mais quelles sont les justifications à ce type d’assertions ? Pourquoi faut-il favoriser la composition plutôt que l’héritage ? Avec ce screencast vous allez pouvoir observer une application concrète de ce principe. Diego et Sébastian se livrent à un ping pong TDD afin d’aboutir à un code plus maintenable et plus évolutif.
Si vous voulez faire l’exercice vous-même, les sources sont disponibles sur GitHub.
Pour ceux qui se poseraient la question : nous employons parfois le terme de P.O. : il s’agit de l’acronyme de Product Owner et matérialise le rôle du détenteur du produit. Il connait les fonctionnalités de son produit et sait quelles modifications apporter pour augmenter sa valeur.
Commentaire
4 réponses pour " Screencast Bonus Calculator "
Published by Macaque , Il y a 9 ans
Je trouve l’exemple mal choisie, la méthodologie et le résultat criticable.
A la fin le « / 100 » par exemple est toujours dupliqué.
Ici le calcul de bonus est le même pour tous les employées, seul le pourcentage change et le calcul de bonus n’est pas utilisé ailleurs.
L’exemple ne montre pas pourquoi favorise la composition par rapport à l’héritage, il montre juste comment mal utilisé l’héritage.
Je pense que la logique voudrait de faire une classe employée du genre :
public class Employee {
private double pourcentageBonus;
public Employee(String name) {
this(name, DEFAULT_BONUS);
}
public Employee(String name, double percentageBonus) {
this.name = name;
this.percentageBonus = percentageBonus;
}
public double calculateBonus(double turnover) {
return turnover * percentageBonus / 100;
}
}
ou encore :
public class Employee {
[…]
protected abstract double getPercentageBonus();
public double calculateBonus(double turnover) {
return turnover * getPercentageBonus() / 100;
}
}
Et d’avoir quelquel part 3 constantes définies pour les bonus min, medium et max.
Published by Sébastian Le Merdy , Il y a 9 ans
Ce qu’on veux montrer avec cette vidéo, c’est qu’on a découplé le calcul du bonus de la classe Employee elle même car la notion d’Employee n’est pas liée à celle de BonusCalculator. Pour justifier pleinement la composition, il manque sans doute des formules de calcul différentes.
D’un point de vue responsabilité dans la solution que tu proposes, on est obligé d’instancier des Employee pour vérifier le calcul des bonus. Dans la solution de la vidéo, on vérifie ces calculs indépendamment.
Published by Macaque , Il y a 9 ans
Découplé le calcul du bonus de la classe Employee n’est pas une mauvaise chose mais ce n’est pas le premier problème qui me vient à l’esprit en voyant les classes de départ, surtout que ce calcul de bonus n’a aucune complexité et qu’il n’est indiqué comme étant employé que dans la classe Employee.
Votre énoncé laisse entendre que vous opposez héritage et composition, les deux sont complémentaires.
Ici en fait même en découplant le calcul de la classe employée il serait logique d’avoir de l’héritage sur la classe Bonus, puisque la formule de calcul du bonus est unique.
Je trouve qu’il est nuisible d’avoir des classes différentes dont la seul différence est la valeur d’une constante, comme c’est le cas pour les bonus calculator. C’est autant de risque d’erreur et niveau test vous avez autant de classe de calcul de bonus à tester qu’il y aura de catégorie de bonus. (La il n’y en a que trois mais c’est le genre de chose qui peut facilement se multiplier.)
Si j’avais voulu découplé le calcul du bonus comme dans votre exemple et distinguer le calcul du bonus MAX, MIN et MEDIUM, je pense que je serai parti sur une solution du genre :
public class FixedPercentageBonusCalculator implements BonusCalculator {
private static final double BONUS_MIN_PERCENTAGE = 0.01;
private static final double BONUS_MEDIUM_PERCENTAGE = 0.02;
private static final double BONUS_MAX_PERCENTAGE = 0.03;
public static final Bonus BONUS_MIN_CALCULATOR = new BonusCalculator(BONUS_MIN_PERCENTAGE);
public static final Bonus BONUS_MEDIUM_CALCULATOR = new BonusCalculator(BONUS_MEDIUM_PERCENTAGE);
public static final Bonus BONUS_MAX_CALCULATOR = new BonusCalculator(BONUS_MAX_PERCENTAGE);
private double bonusPercentage;
public BonusCalculator(int bonusPercentage) {
this.bonusPercentage = bonusPercentage;
}
public double calculateBonus(double turnover) {
return turnover * bonusPercentage;
}
}
J’aurais mis un attribut privé final pour le bonus Calculator dans Employee avec un constructeur qui le prend en paramètre pour que les classes filles puissent en définir un autre.
Mais bon il y a toujours 100 000 façons de coder la même chose, chacun voit ces besoins.
Published by Macaque , Il y a 9 ans
Oups, quelques erreurs à corriger, avec :
public static final BonusCalculator BONUS_MIN_CALCULATOR = new FixedPercentageBonusCalculator(BONUS_MIN_PERCENTAGE);
public static final BonusCalculator BONUS_MEDIUM_CALCULATOR = new FixedPercentageBonusCalculator(BONUS_MEDIUM_PERCENTAGE);
public static final BonusCalculator BONUS_MAX_CALCULATOR = new FixedPercentageBonusCalculator(BONUS_MAX_PERCENTAGE);
ça serait mieux (un ide c’est quand même plus pratique pour développer qu’un text-area ^^).