【问题标题】:How to pass constants to a method?如何将常量传递给方法?
【发布时间】:2017-02-07 09:05:29
【问题描述】:

我有这些课程: 包实用程序;

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) {}

如何重构上面的代码?我的第一个想法是制作扩展基类或实现通用接口的单例。有更好的解决方案吗?

【问题讨论】:

  • 你检查枚举了吗?
  • 我会推荐 Enums 并考虑 switch-case 和提取方法。
  • @Jorji 您的问题有两个答案。如果您需要进一步说明,请对答案发表评论,或通过单击勾选标记接受其中一个答案为正确答案。投票是免费的。接受答案会给你两分。你有什么可失去的。如果您有任何问题阻止您发表评论或接受答案,请告诉我。

标签: java oop design-patterns polymorphism constants


【解决方案1】:

您应该考虑在此处使用 多态性。示例:而不是做

if (X) {
 doY();
}

“好”的 OO 看起来更像:

Y y = getMeSomeY();
y.doTheY();

getMeSomeY() 准确地返回您所需的内容(因此Y 可能是一个接口;并且该方法提供了该接口的不同实现,这些实现都略有不同)。 关键是:您编写了过程代码,在其中询问一些事情,然后做出决定。好的 OO 支持相反的情况(称为 tell don't ask)。

你首先......不要把所有东西都做成扁平的字符串。通过这样做,你放弃了整个“静态类型”的事情。如果您的代码仅对字符串做出决定,那么您为什么要使用 Java 编程?您可以很好地使用非类型化语言。所以,至少要了解 Java 枚举;并使用那些。但请理解:枚举不是这里的真正答案。它们只会帮助您的代码变得更好。

这里真正的问题是你想在各处编写代码来执行这些if (x) then y

您现在可能已经猜到了:这里没有简单的答案。我会做什么:首先,退后一步。并深入了解您的设计。您现在拥有的代码向我表明您的底层 对象模型 远非“有用”。这就是 OO 的重点:您创建的类和对象帮助您编写干净、优雅的代码。但是当你的基本设计不支持它时;那么尝试重构由此产生的代码就没有意义了。因为你代码的丑陋只是一个症状;根本原因在于你的设计

【讨论】:

  • getMeSomeY() 带一个参数会更有意义 ;)
【解决方案2】:

您正在寻找的是Enum。改为将所有类重新定义为Enums。例如,您可以重新定义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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-20
    • 1970-01-01
    • 2020-12-20
    • 1970-01-01
    相关资源
    最近更新 更多