我有一个用于处理客户付款的类。除了一个类(用于计算(例如)客户的用户欠款额的)方法外,对于每个客户而言,此类中的一种方法均是相同的。各个客户之间的差异可能很大,并且由于存在许多自定义因素,因此没有简单的方法来捕获诸如属性文件之类的计算逻辑。
我可以编写难看的代码,以根据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
}
但这需要在我们每次获得新客户时都重新构建班级。有什么更好的方法?
[编辑]“重复”的文章完全不同。我不是在问如何避免使用switch语句,而是在寻求最适合这种情况的现代设计-如果我想编写恐龙代码,可以使用switch语句解决。此处提供的示例是通用的,无济于事,因为它们本质上是在说“嘿,在某些情况下,此开关工作得很好,而在另一些情况下,则效果很好。”
[编辑]我决定采用排名靠前的答案(为实现标准接口的每个客户创建一个单独的“客户”类),原因如下:
一致性:我可以创建一个接口,以确保所有Customer类都可以接收并返回相同的输出,即使是由其他开发人员创建的
可维护性:所有代码都使用相同的语言(Java)编写,因此无需其他任何人学习单独的编码语言来维护应该是简陋的功能。
重用:如果在代码中出现了类似的问题,我可以重用Customer类来容纳许多方法来实现“自定义”逻辑。
熟悉:我已经知道如何执行此操作,因此我可以快速完成它,然后继续处理其他更紧迫的问题。
缺点:
每个新客户都需要编译新的Customer类,这可能会增加我们编译和部署更改的方式的复杂性。
每个新客户都必须由开发人员添加-支持人员不能只是将逻辑添加到属性文件之类的东西中。这不是理想的选择……但是后来我也不确定支持人员将如何写出必要的业务逻辑,尤其是当它很复杂且有很多例外时(很可能)。
如果我们增加许多新客户,它将无法很好地扩展。这是不期望的,但是如果确实发生了,我们将不得不重新考虑代码的许多其他部分以及这一部分。
对于您感兴趣的人,可以使用Java Reflection按名称调用类:
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);