Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Design patterns 全局常量是反模式吗?_Design Patterns_Oop_Anti Patterns - Fatal编程技术网

Design patterns 全局常量是反模式吗?

Design patterns 全局常量是反模式吗?,design-patterns,oop,anti-patterns,Design Patterns,Oop,Anti Patterns,我一直认为仅仅为了保存常量而创建一个类是一个糟糕的设计。但最近,我尝试在谷歌上搜索它,发现只有一个接口作为常量是不好的反模式——更不用说使用常量类了 我的观点是,由于一类常量实际上与全局变量没有太大区别,所以我反对它,并倾向于重构掉这些类。它创建了一类完全没有上下文的数据。这些常量最好与实际使用它们的内容相联系,以赋予它们上下文和含义,并将它们封装在类中 其他人怎么想?全局常数很好 全局(非常量)变量是魔鬼的杰作。我认为全局变量的问题在于它们创造了全局状态。全局常量不能做到这一点,但它们确实负责

我一直认为仅仅为了保存常量而创建一个类是一个糟糕的设计。但最近,我尝试在谷歌上搜索它,发现只有一个接口作为常量是不好的反模式——更不用说使用常量类了

我的观点是,由于一类常量实际上与全局变量没有太大区别,所以我反对它,并倾向于重构掉这些类。它创建了一类完全没有上下文的数据。这些常量最好与实际使用它们的内容相联系,以赋予它们上下文和含义,并将它们封装在类中


其他人怎么想?

全局常数很好


全局(非常量)变量是魔鬼的杰作。

我认为全局变量的问题在于它们创造了全局状态。全局常量不能做到这一点,但它们确实负责一些无上下文的常量,这可能是不好的


如果您需要这样的东西,我建议您创建枚举(如果您有int常量)或常量的静态类,这样您就可以给它们一些上下文(例如Math.PI)

全局变量被广泛认为是一件坏事,通常应该避免。这就是为什么这么多人对单身模式有异议。全局变量的问题在于它们是可传递的。

全局变量是有问题的,因为它们在模块之间引入了大量不必要的依赖关系。这些依赖关系使得调试问题和重用代码变得更加困难


我想说,真正的全局常量也是有问题的,因为同样的原因,所以与其让一个名为MyGlobals的单例包含一个类似MyGlobals.HTTP_SUCCESS_OK的常量,不如将类似常量打包在自己的类中,例如HttpStatus.SUCCESS\u OK.

我想有一件事没有提到,那就是更务实的问题。如果您使用的是编译语言,请记住必须重新编译才能更改常量的值。如果这是一个你可能想要频繁改变的值,你也可能想考虑一个配置文件。

全局常量不是坏的实践,只要它们是…

  • 。。。不可变-对可变对象(如Java
    ArrayList
    或C#
    列表
    )的全局、
    final
    只读引用不是常量,而是全局状态
  • 。。。>1类所需。如果只有一个类需要您的常量,请将这些常量直接放入该类中。(注意:适当平衡干燥和雅格尼。)
  • Bloch在有效的Java中讨论了“常量接口”与“常量类”的问题,并提倡“常量类”方法。您不希望在接口中使用常量的原因是它诱使客户机类“实现”该接口(以便在不使用接口名称作为前缀的情况下访问常量)。但是,您不应该这样做-接口实际上不是对象功能的接口,而是类的外部类型中根深蒂固的编译时便利。考虑这一点:

    interface C { public static final int OMGHAX = 0x539; }
    class A implements C { ... }
    class B { private A a; }
    
    B
    现在不必要地依赖于
    C
    。如果
    A
    的实现发生了变化,因此它不需要
    C
    中的常量,那么在不破坏其外部接口的情况下,您无法从中删除
    实现C
    ——有人(可能是一个非常愚蠢的人,但这样的人很多)可能通过
    C
    引用引用
    A
    对象

    通过将常量放在一个类中,并使该类不可实例化,您可以通知客户机常量类实际上只是作为子名称空间运行。在C#中,您将类标记为
    static
    ,在Java中,您希望将其设置为
    final
    ,并给出一个无法访问的构造函数:

    final class C { 
        private C() { throw new AssertionError("C is uninstantiable"); }
        public static final int OMGHAX = 0x539; 
    }
    
    如果您使用Java编程,并且希望常量不以常量类名作为前缀,那么可以使用
    import static
    功能


    是的,被迫创建一个新类型只是为了有地方放置常量是有点多余的,但这是像Java和C#这样的语言中的一个缺点,我们必须处理它——我们必须将常量放在某个地方,而我们最好的选择恰好是一个不可实例化的类

    在某些情况下,当全局常量是真正的常量时(不仅在程序的一个构建中是常量,而且在软件产品的整个生命周期内以及以后都是常量),全局常量是最好的选择

    例如,您不希望有多个类,每个类都声明自己的常量以获得pi、e或HTTP_成功


    另一方面,如果全局常数是可以更改的任意值(例如,由于需求的变化),则全局常数可能会产生许多全局变量问题。也就是说,如果将这些常量放入配置文件似乎是一个合理的选择,那么它不应该是全局常量。

    是的,但我问的是全局常量。什么设计模式使用全局常量?他说的是反模式。什么是反模式?(几乎存在)反模式要么是一个应用不当的设计模式(因此它不能满足应用程序的需求,要么是无效的),要么是一个问题的糟糕解决方案(与设计模式完全相反)。如果值经常更改,它不是一个常数:)我的意思是程序员经常更改值,而不是在运行时更改值。但在一个程序执行的生命周期内,常量可能会这样做。对于一个很长的运行过程,我想熵最终会得到它-(配置/属性文件还有一个优点——搜索其中的文本要快得多(例如,当您需要重命名窗口、按钮标签时)。这里解释了全局文件的问题:对于技术面试来说,这是一个极好的答案。