Q-INTERACT : Questions TDA

Questions variées

Q: Quand ne devrait-on pas respecter le TDA?

Q: Quelles sont les conséquences de ne pas respecter Demeter et TDA?
R: Voir https://pragprog.com/articles/tell-dont-ask et https://martinfowler.com/bliki/TellDontAsk.html

Solution

Ce sont des questions de réflexions pour lesquelles nous ne fournirons pas de solutions. Nous vous invitons à comparer votre réflexion entre collègues dans un groupe d’étude. Vous pouvez également proposer vos réflexions dans le laboratoire pour en discuter avec un(e) assistant(e).

Exercices de réusinages

Pour les exercices suivants, réusiner rapidement le code afin de respecter le TDA.

NOTE: On ne vous demande pas si c’est pertinent de le respecter, mais uniquement de vous pratiquer à réusiner du code pour respecter aveuglément le TDA :wink:

Questions

Q1

List<Paie> paies = new LinkedList<>();
for (Employe employe : employes) {
    Paie paie;
    if (employe.getType() == TypeEmploye.HORAIRE) {
        double taux = employe.getTauxHoraire();
        double heures = employe.getHeuresTravaillees();
        paies.add(new Paie(taux * heures));
    } else {
        double salairePeriodique = employe.getSalaireAnnuel() / 52.0;
        paies.add(new Paie(salairePeriodique));
    }
}

Q2

Vol vol = obtenirVol();
vol.ajouterHeuresRetard(2);
if (vol.estUnDepart()) {
    systemIntercom.annoncerRetard(vol);
}

Notez dans l’exercice qui précède que .estUnDepart n’est pas strictement une violation du TDA. Mais que pensez-vous de ce design ? Essayez de le retirer.

Q3

for (Item item : panier.obtenirItems()) {
    if (item instanceof ItemEnPromotion) {
        panier.ajouterItem(item.clone());
    }
}

Q4

class X:
  def foo(self):
    z = self.y.getZ()
    w = z.getW()
    w.setA(2)
    z.setB(4)

class Y:
  def getZ(self)
    return Z()

class Z:
  def getW(self)
    return W()

  def setB(self, value):
    self.b = value

class W:
  def setA(self, value):
    self.a = value

Q5

class TxAppService:
  def ajouterAuCompteClient(self, compteClient, description, montant):
    tx = new Transaction(description, montant)

    balance = compteClient.getBalance()
    txList = compteClient.getTransactionsList()
    txList.add(tx)
    compteClient.setBalance(balance + montant)
    compteClient.setEnSouffrance(true)

    self.grand_livre.inscrireTransaction(tx)

Solutions

R1

Une solution possible. Cette solution ne fait que régler le TDA minimalement. Pourriez-vous proposer un design qui serait encore mieux d’un point de vue de l’interaction?

List<Paie> paies = new LinkedList<>();
for (Employe employe : employes) {
    Paie paie = employe.calculerPaie();
    paies.add(paie);
}

public interface Employe {
  Paie calculerPaie();
}

R2

{
  Vol vol = obtenirVol()
  vol.ajouterHeuresRetard(2)
}

public class Vol {
  public void ajouterHeuresRetard(heures) {
    // ... ajouter les heures
    if (this.estUnDepart) {
        this.systemIntercom.annoncerRetard(vol)
        // le sys d'intercom peut etre passe au ctor ou non
    }
  }
}

– ou –

{
  Vol vol = obtenirVol()
  vol.ajouterHeuresRetard(2)
  vol.annoncerRetardsSiNecessaire()
}

public class Vol {
  public void annoncerRetardsSiNecessaire() {
    if (retard && this.estUnDepart) {
        this.systemIntercom.annoncerRetard(vol)
        // le sys d'intercom peut etre passe au ctor ou non
    }
  }
}

R3

Aucune réponse ne sera donnée. Nous vous invitons à aller discuter de votre solution au laboratoire et surtout de comparer vos réponses entre collègues.

R4

class X:
  def foo(self):
    self.y.doXyz()

class Y:
  def doXyz(self):
    self.z.doXyz()

class Z:
  def getW(self)
    self.w.doXyz()
    self.b = 4  

class W:
  def doXyz(self):
    self.a = 2

R5

class TxAppService:
  def ajouterAuCompteClient(self, compteClient, description, montant):
    tx = new Transaction(description, montant)
    compteClient.ajouterTransaction(tx, montant)
    self.grand_livre.inscrireTransaction(tx)

class CompteClient
  def ajouterTransaction(self, tx, montant):
    self.txList.add(tx)
    self.setBalance(self.balance + montant)
    self.setEnSouffrance(true)

Note: cette solution ne fait que régler le TDA. Essayez une solution pour régler tous les problèmes SOLID.

Exercice de réflexion

Pour chacun des cas précédents, débattez de la pertinence de respecter ou non (complètement ou partiellement) le TDA. Essayez de trouver des arguments favorables et défavorables.

Solution

Cette question de réflexion n’aura de solution donnée. Nous vous invitons à débattre entre vous (groupe d’étude) de cette question et de venir confronter vos analyses au laboratoire.