J'ai une classe utilisée pour traiter les paiements des clients. Toutes les méthodes de cette classe, sauf une, sont les mêmes pour chaque client, à l'exception de celle qui calcule (par exemple) le montant dû par l'utilisateur du client. Cela peut varier considérablement d'un client à l'autre et il n'y a pas de moyen facile de capturer la logique des calculs dans quelque chose comme un fichier de propriétés, car il peut y avoir un certain nombre de facteurs personnalisés.
Je pourrais écrire du code laid qui change en fonction de 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
}
mais cela nécessite de reconstruire la classe chaque fois que nous obtenons un nouveau client. Quelle est la meilleure façon?
[Modifier] L'article "en double" est complètement différent. Je ne demande pas comment éviter une déclaration de commutateur, je demande le design moderne qui s'applique le mieux à ce cas - que je pourrais résoudre avec une déclaration de commutateur si je voulais écrire du code de dinosaure. Les exemples qui y sont fournis sont génériques et ne sont pas utiles, car ils disent essentiellement "Hé, le commutateur fonctionne assez bien dans certains cas, pas dans d'autres."
[Modifier] J'ai décidé de choisir la réponse la mieux classée (créer une classe "Client" distincte pour chaque client qui implémente une interface standard) pour les raisons suivantes:
Cohérence: je peux créer une interface qui garantit que toutes les classes clients reçoivent et retournent la même sortie, même si elles ont été créées par un autre développeur
Maintenabilité: Tout le code est écrit dans le même langage (Java), il n'est donc pas nécessaire que quiconque apprenne un langage de codage distinct afin de maintenir ce qui devrait être une fonctionnalité simple et morte.
Réutilisation: dans le cas où un problème similaire apparaît dans le code, je peux réutiliser la classe Customer pour contenir un nombre illimité de méthodes pour implémenter une logique "personnalisée".
Familiarité: je sais déjà comment procéder, je peux donc le faire rapidement et passer à d'autres problèmes plus urgents.
Désavantages:
Chaque nouveau client nécessite une compilation de la nouvelle classe Customer, ce qui peut ajouter de la complexité à la façon dont nous compilons et déployons les modifications.
Chaque nouveau client doit être ajouté par un développeur - une personne de support ne peut pas simplement ajouter la logique à quelque chose comme un fichier de propriétés. Ce n'est pas idéal ... mais je ne savais pas non plus comment une personne de support serait en mesure d'écrire la logique métier nécessaire, surtout si elle est complexe à de nombreuses exceptions près (comme cela est probable).
Cela n'évolue pas bien si nous ajoutons de très nombreux nouveaux clients. Ce n'est pas prévu, mais si cela se produit, nous devrons repenser de nombreuses autres parties du code ainsi que celle-ci.
Pour ceux d'entre vous qui sont intéressés, vous pouvez utiliser Java Reflection pour appeler une classe par son nom:
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);