常量类与全局常量

3

我正在处理一个项目,其中所有的全局常量都被定义在一个名为Constants的类中,例如:

class Constants
{

  const MIN_VALUE = 0.0;
  const MAX_VALUE = 1.0;

  public static function getMinValue()
  {
    return self::MIN_VALUE;
  }

  public static function getMaxValue()
  {
    return self::MAX_VALUE;
  }

  public static function getValueDependingOnURL()
  {
    if($_SERVER['REQUEST_URI'] == 'something')
    {
      return self::MIN_VALUE;
    }
    else
    {
      return self::MAX_VALUE;
    }
  }
}

然后在整个代码中,类似于 Constants :: getMaxValue()这样的东西用于获取常量的值。 这似乎是一种非常奇怪的方法,为什么不直接在最外层使用define 函数呢? 我知道 define()可能会相当慢,但是肯定调用类属性不是最有效的方法吧?
编辑:此外,一些函数中有条件,因此需要调用函数。

2
为什么需要静态方法?Constants::MIN_VALUE将完全起到同样的作用。 - vascowhite
这没有任何意义。 - vascowhite
1
为什么有两个人选择将此问题标记为“基于观点的”?配置容器和全局定义常量都有明显的优缺点,这与观点无关。看起来问题的观众和提问者本身在软件设计经验水平上处于同一水平 :-) - Daniel W.
3个回答

2
清晰化问题:配置容器相对于全局定义(define())的配置常量有什么优势?
这些优势都是面向对象编程提供的优势:数据抽象和封装,继承,多态以及更好的设计模式集成。
本帖的读者似乎有点困惑,把焦点放在了你的类上而不是主要问题上。为了进一步澄清这一点,让我举个例子:
class Configuration
{
    protected $someValue;
}

class ConfigurationDev extends Configuration
{
    protected $baseUrl = 'http://devel.yoursite.com/';
}

class ConfigurationLive extends Configuration
{
    protected $baseUrl = 'http://www.yoursite.com/';
}

index.php:

<?php
$config   = new ConfigurationDev;
$tracking = new Tracking($config);
...

追踪类:

class Tracking
{
    public function __construct(\Configuration $config) {
        if ($config instanceof \ConfigurationLive) {
            // We are in live environment, do track
        } else {
            // Debug Notice: We are NOT in live environment, do NOT track
        }
    }
}

场景说明:

假设您想要追踪用户,但仅在实时系统上进行,而不是在开发系统上进行。Tracking类期望一个实时配置,但如果不是实时配置,则会中止(没有影响)。

您的带有const的类并不是最好的选择,因为const意味着您不想更改变量。不要使用可能会更改的变量值。您也不应该使用静态内容,因为它通常与依赖注入冲突。传递真实的对象!

您的函数public static function getValueDependingOnURL() 应该放在 Helper 类中,而不是 Constant/Configuration 容器中。

class Helper
{
    protected $config;

    public function __construct(\Configuration $config) {
        $this->config = $config;
        return $this;
    }

    public function getValueByUrl($url) {
        if ($url == 'something') {
            return $config->getMinValue();
        } else {
            return $config->getMaxValue();
        }
    }
}

现在,您可以拥有不同的配置集,助手类依赖于这些配置集:
$config = new ConfigurationLive;
$helper = new Helper($config);
$value  = $helper->getValueByUrl($_SERVER['REQUEST_URI']);

我的例子中有很多最佳实践的设计模式、代码风格和面向对象编程,学习这些内容会让你比提问者拥有更高水平的软件工程能力。祝你好运!


1
非常好的回答。谢谢! - Pattle

0
你也可以通过 Constants::MIN_VALUE 这样的方式来获取常量。自己试试看吧。

是的,我可以。但有些函数执行条件,所以需要调用该函数。 - Pattle
1
@Pattle: "执行条件"? 返回一个常量的值? - Jon
好的,我明白了。但是我认为声明一个全局变量并不好,因为它违反了良好软件工程的原则。如果全局变量没有存储在一个文件中,它还可能使你的代码混乱不堪。 - Justin Paul Paño
问题不在于如何改进代码,而在于容器类相对于define的优势是什么。 - Daniel W.
1
然后他所做的是正确的。@Pattle在类的方法中维护了他的验证,这极大地促进了代码的可重用性。 - Justin Paul Paño

0
如果你在询问类常量与全局作用域中定义的常量的优势,我会说类常量可以是一种更清晰的方法,因为它的范围有限。此外,在使用它的类中定义一个MAX_VALUE常量是有意义的,而不是在其他地方定义。
但这似乎不适用于你的情况,因为你的Constants类似乎像是一些随机常量的容器。MIN_VALUE是什么?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接