将静态变量用于全局配置参数的缺点

问题描述:

I know there are other ways to archive this, but the question is... which are the cons about something like:

MyGlobalConfig.php

<?php

namespace Acme\DemoBundle;

class MyGlobalConfig
{
    public static $uploadsDir;
}

AppKernel.php

<?php

use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\Config\Loader\LoaderInterface;
use Acme\DemoBundle\MyGlobalConfig;

class AppKernel extends Kernel
{
    public function __construct($environment, $debug)
    {

        MyGlobalConfig::$uploadsDir = __DIR__ .'/../uploads';

        parent::__construct($environment, $debug);
    }

Article.php

<?php

namespace Acme\DemoBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Acme\DemoBundle\MyGlobalConfig;

/**
 * @ORM\Entity
 */
class Article
{
    protected function getUploadsDir()
    {
        return MyGlobalConfig::$uploadsDir;
    }

我知道还有其他方法可以归档这个,但问题是...... 这是缺点 关于类似 strong>: p>

MyGlobalConfig.php strong> p>

 &lt;?php 
 \  nnamespace Acme \ DemoBundle; 
 
class MyGlobalConfig 
 {
 public static $ uploadsDir; 
} 
  code>  pre> 
 
 

AppKernel.php strong> p>

 &lt;?php 
 
use Symfony \ Component \ HttpKernel \ Kernel; 
use Symfony \ Component \ Config \ Loader \ LoaderInterface; 
use Acme \ DemoBundle \ MyGlobalConfig;  
 
class AppKernel扩展内核
 {
公共函数__construct($ environment,$ debug)
 {
 
 MyGlobalConfig :: $ uploadsDir = __DIR__。'/ .. / uploads'; 
 
 parent  :: __ construct($ environment,$ debug); 
} 
  code>  pre> 
 
 

Article.php strong> p> &lt;?php namespace Acme \ DemoBundle \ Entity; use Doctrine \ ORM \ Mapping as ORM; use Acme \ DemoBundle \ MyGlobalConfig; / ** / n * @ ORM \ Entity * / clas s Article { protected function getUploadsDir() { 返回MyGlobalConfig :: $ uploadsDir; } code> pre> div>

  1. untestable code, since to test any of the using classes you need to be providing them with a MyGlobalConfig with values, but soon you'll notice that it would be really useful if ClassA received different config values than ClassB, so you start creating work-arounds for those. Or classA pollutes the global state with testing values, while ClassB needs original values. Etc. You keep on running around in circles.

  2. Unreusable code, all your config consumers depend on the same, probably monolithic, class. You can't take out a config consumer w/o taking the monolithic class with it.

  3. global state, i.e. modifiable from anywhere w/o a trace and therefore utterly unpredictable and fragile.

  4. less legible code

Probably I forgot a few... It's basically global vars in disguise. Only constants are ok in a global scope, since they're immutable, but even so, many developers use way too many constants for stuff they shouldn't use them for.