首页 > 解决方案 > 将依赖项隐藏在外观后面时,正确的命名约定是什么?

问题描述

我有一个类执行一些操作,比如解析,它将成为一个公共存储库。因为构造函数有些复杂,而且对最终用户来说并不重要,所以我想将它隐藏在外观后面。

// interface
interface ParserInterface {
    function parse(string $input): Document;
}

// implementation
class ParserImplementation implements ParserInterface {
    function __construct(
        Normalizer $normalizer,
        Tokenizer $tokenizer,
        Interpreter $interpreter,
        etc.
    ) {
        $this->normalizer = $normalizer;
        $this->tokenizer = $tokenizer;
        $this->interpreter = $interpreter;
    }

    function parse(string $input): Document {
        $normalizedInput = $this->normalizer->normalize($input);
        $tokens = $this->tokenizer->tokenize($normalizedInput);
        return $this->interpreter->interpret($tokens);
    }
}

// facade
class ParserFacade implements ParserInterface {
    private $parser;

    function __construct() {
        $this->parser = new ParserImplementation(
            new Normalizer(),
            new Tokenizer(),
            etc.
        );
    }

    function parse(string $input) {
        return $this->parser->parse($input);
    }
}

如您所见,那里还有一个界面。

现在,对于外部应用程序,它是解析器的外观。对于相互依赖的代码,它是解析器的接口。对于开发上述解决方案的我来说,ParserImplementation 才是真正的解析器,即它包含了整个解析逻辑。所以现在,我完全不知道正确的命名约定。

我更愿意将接口命名为 Parser,而将 fasade 命名为有点说明我的意图:CustomParser,因为整个是具有某些标准实现的东西的自定义实现。但是后来我找不到命名内部类的模式(上面代码中的 ParserImplementation )。

在这方面是否有成熟的做法?

标签: phpnaming-conventions

解决方案


这是相当主观的,但我通常做的,我最常看到的是这样的:

接口:解析器接口

摘要: ParserAbstract

实现:解析器

外观:为特定目的命名(CsvParser、XmlParser 等),或类似 DefaultParser 或 GenericParser

如果是我,我可能会用抽象而不是外观方法来处理这个问题。因此,我会将 ParserImplementation 类更改为抽象类,并使您的 ParserFacade 扩展该类,并将其称为 Parser。如果您想提供该类的简化实现那么您可以采用外观路线,但在这种情况下可能不需要这样做。

<?php

// interface
interface ParserInterface
{
    function parse(string $input): Document;
}

// abstract
abstract class ParserAbstract implements ParserInterface
{
    function __construct(
        Normalizer $normalizer,
        Tokenizer $tokenizer,
        Interpreter $interpreter
    )
    {
        $this->normalizer  = $normalizer;
        $this->tokenizer   = $tokenizer;
        $this->interpreter = $interpreter;
    }

    function parse(string $input): Document
    {
        $normalizedInput = $this->normalizer->normalize($input);
        $tokens          = $this->tokenizer->tokenize($normalizedInput);
        return $this->interpreter->interpret($tokens);
    }
}

// Concrete class
class Parser extends ParserAbstract
{
    function __construct()
    {
        parent::__construct(
            new Normalizer(),
            new Tokenizer(),
            new Interpreter()
        );
    }
}

// Concrete class
class XmlParser extends ParserAbstract
{
    function __construct()
    {
        parent::__construct(
            new NormalizerXml(),
            new TokenizerXml(),
            new Interpreter()
        );
    }
}

推荐阅读