Есть ли название для этого шаблона проектирования (передайте себя одной из ваших собственных зависимостей), и каковы подводные камни такой техники?

Я не слепо следую шаблонам дизайна (нам действительно просто нужно понять объект связи ИМО), но я тоже не хочу быть в неведении о них.

Есть ли название для шаблона проектирования (аналогично Шаблон делегирования, используемый здесь или, может быть, какая-то двойная модель стратегии-вещи-ма-боппера), но вместо того, чтобы переписывать каждый метод и делегировать, вы просто передали бы ссылку ($ this) себе в зависимость? И это разумное решение, чтобы иметь в наборе инструментов для программистов?

Нужен практический пример? Конечно … Продолжайте …


Представьте, что вы используете DI-контейнер и, возможно, у вас есть какой-то метод Controller (MVC), подобный этому:

Рисунок 1:

// Phew! Four dependencies injected here:
public function index(QueryManagerInterface $queryManager, BlogQueryInterface $blogQuery, RenderQueryPDFInterface $queryPDFRenderer, RequestInterface $request) {

// Do some "managing" of a query, then render it into a PDF

$queryManager->setQuery($query);
$queryManager->addInput($request->input());
$queryPDFRenderer->setQuery($query);
$output = $queryPDFRenderer->render();

return $output;
}

Теперь представьте, что ваш метод Controller выглядит следующим образом:

Фигура 2:

// Nice! Just two dependencies!
public function index(BlogQueryInterface $blogQuery, RequestInterface $request) {

$blogQuery->getQueryManager()->addInput($request->input());
$output = $blogQuery->getPDFRenderer()->render();

return $output;
}

Как я это сделал? Весь код одинаков во всех этих классах, за исключением того, что я обновил класс $ blogQuery:

Class BlogQuery Implements BlogQueryInterface, QueryManageableInterface, PDFRenderableInterface {

public function __construct(QueryManagerInterface $manager, $PDFRendererInterface $pdfRenderer){

// Here I pass a reference of this own class into its dependencies
$this->manager = $manager->setQuery($this);
$this->pdfRenderer = $pdfRenderer->setQuery($this);
}

public function getQueryManager() { return $this->manager; }
public function getPDFrenderer() { return $this->pdfRenderer; }

...

}

Плюсы рисунка 2:

  • Меньше зависимостей от метода Controller
  • Меньше строк кода
  • Композиция по наследству (более слабо связаны?).
  • Нет необходимости «набирать кучу повторяющихся методов», как при использовании шаблона делегирования.
  • Более понятно. Внедрение только BlogQuery и запроса, кажется, захватывает основной контекст. (Субъективно)

Какой шаблон я использовал на рисунке 2? Каковы минусы такого подхода? Такой подход считается хорошей практикой?

2

Решение

Это выглядит для меня как Шаблон посетителя, где __construct делает QueryManagerInterface а также PDFRendererInterface посетители BlogQuery,

Я не хочу слишком увлекаться плюсами и минусами шаблонов программирования, потому что по большей части они будут прежде всего основанный на мнении. Но один довольно объективный результат шаблона посетителя состоит в том, что он имеет тенденцию к большему отскоку между файлами / классами, чем другие опции, что может затруднить загрузку программы чтения для читателя. В конечном счете, «хорошая практика ООП» сводится к опыту, суждению и, вероятно, переписыванию его три раза.

Я хочу отметить, что вы на самом деле не уменьшили зависимости вашего index функция. Да, требуется меньше аргументов, но он все еще знает, как QueryManagerInterface а также RenderQueryPDFInterface вести себя. Если эти интерфейсы изменятся (например, переименуйте addInput или же render), ваш код в index также должен измениться. Когда вы тестируете indexВам все еще нужно настроить или смоделировать эти два объекта для прохождения теста. Если вы не можете скрыть это поведение внутри BlogQueryInterface а также RequestInterface (см. также Закон Деметры), index имеет одинаковые зависимости в обоих подходах.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]