0

假设我有一个加载和解析配置文件的类。但是,该配置文件可以是 3 种类型:

  • JSON
  • YAML
  • INI

我如何设计我的“configLoader”以保留东西:

  1. 松耦合
  2. 易于单元测试
  3. 易于切换组件(例如,将旧解析器更改为更好的新解析器)

但同时:

  1. 易于扩展(我的意思是添加新类型的可接受文件,例如 XML)
  2. 没有大量的构造函数或设置器以使类工作

一些笔记

  • 所有解析器都实现相同的接口(ParserInterface)
  • 例如,可以充当 Symfony/Yaml 等知名解析器的包装器(适配器)
  • 此类在 DI 容器初始化之前初始化(在逻辑中,此处加载的值实际上将注入 DI 容器中),因此在此处使用它不是一个选项

代码

这是我到目前为止所拥有的:

class Loader
{

    /**
     * Loads a configuration string from a ConfigFile
     * 
     * @param ConfigFile $configFile
     * @throws ConfigException if the file type is not recognised
     * @return Config ArrayObject with configuration settings
     */
    public function loadFromFile(ConfigFile $configFile)
    {
        // Finds out what type of config file it is
        $type = $configFile->getType();
        //Loads the file into memory
        $configString = $configFile->read();
        
        switch ($type) {
            case ConfigFile::TYPE_YAML:
                $parser = new YAML\YamlParser(); //Here's the problem
                break;
            
            case ConfigFile::TYPE_JSON:
                $parser = new JSON\JsonParser(); //Here's the problem
                break;
            // (...) same for other file types
            
            // Default case if file type is not recognised
            default:
                throw new ConfigException('Config File type not recognised');
        }
        return $parser->decode($configString);
    }
}
4

2 回答 2

1

我会像Symfony Config Component那样做。实际上,我可能只是使用它。

于 2013-05-12T17:49:38.747 回答
1

怎么样:

interface ParserInterface{
  public static test(ConfigFile $configFile);
  // other required methods
}

你的加载器方法:

$classes = get_declared_classes();
foreach($classes as $class){
  $class = new \ReflectionClass($class);

  if(!$class->implementsInterface('ParserInterface'))
    continue;

  $parser = $class->getName();

  if(!$parser::test($configFile))
    continue;

  $parser = $class->newInstance();
  return $parser->decode(...);
}  

throw new Exception(...);

而且您刚刚“反转控制”到配置文件本身确定要使用的解析器的程度

于 2013-05-12T18:16:32.577 回答