Progettazione dell'interfaccia: Parametro specifico vs generale (A Minimal design rispetto alla variazione d'uso prevista)

2

Codice

public interface IVehicle {
   string VehicleMake { get; }
   int MonthsSincePurchase { get; }
   bool IsApprovedUsed { get; }
   ...
}

public class WarrantyPopUpHandler {
   virtual bool ShouldShowPopup(IVehicle vehicle /* What should I pass in?*/) {
      return false; 
   }
}

public class VolvoWarrantyPopupHandler : WarrantyPopUpHandler {
   override bool ShouldShowPopup(IVehicle vehicle) {
      return vehicle.MonthsSincePurchase < 12;
   }
}

public class BMWWarrantyPopupHandler : WarrantyPopUpHandler {
   override bool ShouldShowPopup(IVehicle vehicle) {
      return vehicle.MonthsSincePurchase < 12;
   }
}

Spiegazione

Guardando lo pseudo-codice sopra c'è un tipo IVehicle che espone molte proprietà di un veicolo. Ora alcuni clienti vogliono mostrare un popup per alcuni veicoli e il programmatore inizia a progettare un WarrantyPopupHandler . Attualmente Volvo e BMW vogliono il popup e lo vogliono entrambi in base all'età dei veicoli. Il programmatore implementa le due classi derivate come mostrato.

Che cosa dovrebbe prendere il metodo ShouldShowPopup() come parametro. L'unica cosa di cui ha bisogno dai casi d'uso correnti è int MonthsSincePurchase . È attualmente prematuro rifornire l'intero veicolo elettronico, dovrebbe prendere solo un int ?

Ma ci sono ottime possibilità che durante la demo un altro cliente, ad esempio Ford, catturi l'idea e vorrà lo stesso popup, ma forse solo per i veicoli ApprovedUsed ( IsApprovedUsed ) in futuro. Il programmatore lo sa per esperienza.

Inoltre ci sarà molto altro codice scritto che si baserà sulla chiamata di WarrantyPopUpHandler::ShouldShowPopup .

Si noti inoltre che la versione della classe base ignora il parametro in entrata e restituisce falso tutto il tempo, quindi qui sembra inutile fornire un parametro.

Domanda bonus

La risposta cambia se IVehicle fa parte di un'interfaccia più grande.

interface VehicleInvoice
{
    IVehicle Vehicle { get; }
    ICustomer Customer { get; }
    ...
}

Il programmatore dovrebbe aver fornito piuttosto VehicleInvoice a ShouldShowPopup dato che i dati dei clienti possono (un raro caso per esperienza) anche prendere in considerazione la decisione di mostrare un popup in futuro?

Vedi anche

La domanda è una variazione della mia precedente domanda: Design minimale rispetto all'uso previsto . Come dovrebbero le risposte lì influenzare la scelta del design qui?

Nota gentile

Vorrei che le risposte provassero e riflettessero su quali principi di progettazione si applicano qui e non trattate questo come un esercizio di refactoring che evita la domanda che viene posta. Grazie.

    
posta Ali 14.10.2015 - 21:01
fonte

1 risposta

5

Rendere il parametro un IVehicle è migliore. Stai essenzialmente utilizzando la tua WarrantyPopupHandler gerarchia per aggiungere un metodo con un'implementazione predefinita a IVehicle . Rendere il parametro un int non avrebbe senso perché ShouldShowPopup sta assumendo un certo "significato" per int (cioè che int detiene IVehicle.MonthsSincePurchase ). Poiché sarebbe un errore logico chiamare ShouldShowPopup con int che significa qualcos'altro, il parametro potrebbe essere anche un IVehicle . L'utilizzo di IVehicle migliora anche l'incapsulamento poiché il chiamante di ShouldShowPopup non deve esaminare la struttura interna di IVehicle .

Come per l'interfaccia VehicleInvoice , ciò dipende dalla conoscenza del dominio. Mi sembra che una garanzia sia associata a una particolare transazione , che sembra essere ciò che VehicleInvoice rappresenta. Quindi nel caso particolare della tua domanda "bonus", sarei propenso a renderlo ShouldShowPopup(VehicleInvoice) . Ovviamente se porti questo pensiero troppo lontano finisci con le variabili globali, quindi devi usare il tuo miglior giudizio.

    
risposta data 15.10.2015 - 00:35
fonte