Best practice for global constants involving magic numbers

前端 未结 5 1413
北海茫月
北海茫月 2020-12-17 21:11

To avoid magic numbers, I always use constants in my code. Back in the old days we used to define constant sets in a methodless interface which has now become an antipatter

相关标签:
5条回答
  • 2020-12-17 21:46

    Using interfaces for storing constants is some kind of abusing interfaces.

    But using Enums is not the best way for each situation. Often a plain int or whatever else constant is sufficient. Defining own class instances ("type-safe enums") are even more flexible, for example:

    public abstract class MyConst {
      public static final MyConst FOO = new MyConst("foo") {
        public void doSomething() {
          ...
        }
      };
    
      public static final MyConst BAR = new MyConst("bar") {
        public void doSomething() {
          ...
        }
      };
    
      protected abstract void doSomething();
    
      private final String id;
    
      private MyConst(String id) {
        this.id = id;
      }
    
      public String toString() {
        return id;
      }
      ...
    }
    
    0 讨论(0)
  • 2020-12-17 21:47

    Yes it is. Enum is the best choice.

    You are getting for free:

    • constants
    • immutable objects
    • singletons

    All in one.

    But wait, there's some more. Every enum value can have its own fields and methods. It's a rich constant object with behavior that allows transformation into different forms. Not only toString, but toInt, toWhateverDestination you need.

    0 讨论(0)
  • 2020-12-17 21:48

    Enum is best for most of the case, but not everything. Some might be better put like before, that is in a special class with public static constants.

    Example where enum is not the best solution is for mathematical constants, like PI. Creating an enum for that will make the code worse.

    enum MathConstants {
        PI(3.14);
    
        double a;        
    
        MathConstants(double a) {
           this.a = a;
        }
    
        double getValueA() {
           return a;
        }
    }
    

    Usage:

    MathConstants.PI.getValueA();
    

    Ugly isn't it? Compare to:

    MathConstants.PI;
    
    0 讨论(0)
  • 2020-12-17 21:50

    Forget about enums - now, when static import is available in Java, put all your constants in REAL class (instead of interface) and then just import the static members from all the other ones using import static <Package or Class>.

    0 讨论(0)
  • 2020-12-17 22:08

    For magic numbers where the number actual has a meaning and is not just a label you obviously should not use enums. Then the old style is still the best.

    public static final int PAGE_SIZE = 300;
    

    When you are just labelling something you would use an enum.

    enum Drink_Size
    {
       TALL,
       GRANDE,
       VENTI;
    }
    

    Sometimes it makes sense to put all your global constants in their own class, but I prefer to put them in the class that they are most closely tied to. That is not always easy to determine, but at the end of the day the most important thing is that your code works :)

    0 讨论(0)
提交回复
热议问题