简体   繁体   English

摆脱 Java 中的幻数

[英]Getting rid of magic numbers in Java

How do I get rid of magic numbers in java without declaring a massive amount of finals or static finals?如何在不声明大量决赛或静态决赛的情况下摆脱 Java 中的幻数? Keep in mind looping, arrays are not allowed.请记住循环,数组是不允许的。 It doesn't seem possible?好像不太可能? Help appreciated.帮助表示赞赏。 thanks.谢谢。

Example code:示例代码:

drawOval(5, 5, width, height);
drawOval(10, 10, width, height);
drawOval(15, 15, width, height);
drawOval(20, 20, width, height);
drawOval(25, 25, width, height);

Defining constants is really your only option. 定义常量是您唯一的选择。 What's your opposition to using them? 你反对使用它们是什么? They are definitely worth their space in this context. 在这种情况下,他们绝对值得他们的空间。 Future developers would much rather see extra constants than be confused by what those numbers mean. 未来的开发人员更愿意看到额外的常量,而不是被这些数字的含义搞糊涂。

The direct answer is that named constants is the only way to avoid having magic numbers in your code. 直接的答案是命名常量是避免在代码中使用幻数的唯一方法。


But the flip-side is that it is debatable whether magic numbers are harmful or the extent that they are harmful. 但另一方面,魔术数字是否有害或者它们有害的程度是值得商榷的 And in this particular case it is debatable whether these actually qualify as "magic" numbers ... at least, IMO. 在这个特殊情况下,这些实际上是否符合“魔术”数字是至关重要的......至少,IMO。

Lets illustrate this: 让我们说明一下:

// Alternative #1

private final int PLACE_1_X = 5;
private final int PLACE_1_Y = 5;
...
drawOval(PLACE_1_X, PLACE_1_Y, width, height);

// Alternative #2
drawOval(5, 5, width, height);

Which of these is actually more readable? 其中,这些实际上是更具可读性? Does defining named constants (which are most likely at a different point in the source code!) make it easier to understand what is going on? 定义命名常量(最有可能在源代码中的不同点!)使得更容易理解发生了什么? Don't you now have the problem that you have to look in two places not one to understand what a specific drawOval call is going to draw? 难道你现在遇到的问题是你必须在两个地方看一下才能了解一个特定的drawOval调用将要绘制的内容吗?


The bottom line is that the "no magic numbers" dogma only really applies when it meaning of the numbers is not self-evident from the context ... or when the number is actually a repeatedly used constant. 最重要的是,“无魔数”教条只有当数字的含义从上下文中不明显时才真正适用......或者当数字实际上是重复使用的常数时。 (Like if we were going to use PLACE_1 lots of times in the same "picture".) (就像我们要在同一张“图片”中多次使用PLACE_1一样。)

You need to think about the context, not just blindly apply the dogma. 你需要考虑上下文,而不是盲目地应用教条。

An alternative to finals / static that I've already seen is to use a custom object as an argument: 我已经看到的finals / static的替代方法是使用自定义对象作为参数:

public void drawOval(OvalArg arg) {
    // ...
}

OvalArg arg = new OvalArg();
arg.first = 10;
arg.second = 10;
arg.width = 100;
arg.height = 500;

drawOval(arg);

However, this approach implies that you cannot see directly which arguments must be sent to a method (unless you look into the argument object), and requires extra validation to ensure that your custom object is correctly filled. 但是,这种方法意味着您无法直接查看必须将哪些参数发送到方法(除非您查看参数对象),并且需要额外的验证以确保正确填充自定义对象。 For that reason, I would recommend using constants. 出于这个原因,我建议使用常量。

Adding to the other answers we can also use Enums to declare constants and they can have values attached like width and height.除了其他答案之外,我们还可以使用枚举来声明常量,它们可以附加值,如宽度和高度。

public enum Dimensions {
  
  DIMENSION_FIVE_FIVE(5, 5);

  private final int height;
  private final int weight;

  private Dimensions(int height, int width) {
     this.height = height;
     this.weight = weight;
  }

}

Please ignore my naming convention, suggestions are welcome.请忽略我的命名约定,欢迎提出建议。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM