SlideShare a Scribd company logo
1 of 85
Download to read offline
Les classes abstraites,
c’est fini !
(et c’est la faute à TDD)
@DorraBartaguiz
http://www.nickelodeonjunior.fr/dora-l-exploratrice/
Dora l’exploratrice
@DorraBartaguiz
Dorra Bartaguiz
Dev / Craft coach
Co-auteure & illustratrice
@DorraBartaguiz
iAmDorra
@DorraBartaguiz
Dorra Bartaguiz
Rédactrice en chef du numéro 250
100 % féminin
Janvier 2022
@DorraBartaguiz
iAmDorra
@DorraBartaguiz
Discussion
Livre « Software Craft » - Edition Dunod
@DorraBartaguiz
Besoin métier
@DorraBartaguiz
Contexte
• Chaine de garagistes (France & Luxembourg)
• Calcul total d’une prestation à partir d’un montant hors taxe
• Calcul de la taxe en fonction du pays
• France 19.6%
• Luxembourg 15% sur le matériel & 12% sur le service
@DorraBartaguiz
Exemple
• En France
• 150€ HT & 19.6% taxe
• Total : 179,4€ TTC
• Au Luxembourg
• 100€ HT de matériel & 15% taxe de matériel => total matériel : 115€
• 50€ HT de service & 12% taxe de service => total service : 56€
• Total : 171€
@DorraBartaguiz
TDD
Test Driven Development
@DorraBartaguiz
TDD
• Kent Beck – 1990
• Ecrire le code de test avant le code de production
• Fixer l’objectif du besoin
• Définir à l’avance le comportement attendu
@DorraBartaguiz
TDD
@DorraBartaguiz
Besoin du garagiste
• En France
• 150€ HT & 19.6% taxe
• Total : 179,4€ TTC
• Au Luxembourg
• 100€ HT de matériel & 15% taxe de matériel => total matériel : 115€
• 50€ HT de service & 12% taxe de service => total service : 56€
• Total : 171€
@DorraBartaguiz
Disclaimer
@DorraBartaguiz
Garagiste en France
• 150€ HT & 19.6% taxe
• Total : 179,4€ TTC
Calculate_total_price_including_tax_for_french_mechanic()
{
var frenchTax = 0.196;
var preTaxPrice = 150;
var frenchPrice = new FrenchPrice(frenchTax, preTaxPrice);
var total = frenchPrice.CalculateTotal();
Check.That(total).IsEqualTo(179.4);
}
@DorraBartaguiz
Garagiste en France
• 150€ HT & 19.6% taxe
=> Total : 179,4€ TTC FrenchPrice
-preTaxPrice
-tax
+CalculateTotal()
public double CalculateTotal()
{
return preTaxPrice + preTaxPrice * tax;
}
@DorraBartaguiz
Garagiste au Luxembourg
• 100€ HT de matériel & 15% taxe de matériel => total matériel : 115€
• 50€ HT de service & 12% taxe de service => total service : 56€
• Total : 171€
Calculate_total_price_including_tax_for_luxembourgish_mechanic()
{
var preTaxServiceAmount = 50;
var serviceTax = 0.12;
var preTaxMaterialAmount = 100;
var materialTax = 0.15;
var luxembourgishPrice = new LuxembourgishPrice(preTaxServiceAmount, serviceTax,
preTaxMaterialAmount, materialTax);
var total = luxembourgishPrice.CalculateTotal();
Check.That(total).IsEqualTo(171);
}
@DorraBartaguiz
Garagiste au Luxembourg
• 100€ HT de matériel
• 15% taxe de matériel
=> total matériel : 115€
• 50€ HT de service
• 12% taxe de service
=> total service : 56€
=> Total : 171€
LuxembourgishPrice
-preTaxServiceAmount
-serviceTax
-preTaxMaterialAmount
-materialTax
+CalculateTotal()
public double CalculateTotal()
{
return CalculateVat() +
CalculatePreTaxAmount();
}
private double CalculateVat()
{
return preTaxServiceAmount * serviceTax +
preTaxMaterialAmount * materialTax;
}
private double CalculatePreTaxAmount()
{
return preTaxServiceAmount +
preTaxMaterialAmount;
}
@DorraBartaguiz
<<Interface>>
Price
+CalculateTotal()
FrenchPrice
-preTaxPrice
-tax
+CalculateTotal()
LuxembourgishPrice
-preTaxServiceAmount
-serviceTax
-preTaxMaterialAmount
-materialTax
+CalculateTotal()
public double CalculateTotal()
{
return preTaxPrice + preTaxPrice * tax;
}
public double CalculateTotal()
{
return CalculateVat() +
CalculatePreTaxAmount();
}
private double CalculateVat()
{
return preTaxServiceAmount * serviceTax +
preTaxMaterialAmount * materialTax;
}
private double CalculatePreTaxAmount()
{
return preTaxServiceAmount +
preTaxMaterialAmount;
}
@DorraBartaguiz
<<Interface>>
Price
+CalculateAmount()
FrenchPrice
-preTaxAmount
-tax
#CalculateVat()
#CalculatePreTaxAmount()
<<Abstract>>
BasePrice
+CalculateTotal()
#CalculateVat()
#CalculatePreTaxAmount()
LuxembourgishPrice
-preTaxServiceAmount
-serviceTax
-preTaxMaterialAmount
-materialTax
#CalculateVat()
#CalculatePreTaxAmount()
protected override double CalculateVat()
{
return preTaxAmount * tax;
}
protected override double CalculatePreTaxAmount()
{
return preTaxAmount;
}
public double CalculateTotal()
{
return CalculateVat() + CalculatePreTaxAmount();
}
protected abstract double CalculateVat();
protected abstract double CalculatePreTaxAmount();
protected override double CalculateVat()
{
return preTaxServiceAmount * serviceTax +
preTaxMaterialAmount * materialTax;
}
protected override double CalculatePreTaxAmount()
{
return preTaxServiceAmount +
preTaxMaterialAmount;
}
https://fr.wikipedia.org/wiki/Classe_abstraite
@DorraBartaguiz
<<Interface>>
Price
+CalculateAmount()
FrenchPrice
-preTaxAmount
-tax
#CalculateVat()
#CalculatePreTaxAmount()
<<Abstract>>
BasePrice
+CalculateTotal()
#CalculateVat()
#CalculatePreTaxAmount()
LuxembourgishPrice
-preTaxServiceAmount
-serviceTax
-preTaxMaterialAmount
-materialTax
#CalculateVat()
#CalculatePreTaxAmount()
protected override double CalculateVat()
{
return preTaxAmount * tax;
}
protected override double CalculatePreTaxAmount()
{
return preTaxAmount;
}
public double CalculateTotal()
{
return CalculateVat() + CalculatePreTaxAmount();
}
protected abstract double CalculateVat();
protected abstract double CalculatePreTaxAmount();
protected override double CalculateVat()
{
return preTaxServiceAmount * serviceTax +
preTaxMaterialAmount * materialTax;
}
protected override double CalculatePreTaxAmount()
{
return preTaxServiceAmount +
preTaxMaterialAmount;
}
« Design Patterns: Elements of Reusable Object-Oriented Software » écrit par Erich Gamma, Richard Helm, Ralph Johnson, et John Vlissides, avec une préface de Grady Booch
@DorraBartaguiz
<<Interface>>
Price
+CalculateAmount()
FrenchPrice
-preTaxAmount
-tax
#CalculateVat()
#CalculatePreTaxAmount()
<<Abstract>>
BasePrice
+CalculateTotal()
#CalculateVat()
#CalculatePreTaxAmount()
LuxembourgishPrice
-preTaxServiceAmount
-serviceTax
-preTaxMaterialAmount
-materialTax
#CalculateVat()
#CalculatePreTaxAmount()
protected override double CalculateVat()
{
return preTaxAmount * tax;
}
protected override double CalculatePreTaxAmount()
{
return preTaxAmount;
}
public double CalculateTotal()
{
return CalculateVat() + CalculatePreTaxAmount();
}
protected abstract double CalculateVat();
protected abstract double CalculatePreTaxAmount();
protected override double CalculateVat()
{
return preTaxServiceAmount * serviceTax +
preTaxMaterialAmount * materialTax;
}
protected override double CalculatePreTaxAmount()
{
return preTaxServiceAmount +
preTaxMaterialAmount;
}
@DorraBartaguiz
<<Interface>>
Price
+CalculateAmount()
FrenchPrice
-preTaxAmount
-tax
#CalculateVat()
#CalculatePreTaxAmount()
<<Abstract>>
BasePrice
+CalculateTotal()
#CalculateVat()
#CalculatePreTaxAmount()
LuxembourgishPrice
-preTaxServiceAmount
-serviceTax
-preTaxMaterialAmount
-materialTax
#CalculateVat()
#CalculatePreTaxAmount()
protected override double CalculateVat()
{
return preTaxAmount * tax;
}
protected override double CalculatePreTaxAmount()
{
return preTaxAmount;
}
public double CalculateTotal()
{
return CalculateVat() + CalculatePreTaxAmount();
}
protected abstract double CalculateVat();
protected abstract double CalculatePreTaxAmount();
protected override double CalculateVat()
{
return preTaxServiceAmount * serviceTax +
preTaxMaterialAmount * materialTax;
}
protected override double CalculatePreTaxAmount()
{
return preTaxServiceAmount +
preTaxMaterialAmount;
}
Non
instanciable !
@DorraBartaguiz
<<Interface>>
Price
+CalculateAmount()
FrenchPrice
-preTaxAmount
-tax
#CalculateVat()
#CalculatePreTaxAmount()
<<Abstract>>
BasePrice
+CalculateTotal()
#CalculateVat()
#CalculatePreTaxAmount()
LuxembourgishPrice
-preTaxServiceAmount
-serviceTax
-preTaxMaterialAmount
-materialTax
#CalculateVat()
#CalculatePreTaxAmount()
protected override double CalculateVat()
{
return preTaxAmount * tax;
}
protected override double CalculatePreTaxAmount()
{
return preTaxAmount;
}
public double CalculateTotal()
{
return CalculateVat() + CalculatePreTaxAmount();
}
protected abstract double CalculateVat();
protected abstract double CalculatePreTaxAmount();
protected override double CalculateVat()
{
return preTaxServiceAmount * serviceTax +
preTaxMaterialAmount * materialTax;
}
protected override double CalculatePreTaxAmount()
{
return preTaxServiceAmount +
preTaxMaterialAmount;
}
Tester
unitairement les
sous calculs ?!
@DorraBartaguiz
<<Interface>>
Price
+CalculateAmount()
FrenchPrice
-preTaxAmount
-tax
#CalculateVat()
#CalculatePreTaxAmount()
<<Abstract>>
BasePrice
+CalculateTotal()
#CalculateVat()
#CalculatePreTaxAmount()
LuxembourgishPrice
-preTaxServiceAmount
-serviceTax
-preTaxMaterialAmount
-materialTax
#CalculateVat()
#CalculatePreTaxAmount()
protected override double CalculateVat()
{
return preTaxAmount * tax;
}
protected override double CalculatePreTaxAmount()
{
return preTaxAmount;
}
public double CalculateTotal()
{
return CalculateVat() + CalculatePreTaxAmount();
}
protected abstract double CalculateVat();
protected abstract double CalculatePreTaxAmount();
protected override double CalculateVat()
{
return preTaxServiceAmount * serviceTax +
preTaxMaterialAmount * materialTax;
}
protected override double CalculatePreTaxAmount()
{
return preTaxServiceAmount +
preTaxMaterialAmount;
}
Le même test
se répète !
@DorraBartaguiz
Supprimer du code,
jamais de la vie !
On le garde au cas où !
@DorraBartaguiz
<<Interface>>
Price
+CalculateAmount()
FrenchPrice
-preTaxAmount
-tax
#CalculateVat()
#CalculatePreTaxAmount()
<<Abstract>>
BasePrice
+CalculateTotal()
#CalculateVat()
#CalculatePreTaxAmount()
LuxembourgishPrice
-preTaxServiceAmount
-serviceTax
-preTaxMaterialAmount
-materialTax
#CalculateVat()
#CalculatePreTaxAmount()
protected override double CalculateVat()
{
return preTaxAmount * tax;
}
protected override double CalculatePreTaxAmount()
{
return preTaxAmount;
}
public double CalculateTotal()
{
return CalculateVat() + CalculatePreTaxAmount();
}
protected abstract double CalculateVat();
protected abstract double CalculatePreTaxAmount();
protected override double CalculateVat()
{
return preTaxServiceAmount * serviceTax +
preTaxMaterialAmount * materialTax;
}
protected override double CalculatePreTaxAmount()
{
return preTaxServiceAmount +
preTaxMaterialAmount;
}
Le même test
se répète !
@DorraBartaguiz
<<Interface>>
Price
+CalculateAmount()
FrenchPrice
-preTaxAmount
-tax
#CalculateVat()
#CalculatePreTaxAmount()
<<Abstract>>
BasePrice
+CalculateTotal()
#CalculateVat()
#CalculatePreTaxAmount()
LuxembourgishPrice
-preTaxServiceAmount
-serviceTax
-preTaxMaterialAmount
-materialTax
#CalculateVat()
#CalculatePreTaxAmount()
protected override double CalculateVat()
{
return preTaxAmount * tax;
}
protected override double CalculatePreTaxAmount()
{
return preTaxAmount;
}
public double CalculateTotal()
{
return CalculateVat() + CalculatePreTaxAmount();
}
protected abstract double CalculateVat();
protected abstract double CalculatePreTaxAmount();
protected override double CalculateVat()
{
return preTaxServiceAmount * serviceTax +
preTaxMaterialAmount * materialTax;
}
protected override double CalculatePreTaxAmount()
{
return preTaxServiceAmount +
preTaxMaterialAmount;
}
Couplage
Dépendance
@DorraBartaguiz
USA
Tips = 10% du Total TTC
<<Interface>>
Price
+CalculateAmount()
FrenchPrice
-preTaxAmount
-tax
#CalculateVat()
#CalculatePreTaxAmount()
<<Abstract>>
BasePrice
+CalculateTotal()
#CalculateVat()
#CalculatePreTaxAmount()
LuxembourgishPrice
-preTaxServiceAmount
-serviceTax
-preTaxMaterialAmount
-materialTax
#CalculateVat()
#CalculatePreTaxAmount()
USAPrice
-preTaxAmount
-tax
#CalculateVat()
#CalculatePreTaxAmount()
protected override double CalculateVat()
{
return preTaxAmount * tax;
}
protected override double CalculatePreTaxAmount()
{
return preTaxAmount;
}
public double CalculateTotal()
{
return CalculateVat() + CalculatePreTaxAmount();
}
protected abstract double CalculateVat();
protected abstract double CalculatePreTaxAmount();
protected override double CalculateVat()
{
return preTaxServiceAmount * serviceTax +
preTaxMaterialAmount * materialTax;
}
protected override double CalculatePreTaxAmount()
{
return preTaxServiceAmount +
preTaxMaterialAmount;
}
@DorraBartaguiz
<<Interface>>
Price
+CalculateAmount()
FrenchPrice
-preTaxAmount
-tax
#CalculateVat()
#CalculatePreTaxAmount()
<<Abstract>>
BasePrice
+CalculateTotal()
#CalculateVat()
#CalculatePreTaxAmount()
LuxembourgishPrice
-preTaxServiceAmount
-serviceTax
-preTaxMaterialAmount
-materialTax
#CalculateVat()
#CalculatePreTaxAmount()
USAPrice
-preTaxAmount
-tax
#CalculateVat()
#CalculatePreTaxAmount()
protected override double CalculateVat()
{
return preTaxAmount * tax;
}
protected override double CalculatePreTaxAmount()
{
return preTaxAmount;
}
public double CalculateTotal()
{
if(this.GetType() == typeof(USAPrice))
{
var total = CalculateVat() + CalculatePreTaxAmount();
return total + total * 0.10;
}
return CalculateVat() + CalculatePreTaxAmount();
}
protected abstract double CalculateVat();
protected abstract double CalculatePreTaxAmount();
protected override double CalculateVat()
{
return preTaxServiceAmount * serviceTax +
preTaxMaterialAmount * materialTax;
}
protected override double CalculatePreTaxAmount()
{
return preTaxServiceAmount +
preTaxMaterialAmount;
}
@DorraBartaguiz
<<Interface>>
Price
+CalculateAmount()
FrenchPrice
-preTaxAmount
-tax
#CalculateVat()
#CalculatePreTaxAmount()
<<Abstract>>
BasePrice
+CalculateTotal()
#CalculateVat()
#CalculatePreTaxAmount()
LuxembourgishPrice
-preTaxServiceAmount
-serviceTax
-preTaxMaterialAmount
-materialTax
#CalculateVat()
#CalculatePreTaxAmount()
USAPrice
-preTaxAmount
-tax
#CalculateVat()
#CalculatePreTaxAmount()
protected override double CalculateVat()
{
return preTaxAmount * tax;
}
protected override double CalculatePreTaxAmount()
{
return preTaxAmount;
}
public virtual double CalculateTotal()
{
return CalculateVat() + CalculatePreTaxAmount();
}
protected abstract double CalculateVat();
protected abstract double CalculatePreTaxAmount();
protected override double CalculateVat()
{
return preTaxServiceAmount * serviceTax +
preTaxMaterialAmount * materialTax;
}
protected override double CalculatePreTaxAmount()
{
return preTaxServiceAmount +
preTaxMaterialAmount;
}
public override double CalculateTotal()
{
var total = CalculateVat() + CalculatePreTaxAmount();
// var total = base.CalculateTotal();
return total + total * 0.10;
}
protected override double CalculateVat()
{
return preTaxAmount * tax;
}
protected override double CalculatePreTaxAmount()
{
return preTaxAmount;
}
@DorraBartaguiz
SOLID
Principe de substitution de
Liskov
@DorraBartaguiz
Classe abstraite
Non
instanciable !
Le même test
se répète !
Couplage
Dépendance
@DorraBartaguiz
Les classes abstraites,
c’est fini !
(et c’est la faute à TDD)
@DorraBartaguiz
TDD
@DorraBartaguiz
Décomposition Exemples
Priorisation Baby steps
Prérequis
@DorraBartaguiz
Besoin du garagiste
• En France
• 150€ HT & 19.6% taxe
• Total : 179,4€ TTC
• Au Luxembourg
• 100€ HT de matériel & 15% taxe de matériel => total matériel : 115€
• 50€ HT de service & 12% taxe de service => total service : 56€
• Total : 171€
@DorraBartaguiz
Décomposer
@DorraBartaguiz
Identifier les composants
Somme HT et Taxe
Total hors taxe
Total
Calcul montant HT
France
Calcul montant HT
Luxembourg
Calcul taxe France
Calcul taxe Luxembourg
Total taxe
Calcul taxe
Calcul montant HT
Calcul Total
Montant hors taxe
Taxe
Montant hors taxe
Montant hors taxe service
Montant hors taxe matériel
Montant hors taxe service
Taxe service
Taxe matériel
Montant hors taxe matériel
@DorraBartaguiz
Identifier les composants
• Calcul du total
• Calcul du montant HT
• France
• Luxembourg
• Calcul de la taxe
• France
• Luxembourg
@DorraBartaguiz
Inside out
vs
Outside in
@DorraBartaguiz
Inside out
Classic approach Chicago school
Bottom up
@DorraBartaguiz
Inside out
Livre « Software Craft » - Edition Dunod
@DorraBartaguiz
Inside out
Somme HT et Taxe
Total hors taxe
Total
Calcul montant HT
France
Calcul montant HT
Luxembourg
Calcul taxe France
Calcul taxe Luxembourg
Total taxe
Calcul taxe
Calcul montant HT
Calcul Total
Montant hors taxe
Taxe
Montant hors taxe
Montant hors taxe service
Montant hors taxe matériel
Montant hors taxe service
Taxe service
Taxe matériel
Montant hors taxe matériel
@DorraBartaguiz
Outside in
Mockist approach London school
Top down
@DorraBartaguiz
Outside in
Livre « Software Craft » - Edition Dunod
@DorraBartaguiz
Outside in
Livre « Software Craft » - Edition Dunod
@DorraBartaguiz
Outside in
Livre « Software Craft » - Edition Dunod
@DorraBartaguiz
Outside in
Livre « Software Craft » - Edition Dunod
@DorraBartaguiz
Outside in
Livre « Software Craft » - Edition Dunod
@DorraBartaguiz
Outside in
Livre « Software Craft » - Edition Dunod
@DorraBartaguiz
Outside in
Somme HT et Taxe
Total hors taxe
Total
Calcul montant HT
France
Calcul montant HT
Luxembourg
Calcul taxe France
Calcul taxe Luxembourg
Total taxe
Calcul taxe
Calcul montant HT
Calcul Total
Montant hors taxe
Taxe
Montant hors taxe
Montant hors taxe service
Montant hors taxe matériel
Montant hors taxe service
Taxe service
Taxe matériel
Montant hors taxe matériel
@DorraBartaguiz
Inside out
vs
Outside in
@DorraBartaguiz
Inside out vs Outside in
Livre « Software Craft » - Edition Dunod
@DorraBartaguiz
Inside out
Somme HT et Taxe
Total hors taxe
Total
Calcul montant HT
France
Calcul montant HT
Luxembourg
Calcul taxe France
Calcul taxe Luxembourg
Total taxe
Calcul taxe
Calcul montant HT
Calcul Total
Montant hors taxe
Taxe
Montant hors taxe
Montant hors taxe service
Montant hors taxe matériel
Montant hors taxe service
Taxe service
Taxe matériel
Montant hors taxe matériel
@DorraBartaguiz
Trouver des exemples
@DorraBartaguiz
Bénéfices des exemples
Exemple
Besoin
attendu
Test
explicite
devient
vérifie
@DorraBartaguiz
Les exemples à consommer
sans modération
@DorraBartaguiz
Calcul montant HT
• 150 € => 150 €
• 10.5 € => 10.5 €
• 0 € => 0 €
• 100 €, 50 € => 150 €
• 100 €, 0 € => 100 €
• 10.5 €, 0 € => 10.5 €
• 0 €, 0 € => 0 €
Calcul montant HT
France
Montant hors taxe Montant hors taxe
Calcul montant HT
Luxembourg
Montant hors taxe service
Montant hors taxe matériel
Montant hors taxe
@DorraBartaguiz
Calcul montant HT
• 150 € => 150 €
• 10.5 € => 10.5 €
• 0 € => 0 €
• 100 €, 50 € => 150 €
• 100 €, 0 € => 100 €
• 10.5 €, 0 € => 10.5 €
• 0 €, 0 € => 0 €
Calcul montant HT
France
Montant hors taxe Montant hors taxe
Calcul montant HT
Luxembourg
Montant hors taxe service
Montant hors taxe matériel
Montant hors taxe
@DorraBartaguiz
Baby steps
L’art d’identifier des exemples pour avancer par petits pas
@DorraBartaguiz
Calcul montant HT
FrenchPrice
+FrenchPrice(double preTaxAmount)
-preTaxAmount
+CalculatePreTaxAmount()
LuxembourgishPrice
+LuxembourgishPrice(
double preTaxServiceAmount,
double preTaxMaterialAmount)
-preTaxServiceAmount
-preTaxMaterialAmount
+CalculatePreTaxAmount()
public double CalculatePreTaxAmount()
{
return preTaxAmount;
}
public double CalculatePreTaxAmount()
{
return preTaxServiceAmount +
preTaxMaterialAmount;
}
@DorraBartaguiz
Calcul taxe
• 150 €, 19.6% => 29.4 €
• 0 €, 19.6% => 0 €
• 100 €, 15%, 50 €, 12% => 21 €
• 100 €, 15%, 0 €, 12% => 15 €
• 0 €, 15%, 0 €, 12% => 0 €
Montant taxe
Calcul taxe France
Taxe
Montant hors taxe
Calcul taxe
Luxembourg
Montant taxe
Montant hors taxe service
Taxe service
Taxe matériel
Montant hors taxe matériel
@DorraBartaguiz
Calcul taxe
• 150 €, 19.6% => 29.4 €
• 0 €, 19.6% => 0 €
• 100 €, 15%, 50 €, 12% => 21 €
• 100 €, 15%, 0 €, 12% => 15 €
• 0 €, 15%, 0 €, 12% => 0 €
Montant taxe
Calcul taxe France
Taxe
Montant hors taxe
Calcul taxe
Luxembourg
Montant taxe
Montant hors taxe service
Taxe service
Taxe matériel
Montant hors taxe matériel
@DorraBartaguiz
Calcul taxe
• 150 €, 19.6% => 29.4 €
• 0 €, 19.6% => 0 €
• 100 €, 15%, 50 €, 12% => 21 €
• 100 €, 15%, 0 €, 12% => 15 €
• 0 €, 15%, 0 €, 12% => 0 €
Montant taxe
Calcul taxe France
Taxe
Montant hors taxe
Calcul taxe
Luxembourg
Montant taxe
Montant hors taxe service
Taxe service
Taxe matériel
Montant hors taxe matériel
@DorraBartaguiz
Calcul taxe
• 0 €, 19.6% => 0 € • 0 €, 15%, 0 €, 12% => 0 €
FrenchPrice
+FrenchPrice(
double preTaxAmount,
double tax)
-preTaxAmount
-tax
+CalculatePreTaxAmount()
+CalculateVat()
public double CalculatePreTaxAmount()
{
return preTaxAmount;
}
public double CalculateVat()
{
return preTaxAmount;
}
LuxembourgishPrice
+LuxembourgishPrice(double preTaxServiceAmount,
double preTaxMaterialAmount,
double serviceTax, double materialTax)
-preTaxServiceAmount
-preTaxMaterialAmount
-serviceTax
-materialTax
+CalculatePreTaxAmount()
+CalculateVat()
public double CalculatePreTaxAmount()
{
return preTaxServiceAmount +
preTaxMaterialAmount;
}
public double CalculateVat()
{
return preTaxServiceAmount;
}
@DorraBartaguiz
Calcul taxe
• 150 €, 19.6% => 29.4 € • 100 €, 15%, 0 €, 12% => 15 €
FrenchPrice
+FrenchPrice(
double preTaxAmount,
double tax)
-preTaxAmount
-tax
+CalculatePreTaxAmount()
+CalculateVat()
public double CalculatePreTaxAmount()
{
return preTaxAmount;
}
public double CalculateVat()
{
return preTaxAmount * tax;
}
LuxembourgishPrice
+LuxembourgishPrice(double preTaxServiceAmount,
double preTaxMaterialAmount,
double serviceTax, double materialTax)
-preTaxServiceAmount
-preTaxMaterialAmount
-serviceTax
-materialTax
+CalculatePreTaxAmount()
+CalculateVat()
public double CalculatePreTaxAmount()
{
return preTaxServiceAmount +
preTaxMaterialAmount;
}
public double CalculateVat()
{
return preTaxServiceAmount * serviceTax;
}
@DorraBartaguiz
Calcul taxe
• 150 €, 19.6% => 29.4 € • 100 €, 15%, 50 €, 12% => 21 €
FrenchPrice
+FrenchPrice(
double preTaxAmount,
double tax)
-preTaxAmount
-tax
+CalculatePreTaxAmount()
+CalculateVat()
public double CalculatePreTaxAmount()
{
return preTaxAmount;
}
public double CalculateVat()
{
return preTaxAmount * tax;
}
LuxembourgishPrice
+LuxembourgishPrice(double preTaxServiceAmount,
double preTaxMaterialAmount,
double serviceTax, double materialTax)
-preTaxServiceAmount
-preTaxMaterialAmount
-serviceTax
-materialTax
+CalculatePreTaxAmount()
+CalculateVat()
public double CalculatePreTaxAmount()
{
return preTaxServiceAmount +
preTaxMaterialAmount;
}
public double CalculateVat()
{
return preTaxServiceAmount * serviceTax
+ preTaxMaterialAmount * materialTax;
}
@DorraBartaguiz
Somme HT et taxe
• 150 €, 29.4 € => 179.4 €
• 150 €, 0 € => 150 €
Somme HT et Taxe
Total hors taxe Total
Total taxe
@DorraBartaguiz
Somme HT et taxe
• 150 €, 29.4 € => 179.4 €
• 150 €, 0 € => 150 €
TotalCalculator
+CalculateTotal(double preTaxAmount, double taxAmount)
public double CalculateTotal(double preTaxAmount,
double taxAmount)
{
return preTaxAmount + taxAmount;
}
Somme HT et Taxe
Total hors taxe Total
Total taxe
@DorraBartaguiz
Côté appelant
public void CalculateTotalPrice()
{
var preTaxServiceAmount = 50;
var serviceTax = 0.12;
var preTaxMaterialAmount = 100;
var materialTax = 0.15;
var luxembourgishPrice = new LuxembourgishPrice(preTaxServiceAmount, serviceTax,
preTaxMaterialAmount, materialTax);
var preTaxAmount = luxembourgishPrice.CalculatePreTaxAmount();
var taxAmount = luxembourgishPrice.CalculateVat();
var totalCalculator = new TotalCalculator();
var total = totalCalculator.CalculateTotal(preTaxAmount, taxAmount);
Check.That(total).IsEqualTo(171);
}
@DorraBartaguiz
Simplifier l’appelant
public void CalculateTotalPrice_For_Luxembourg()
{
var preTaxServiceAmount = 50;
var serviceTax = 0.12;
var preTaxMaterialAmount = 100;
var materialTax = 0.15;
var luxembourgishPrice = new LuxembourgishPrice(preTaxServiceAmount, serviceTax,
preTaxMaterialAmount, materialTax);
var totalCalculator = new TotalCalculator(luxembourgishPrice);
var totalCalculator.CalculateTotal();
Check.That(total).IsEqualTo(171);
}
@DorraBartaguiz
Simplifier l’appelant
public void CalculateTotalPrice_For_France()
{
var preTaxAmount = 150;
var tax = 0.196;
var frenchPrice = new FrenchPrice(preTaxAmount, tax);
var totalCalculator = new TotalCalculator(frenchPrice);
var totalCalculator.CalculateTotal();
Check.That(total).IsEqualTo(179.4);
}
@DorraBartaguiz
Interface
FrenchPrice
+FrenchPrice(
double preTaxAmount,
double tax)
-preTaxAmount
-tax
+CalculatePreTaxAmount()
+CalculateVat()
LuxembourgishPrice
+LuxembourgishPrice(double preTaxServiceAmount,
double preTaxMaterialAmount,
double serviceTax, double materialTax)
-preTaxServiceAmount
-preTaxMaterialAmount
-serviceTax
-materialTax
+CalculatePreTaxAmount()
+CalculateVat()
<<Interface>>
Price
+CalculatePreTaxAmount()
+CalculateVat()
public double CalculatePreTaxAmount()
{
return preTaxAmount;
}
public double CalculateVat()
{
return preTaxAmount * tax;
}
public double CalculatePreTaxAmount()
{
return preTaxServiceAmount +
preTaxMaterialAmount;
}
public double CalculateVat()
{
return preTaxServiceAmount * serviceTax
+ preTaxMaterialAmount * materialTax;
}
@DorraBartaguiz
Composition
@DorraBartaguiz
Pas de composition
TotalCalculator
+CalculateTotal(double preTaxAmount, double taxAmount)
public double CalculateTotal(double preTaxAmount,
double taxAmount)
{
return preTaxAmount + taxAmount;
}
@DorraBartaguiz
Composition
TotalCalculator
+TotalCalculator(Price price)
-Price price
+CalculateTotal()
public double CalculateTotal()
{
return price.CalculatePreTaxAmount() +
price.CalculateVat();
}
@DorraBartaguiz
Composition
FrenchPrice
+FrenchPrice(
double preTaxAmount,
double tax)
-preTaxAmount
-tax
+CalculatePreTaxAmount()
+CalculateVat()
LuxembourgishPrice
+LuxembourgishPrice(double preTaxServiceAmount,
double preTaxMaterialAmount,
double serviceTax, double materialTax)
-preTaxServiceAmount
-preTaxMaterialAmount
-serviceTax
-materialTax
+CalculatePreTaxAmount()
+CalculateVat()
<<Interface>>
Price
+CalculatePreTaxAmount()
+CalculateVat()
TotalCalculator
+TotalCalculator(Price price)
-Price price
+CalculateTotal()
use
public double CalculatePreTaxAmount()
{
return preTaxAmount;
}
public double CalculateVat()
{
return preTaxAmount * tax;
}
public double CalculatePreTaxAmount()
{
return preTaxServiceAmount +
preTaxMaterialAmount;
}
public double CalculateVat()
{
return preTaxServiceAmount * serviceTax
+ preTaxMaterialAmount * materialTax;
}
public double CalculateTotal()
{
return price.CalculatePreTaxAmount() +
price.CalculateVat();
}
@DorraBartaguiz
<<Interface>>
Price
+CalculateAmount()
FrenchPrice
-preTaxAmount
-tax
#CalculateVat()
#CalculatePreTaxAmount()
<<Abstract>>
BasePrice
+CalculateTotal()
#CalculateVat()
#CalculatePreTaxAmount()
LuxembourgishPrice
-preTaxServiceAmount
-serviceTax
-preTaxMaterialAmount
-materialTax
#CalculateVat()
#CalculatePreTaxAmount()
protected override double CalculateVat()
{
return preTaxAmount * tax;
}
protected override double CalculatePreTaxAmount()
{
return preTaxAmount;
}
public double CalculateTotal()
{
return CalculateVat() + CalculatePreTaxAmount();
}
protected abstract double CalculateVat();
protected abstract double CalculatePreTaxAmount();
protected override double CalculateVat()
{
return preTaxServiceAmount * serviceTax +
preTaxMaterialAmount * materialTax;
}
protected override double CalculatePreTaxAmount()
{
return preTaxServiceAmount +
preTaxMaterialAmount;
}
Non instanciable
Le même test se répète
Couplage
Dépendance
@DorraBartaguiz
FrenchPrice
+FrenchPrice(
double preTaxAmount,
double tax)
-preTaxAmount
-tax
+CalculatePreTaxAmount()
+CalculateVat()
LuxembourgishPrice
+LuxembourgishPrice(double preTaxServiceAmount,
double preTaxMaterialAmount,
double serviceTax, double materialTax)
-preTaxServiceAmount
-preTaxMaterialAmount
-serviceTax
-materialTax
+CalculatePreTaxAmount()
+CalculateVat()
<<Interface>>
Price
+CalculatePreTaxAmount()
+CalculateVat()
TotalCalculator
+TotalCalculator(Price price)
-Price price
+CalculateTotal()
use
public double CalculatePreTaxAmount()
{
return preTaxAmount;
}
public double CalculateVat()
{
return preTaxAmount * tax;
}
public double CalculatePreTaxAmount()
{
return preTaxServiceAmount +
preTaxMaterialAmount;
}
public double CalculateVat()
{
return preTaxServiceAmount * serviceTax
+ preTaxMaterialAmount * materialTax;
}
public double CalculateTotal()
{
return price.CalculatePreTaxAmount() +
price.CalculateVat();
}
Tout est instanciable
Pas de test qui se répète
Dépendance inversée
@DorraBartaguiz
Pourboires = Total TTC + 10%
FrenchPrice
+FrenchPrice(
double preTaxAmount,
double tax)
-preTaxAmount
-tax
+CalculatePreTaxAmount()
+CalculateVat()
LuxembourgishPrice
+LuxembourgishPrice(double preTaxServiceAmount,
double preTaxMaterialAmount,
double serviceTax, double materialTax)
-preTaxServiceAmount
-preTaxMaterialAmount
-serviceTax
-materialTax
+CalculatePreTaxAmount()
+CalculateVat()
<<Interface>>
Price
+CalculatePreTaxAmount()
+CalculateVat()
DefaultTotalCalculator
+DefaultTotalCalculator(Price price)
-price
+CalculateTotal()
USAPrice
-preTaxAmount
-tax
#CalculateVat()
#CalculatePreTaxAmount()
<<Interface>>
TotalCalculator
+CalculateTotal()
TotalCalculatorWithTips
+TotalCalculatorWithTips(Price price)
-price
-tips
+CalculateTotal()
public double CalculatePreTaxAmount()
{
return preTaxAmount;
}
public double CalculateVat()
{
return preTaxAmount * tax;
}
public double CalculatePreTaxAmount()
{
return preTaxServiceAmount +
preTaxMaterialAmount;
}
public double CalculateVat()
{
return preTaxServiceAmount * serviceTax
+ preTaxMaterialAmount * materialTax;
}
public double CalculateTotal()
{
return price.CalculatePreTaxAmount() +
price.CalculateVat();
}
public double CalculateTotal()
{
var total = price.CalculatePreTaxAmount() +
price.CalculateVat();
return total + total * tips;
}
@DorraBartaguiz
Composition
over
Inheritance
« Design Patterns: Elements of Reusable Object-Oriented Software »
écrit par Erich Gamma, Richard Helm, Ralph Johnson, et John Vlissides,
avec une préface de Grady Booch
@DorraBartaguiz
Composition
@DorraBartaguiz
Make big things from small things in the same way.
That’s the power of composition.
Scott Wlaschin
Les classes abstraites,
c’est fini !
(et c’est la faute à TDD)
Baby steps Composition
@DorraBartaguiz
Buy the book!
@DorraBartaguiz
Merci !
https://roti.express/r/alp-19
@DorraBartaguiz

More Related Content

Similar to Les classes abstraites c’est fini (et c’est la faute à TDD)

Programming For Big Data [ Submission DvcScheduleV2.cpp and StaticA.pdf
Programming For Big Data [ Submission DvcScheduleV2.cpp and StaticA.pdfProgramming For Big Data [ Submission DvcScheduleV2.cpp and StaticA.pdf
Programming For Big Data [ Submission DvcScheduleV2.cpp and StaticA.pdf
ssuser6254411
 
Modify this code to use multiple threads with the same data1.Modif.pdf
Modify this code to use multiple threads with the same data1.Modif.pdfModify this code to use multiple threads with the same data1.Modif.pdf
Modify this code to use multiple threads with the same data1.Modif.pdf
mallik3000
 
Performance measurement and tuning
Performance measurement and tuningPerformance measurement and tuning
Performance measurement and tuning
AOE
 

Similar to Les classes abstraites c’est fini (et c’est la faute à TDD) (13)

Fedor Polyakov - Optimizing computer vision problems on mobile platforms
Fedor Polyakov - Optimizing computer vision problems on mobile platforms Fedor Polyakov - Optimizing computer vision problems on mobile platforms
Fedor Polyakov - Optimizing computer vision problems on mobile platforms
 
Programming For Big Data [ Submission DvcScheduleV2.cpp and StaticA.pdf
Programming For Big Data [ Submission DvcScheduleV2.cpp and StaticA.pdfProgramming For Big Data [ Submission DvcScheduleV2.cpp and StaticA.pdf
Programming For Big Data [ Submission DvcScheduleV2.cpp and StaticA.pdf
 
Dartprogramming
DartprogrammingDartprogramming
Dartprogramming
 
Modify this code to use multiple threads with the same data1.Modif.pdf
Modify this code to use multiple threads with the same data1.Modif.pdfModify this code to use multiple threads with the same data1.Modif.pdf
Modify this code to use multiple threads with the same data1.Modif.pdf
 
Performance measurement and tuning
Performance measurement and tuningPerformance measurement and tuning
Performance measurement and tuning
 
Code optimization
Code optimization Code optimization
Code optimization
 
Code optimization
Code optimization Code optimization
Code optimization
 
C++ L02-Conversion+enum+Operators
C++ L02-Conversion+enum+OperatorsC++ L02-Conversion+enum+Operators
C++ L02-Conversion+enum+Operators
 
I T.A.K.E. talk: "When DDD meets FP, good things happen"
I T.A.K.E. talk: "When DDD meets FP, good things happen"I T.A.K.E. talk: "When DDD meets FP, good things happen"
I T.A.K.E. talk: "When DDD meets FP, good things happen"
 
CPP Homework Help
CPP Homework HelpCPP Homework Help
CPP Homework Help
 
Lecture05
Lecture05Lecture05
Lecture05
 
How to Build a Telegraf Plugin by Noah Crowley
How to Build a Telegraf Plugin by Noah CrowleyHow to Build a Telegraf Plugin by Noah Crowley
How to Build a Telegraf Plugin by Noah Crowley
 
Building a Telegraf Plugin by Noah Crowly | Developer Advocate | InfluxData
Building a Telegraf Plugin by Noah Crowly | Developer Advocate | InfluxDataBuilding a Telegraf Plugin by Noah Crowly | Developer Advocate | InfluxData
Building a Telegraf Plugin by Noah Crowly | Developer Advocate | InfluxData
 

More from Dorra BARTAGUIZ

More from Dorra BARTAGUIZ (8)

Améliorer l'implémentation du feature flipping
Améliorer l'implémentation du feature flippingAméliorer l'implémentation du feature flipping
Améliorer l'implémentation du feature flipping
 
Sortons de la pyramide pour construire une stratégie de test
Sortons de la pyramide pour construire une stratégie de testSortons de la pyramide pour construire une stratégie de test
Sortons de la pyramide pour construire une stratégie de test
 
Living documentation au service de l'agilité
Living documentation au service de l'agilitéLiving documentation au service de l'agilité
Living documentation au service de l'agilité
 
Devs, let's reclaim DDD!
Devs, let's reclaim DDD!Devs, let's reclaim DDD!
Devs, let's reclaim DDD!
 
Rendons le DDD aux devs
Rendons le DDD aux devsRendons le DDD aux devs
Rendons le DDD aux devs
 
S'améliorer sans s'épuiser
S'améliorer sans s'épuiserS'améliorer sans s'épuiser
S'améliorer sans s'épuiser
 
Slim down diet and tdd
Slim down diet and tddSlim down diet and tdd
Slim down diet and tdd
 
Slim down diet_ and tdd
Slim down diet_ and tddSlim down diet_ and tdd
Slim down diet_ and tdd
 

Recently uploaded

Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
Dr.Costas Sachpazis
 
result management system report for college project
result management system report for college projectresult management system report for college project
result management system report for college project
Tonystark477637
 
UNIT-V FMM.HYDRAULIC TURBINE - Construction and working
UNIT-V FMM.HYDRAULIC TURBINE - Construction and workingUNIT-V FMM.HYDRAULIC TURBINE - Construction and working
UNIT-V FMM.HYDRAULIC TURBINE - Construction and working
rknatarajan
 

Recently uploaded (20)

(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
 
Porous Ceramics seminar and technical writing
Porous Ceramics seminar and technical writingPorous Ceramics seminar and technical writing
Porous Ceramics seminar and technical writing
 
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
 
Coefficient of Thermal Expansion and their Importance.pptx
Coefficient of Thermal Expansion and their Importance.pptxCoefficient of Thermal Expansion and their Importance.pptx
Coefficient of Thermal Expansion and their Importance.pptx
 
College Call Girls Nashik Nehal 7001305949 Independent Escort Service Nashik
College Call Girls Nashik Nehal 7001305949 Independent Escort Service NashikCollege Call Girls Nashik Nehal 7001305949 Independent Escort Service Nashik
College Call Girls Nashik Nehal 7001305949 Independent Escort Service Nashik
 
UNIT - IV - Air Compressors and its Performance
UNIT - IV - Air Compressors and its PerformanceUNIT - IV - Air Compressors and its Performance
UNIT - IV - Air Compressors and its Performance
 
Java Programming :Event Handling(Types of Events)
Java Programming :Event Handling(Types of Events)Java Programming :Event Handling(Types of Events)
Java Programming :Event Handling(Types of Events)
 
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
 
Booking open Available Pune Call Girls Pargaon 6297143586 Call Hot Indian Gi...
Booking open Available Pune Call Girls Pargaon  6297143586 Call Hot Indian Gi...Booking open Available Pune Call Girls Pargaon  6297143586 Call Hot Indian Gi...
Booking open Available Pune Call Girls Pargaon 6297143586 Call Hot Indian Gi...
 
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLSMANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
 
University management System project report..pdf
University management System project report..pdfUniversity management System project report..pdf
University management System project report..pdf
 
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur Escorts
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur Suman Call 7001035870 Meet With Nagpur Escorts
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur Escorts
 
Water Industry Process Automation & Control Monthly - April 2024
Water Industry Process Automation & Control Monthly - April 2024Water Industry Process Automation & Control Monthly - April 2024
Water Industry Process Automation & Control Monthly - April 2024
 
result management system report for college project
result management system report for college projectresult management system report for college project
result management system report for college project
 
ONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdf
ONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdfONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdf
ONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdf
 
UNIT-V FMM.HYDRAULIC TURBINE - Construction and working
UNIT-V FMM.HYDRAULIC TURBINE - Construction and workingUNIT-V FMM.HYDRAULIC TURBINE - Construction and working
UNIT-V FMM.HYDRAULIC TURBINE - Construction and working
 
Introduction to Multiple Access Protocol.pptx
Introduction to Multiple Access Protocol.pptxIntroduction to Multiple Access Protocol.pptx
Introduction to Multiple Access Protocol.pptx
 
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete RecordCCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
 
Introduction and different types of Ethernet.pptx
Introduction and different types of Ethernet.pptxIntroduction and different types of Ethernet.pptx
Introduction and different types of Ethernet.pptx
 
(INDIRA) Call Girl Aurangabad Call Now 8617697112 Aurangabad Escorts 24x7
(INDIRA) Call Girl Aurangabad Call Now 8617697112 Aurangabad Escorts 24x7(INDIRA) Call Girl Aurangabad Call Now 8617697112 Aurangabad Escorts 24x7
(INDIRA) Call Girl Aurangabad Call Now 8617697112 Aurangabad Escorts 24x7
 

Les classes abstraites c’est fini (et c’est la faute à TDD)