如何将常量传递给方法?

时间:2017-02-07 09:05:30

标签: java oop design-patterns polymorphism constants

我有这个课程: 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扩展基类,或实现一个通用接口。还有更好的解决方案吗?

2 个答案:

答案 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的重点:您创建的类和对象帮助您编写干净,优雅的代码。但是当你的基础设计不支持时;那么试图重构出来的代码是没有意义的。因为你的代码的丑陋只是一个症状;根本原因在于你的设计