abe*_*t80 11 oop design-patterns anti-patterns
我一直认为只是为了保持常量而有一个类是一个糟糕的设计.但最近,我尝试使用谷歌搜索它,并发现只有一个接口作为常量是坏的反模式 - 没有提到使用一类常量.
我认为,由于一类常量实际上与全局变量没有太大差别,这就是为什么我反对它并倾向于重构这些类.它创建了一类绝对没有上下文的数据.这些常量与实际使用它们的关系更好,给它们上下文和意义,以及将它们封装在一个类中.
其他人怎么想?
gus*_*afc 14
全局常数不是坏习惯,只要它们是......
final//readonly引用不是常量,而是全局状态.ArrayList<T>List<T>Bloch涵盖了Effective Java中的"常量接口"与"常量类"问题,并提倡"常量类"方法.您不希望接口中存在常量的原因是它诱使客户端类"实现"该接口(为了访问常量而不使用接口名称作为前缀).但是,您不应该 - 接口实际上不是对象功能的接口,而是在类外部类型中根深蒂固的编译时方便性.考虑一下:
interface C { public static final int OMGHAX = 0x539; }
class A implements C { ... }
class B { private A a; }
Run Code Online (Sandbox Code Playgroud)
类B现在不必要地依赖于C.如果执行A更改以便它不需要常量C,则无法implements C在不破坏其外部接口的情况下从中删除- 某人(可以说是一个非常愚蠢的人,但这样的人比比皆是)可能A通过C引用引用一个对象!
通过将常量放在类中,并使该类不可实现,您通知客户端常量类实际上只是作为子命名空间.在C#中,您将该类标记为static,在Java中您需要创建它final并提供无法访问的构造函数:
final class C {
private C() { throw new AssertionError("C is uninstantiable"); }
public static final int OMGHAX = 0x539;
}
Run Code Online (Sandbox Code Playgroud)
如果使用Java编程并且希望常量不使用常量类名称作为前缀,则可以使用该import static功能.
是的,被迫创建一个新类型只是为了放置你的常量,这有点多余,但这是我们必须处理的Java和C#等语言的瑕疵 - 我们必须把我们的常量放在某处,而我们的最佳选择恰好是一个不可实例化的类.
Jim*_*ans 10
全局变量存在问题,因为它们在模块之间引入了很多不必要的依赖.这些依赖性使得调试问题和重用代码变得更加困难.
我会说真正的全局常量也出于同样的原因也存在问题,所以不要让一个名为MyGlobals的单例包含像MyGlobals.HTTP_SUCCESS_OK这样的常量,而是将它们像常量一样打包在它们自己的类中,例如HttpStatus.SUCCESS_OK.
我认为全局变量问题是他们创造了全球状态.全局常量不会这样做,但它们确实负责一些无环境的常量,这可能是坏的.
如果你需要这样的东西,我建议创建枚举(如果你有int常量)或常量的静态类,所以你可以给它们一些上下文(例如,Math.PI)