GLO-4002 - Site du cours 2023

Temps estimé: 30 minutes

Exercices : Identifier et Réusiner

Instructions

Pour les exercices suivants, réusinez rapidement le code afin de respecter le TDA. Notez que le but est de pratiquer le TDA, sans considération pour la pertinence des changements.

Question 1

public class Exercise_1 {

    public List<Salary> getAllWorkerSalaries(List<Worker> workers) {
        List<Salary> salaries = new LinkedList<>();
        for (Worker worker : workers) {
            if (worker.getType() == WorkerType.HOURLY) {
                double hourlyWage = worker.getHourlyWage();
                double hours = worker.getWorkedHours();
                salaries.add(new Salary(hourlyWage * hours));
            } else {
                double salary = worker.getAnnualSalary() / 52.0;
                salaries.add(new Salary(salary));
            }
        }

        return salaries;
    }
}
public class Exercise_1 {

    public List<Salary> getAllWorkerSalaries(List<Worker> workers) {
        List<Salary> salaries = new LinkedList<>();
        for (Worker worker : workers) {
            Salary salary = worker.calculateSalary();
            salaries.add(salary);
        }

        return salaries;
    }
}
    public interface Worker {
        Salary calculateSalary();
    }

Cette solution règle le TDA minimalement. Bravo si vous trouvez un design avec une meilleur interaction!

Question 2

Ce n'est pas strictement une violation du TDA, mais essayez de retirer l'utilisation de la méthode getIsDeparture de la classe suivante:

public class Exercise_2 {

    public void addTwoHoursOfDelay() {
        Flight flight = new flight();
        flight.addDelay(2);

        if (flight.getIsDeparture()) {
            intercomSystem.announceDelay(flight, 2);
        }
    }
}
public class Exercise_2 {

    public void addDelay() {
        Flight flight = new Flight();
        flight.addDelay(2);
    }
}
public class Flight {

    private int delay = 0;

    public void addDelay(int hours) {
        delay += hours;

        if (this.isDeparture) {
            this.intercomSystem.announceDelay(flight, delay);
            // Le système d'intercom peut etre injecté au constructeur ou non.
        }
    }
}

~ ou ~

public class Exercise_2 {

    public void addDelay() {
        Flight flight = new Flight();
        flight.addDelay(2);
        flight.announceDelayIfNecessary();
    }
}
public class Flight {

    private int delay = 0;
    private boolean isDeparture; // dans constructeur

    public void addDelay(int hours) {
        delay += hours;
    }

    public void notifyDelayIfNecessary() {
        if (this.delay > 0 && this.isDeparture) {
            this.intercomSystem.announceDelay(flight, delay);
            // Le système d'intercom peut etre injecté au constructeur ou non.
        }
    }
}

Question 3

public class Exercise_3 {

    public void storeSpecialItems(Inventory inventory) {
        for (Item item : inventory.getItems()) {
            if (item instanceof SpecialItem) {
                inventory.add(item.clone());
            }
        }
    }
}
public class Exercise_3 {

    public void storeSpecialItems(Inventory inventory) {
        inventory.storeSpecialItems();
    }
}
public class Inventory {

    private List<Item> items;
    private List<Item> specialItems;

    public Inventory(List<Item> items) {
        this.items = items;
        this.specialItems = new ArrayList<>();
    }

    public void storeSpecialItems() {
        for (Item item : items) {
            if (item instanceof SpecialItem) {
                specialItems.add(item.clone());
            }
        }
    }
}

Question 4

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
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

Question 5

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)
class TxAppService:
  def ajouterAuCompteClient(self, compteClient, description, montant):
    tx = new Transaction(description, montant)
    compteClient.ajouterTransaction(tx, montant)
    self.grand_livre.inscrireTransaction(tx) // Ceci pourrait aussi être délégué. Avez-vous une idée de comment?
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, mais il reste des violations des principes SOLID que nous verrons plus tard dans le cours.

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.