Ho una classe utilizzata per elaborare i pagamenti dei clienti. Tutti tranne uno dei metodi di questa classe sono gli stessi per ogni cliente, ad eccezione di uno che calcola (ad esempio) quanto deve l'utente del cliente. Questo può variare notevolmente da cliente a cliente e non esiste un modo semplice per acquisire la logica dei calcoli in qualcosa di simile a un file di proprietà, in quanto può esserci un numero qualsiasi di fattori personalizzati.
Potrei scrivere un codice brutto che cambia in base a customerID:
switch(customerID) {
case 101:
.. do calculations for customer 101
case 102:
.. do calculations for customer 102
case 103:
.. do calculations for customer 103
etc
}
ma ciò richiede la ricostruzione della classe ogni volta che riceviamo un nuovo cliente. Qual è il modo migliore?
[Modifica] L'articolo "duplicato" è completamente diverso. Non sto chiedendo come evitare un'istruzione switch, sto chiedendo il design moderno più adatto a questo caso - che potrei risolvere con una dichiarazione di switch se volessi scrivere il codice del dinosauro. Gli esempi forniti sono generici e non utili, poiché in pratica dicono "Ehi, l'interruttore funziona abbastanza bene in alcuni casi, non in altri."
[Modifica] Ho deciso di andare con la risposta top-class (creare una classe "Cliente" separata per ogni cliente che implementa un'interfaccia standard) per i seguenti motivi:
-
Consistenza: posso creare un'interfaccia che garantisca che tutte le classi cliente ricevano e restituiscano lo stesso output, anche se create da un altro sviluppatore
-
Mantenibilità: tutto il codice è scritto nella stessa lingua (Java), quindi non è necessario che qualcun altro apprenda un linguaggio di codifica separato per mantenere quella che dovrebbe essere una caratteristica semplice.
-
Riutilizzo: nel caso in cui un problema simile emerga nel codice, posso riutilizzare la classe Customer per contenere un numero qualsiasi di metodi per implementare la logica "personalizzata".
-
Familiarità: so già come farlo, così posso farlo rapidamente e passare ad altri problemi più urgenti.
Svantaggi:
-
Ogni nuovo cliente richiede una compilazione della nuova classe Customer, che può aggiungere una certa complessità al modo in cui compiliamo e implementiamo le modifiche.
-
Ogni nuovo cliente deve essere aggiunto da uno sviluppatore - una persona di supporto non può semplicemente aggiungere la logica a qualcosa come un file di proprietà. Questo non è l'ideale ... ma poi non ero nemmeno sicuro di come una persona di supporto sarebbe in grado di scrivere la logica di business necessaria, specialmente se è complessa con molte eccezioni (come è probabile).
-
Non si scalerà bene se aggiungiamo molti, molti nuovi clienti. Questo non è previsto, ma se dovesse succedere dovremo ripensare a molte altre parti del codice e anche a questo.
Per quelli di voi interessati, è possibile utilizzare Java Reflection per chiamare una classe per nome:
Payment payment = getPaymentFromSomewhere();
try {
String nameOfCustomClass = propertiesFile.get("customClassName");
Class<?> cpp = Class.forName(nameOfCustomClass);
CustomPaymentProcess pp = (CustomPaymentProcess) cpp.newInstance();
payment = pp.processPayment(payment);
} catch (Exception e) {
//handle the various exceptions
}
doSomethingElseWithThePayment(payment);