Stai scrivendo un videogioco sul commercio di fagioli. Fagioli rossi, fagioli neri, fagioli borlotti, lo chiami. Come tutti sanno, tutti i fagioli sono uguali. Scrivi la classe "Inventario" per un commerciante in quel videogioco come segue (saltando tutti i controlli null):
class BeansInventory{
HashMap<BeanType,Integer> amountsOwned;
public void receive(BeanType typeReceived, int amount)
{amountsOwned.put(typeReceived,amountsOwned.get(typeReceived)+amount)}
public void remove(BeanType typeRemoved, int amount)
{amountsOwned.put(typeRemoved,amountsOwned.get(typeRemoved)-amount)}
public Integer amountOwned(BeanType type)
{amountsOwned.get(type)}
}
Funziona bene per anni. Poi improvvisamente qualcun altro ha la grande idea di aggiungere al gioco il caffè in grani. Come tutti sanno, ogni singolo chicco di caffè è completamente diverso dall'altro. Quindi non puoi semplicemente aggiungere caffè come un altro tipo di fagiolo. Ogni chicco di caffè è la sua istanza. La classe di inventario del caffè è simile a questa:
class CoffeeInventory{
HashMap<CoffeType,List<CoffeeBeans>> coffeOwned;
public void receive(CoffeType typeReceived, CoffeeBeans... beans)
{coffeOwned.get(typeReceived).addAll(beans)}
public void remove(CoffeType typeRemoved, CoffeeBeans... beans)
{coffeOwned.get(typeRemoved).removeAll(beans)}
public Integer amountOwned(CoffeType type)
{amountsOwned.get(type).size()}
}
Ma ora hai un sacco di problemi. Hai due API per la stessa attività. Tutta l'infrastruttura di trading ora deve controllare attentamente se si tratta di fagioli pinto o chicchi di caffè e chiama un inventario diverso e un metodo diverso con una firma diversa per quello che è dopo lo stesso compito: "memorizza questo".
Quindi ora ho questo codice che viene riempito di if
assegni e instanceof
e tutti gli altri segni di odore di codice. Ma non riesco a capire un modo per utilizzare un'unica semplice API. Non ho idea di cosa sia la cosa giusta da fare.