Ho una classe utilizzata per elaborare i pagamenti dei clienti. Tutti i metodi tranne uno di questa classe sono gli stessi per tutti i clienti, tranne uno che calcola (ad esempio) quanto deve il cliente. Ciò 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à, poiché possono esserci un numero qualsiasi di fattori personalizzati.
Potrei scrivere un brutto codice che cambia in base all'ID cliente:
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 otteniamo 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 che si applica meglio a questo caso - che potrei risolvere con un'istruzione switch se volessi scrivere un codice dinosauro. Gli esempi forniti sono generici e non utili, dal momento che essenzialmente dicono "Ehi, l'interruttore funziona abbastanza bene in alcuni casi, non in altri".
[Modifica] Ho deciso di scegliere la risposta più votata (creare una classe "Cliente" separata per ciascun cliente che implementa un'interfaccia standard) per i seguenti motivi:
Coerenza: posso creare un'interfaccia che assicuri che tutte le classi di clienti ricevano e restituiscano lo stesso output, anche se creato da un altro sviluppatore
Manutenibilità: tutto il codice è scritto nella stessa lingua (Java), quindi non è necessario che nessun altro impari un linguaggio di codifica separato per mantenere quella che dovrebbe essere una funzionalità semplicissima.
Riutilizzo: nel caso si verifichi un problema simile nel codice, posso riutilizzare la classe Customer per contenere un numero qualsiasi di metodi per implementare la logica "personalizzata".
Familiarità: so già come farlo, quindi 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 delle proprietà. Questo non è l'ideale ... ma poi non ero sicuro di come una persona del Supporto sarebbe in grado di scrivere la logica aziendale necessaria, specialmente se è complessa con molte eccezioni (come è probabile).
Non si ridimensionerà bene se aggiungiamo molti, molti nuovi clienti. Ciò non è previsto, ma in tal caso dovremo ripensare molte altre parti del codice, oltre a questa.
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);