我有这个课程: package util;
public final class Constant {
private Constant() {
throw new AssertionError();
}
public static class Product {
public static final String CODE = "Product";
public static final String A = "product_5g2g";
public static final String B = "product_a45h";
public static final String C = "product_a3ag";
//more constants..
}
public static class Employee {
public static final String CODE = "Employee";
public static final String A = "employee_1g3f";
public static final String B = "employee_h52d";
public static final String C = "employee_h5d2";
//more constants..
}
public static class Client {
public static final String CODE = "Client";
public static final String A = "client_h5ad";
public static final String B = "client_1df1";
public static final String C = "client_6g23";
//more constants..
}
}
和
package util;
import util.Constant.*;
public class Main {
public void run() {
if (isSelected(Product.CODE)) {
if (isSelected(Product.A) || isSelected(Product.B)) {
//do something
}
compute(Product.C);
//more similar instruction that use constants from Product class
}
if (isSelected(Employee.CODE)) {
if (isSelected(Employee.A) || isSelected(Employee.B)) {
//do something
}
compute(Employee.C);
//more similar instruction that use constants from Employee class
}
if (isSelected(Client.CODE)) {
if (isSelected(Client.A) || isSelected(Client.B)) {
//do something
}
compute(Client.C);
//more similar instruction that use constants from Client class
}
}
public boolean isSelected(String s) {
return true;
}
public void compute(String s) {
}
}
如您所见,这段代码
if (isSelected(StaticClass.CODE)) {
if (isSelected(StaticClass.A) || isSelected(StaticClass.B)) {
//do something
}
compute(StaticClass.C);
//more similar instruction that use constants from Product class
}
是重复的,但不能将它放在单独的方法中,因为java不允许将静态类作为参数public void method(StaticClass) {}
。
如何重构上述代码?我的第一个想法是让Singletons扩展基类,或实现一个通用接口。还有更好的解决方案吗?
答案 0 :(得分:1)
您要找的是Enum
。请将所有课程重新定义为Enum
。例如,您可以按如下方式重新定义Product
类:
public enum Product {
CODE("Product"),
A("product_5g2g");
private String value;
//define others constants in a similar fasion
public Product(String value) {
this.value = value;
}
}
Enums
可以作为方法参数传递。在您的特定示例中,您可以执行此操作:
public void method(Constants.Product product) {
}
那就是说,你绝对应该寻找另一种方法来实现你的目标。首先看一下Replacing conditionals with Polymorphism。
答案 1 :(得分:1)
您应该在此处查看使用多态。示例:而不是执行
if (X) {
doY();
}
"良好" OO看起来更像是:
Y y = getMeSomeY();
y.doTheY();
getMeSomeY()
确切地返回了所需的内容(因此Y
可以是一个接口;并且该方法提供了该接口的不同实现,它们都做了稍微不同的事情)。
重点是:您编写了程序代码,在那里询问某些东西,然后对其做出决定。 Good OO倾向于相反(称为tell don't ask)。
你开始......不是把所有东西都弄成扁平的字符串。通过这样做,你放弃了整个"静态打字"事情。如果您的代码仅在字符串上做出决定,那么为什么要用Java编程?你可以很好地使用非类型语言。所以,至少要了解Java枚举;并使用那些。但请理解:枚举不是真正的答案。它们只会帮助您使代码更好一些。
真正的问题在于,您希望编写代码来完成这些if (x) then y
。
你可能已经猜到了:这里没有简单的答案。我会做什么:首先,退后一步。并深入了解您的设计。您现在拥有的代码向我表明您的基础对象模型远非“有用”#34;。这就是OO的重点:您创建的类和对象帮助您编写干净,优雅的代码。但是当你的基础设计不支持时;那么试图重构出来的代码是没有意义的。因为你的代码的丑陋只是一个症状;根本原因在于你的设计。