Как добиться разделения слоев, не смешивая мой репозиторий с моей службой API?

(Внизу есть TL;DR:)

У меня есть PDF-файл, созданный с помощью шаблона MVC. Я работаю с существующим кодом, который был немного запутанным, но теперь я вижу появление шаблона.

В настоящее время у меня есть класс Controller, и внутри у меня много разных функций, примерно по одной функции на страницу. Каждая функция делает что-то вроде этого:

function showPage()
{ 
    //get some data from repository
    $data1 = $this->repository->getData1();
    $data2 = $this->repository->getData2();

    //pass that data to the PDF API class, aka "the view"
    //and the class takes care of creating PDF pages
    //with the appropriate data
    $this->pdfApi->showView($data, $data2);
}

Вышеупомянутое обеспечивает четкое разделение между Repository (который только возвращает данные), службой API PDF (которая получает данные и не нуждается в уходе или обслуживании конструкций извлечения данных). И контроллером, который в значительной степени просто запрашивает данные и передает их в PDF API, и все было хорошо, пока я не столкнулся с этой проблемой:

Проблема

Почти на каждой странице есть «нижний колонтитул» с сообщением и «Номер предложения», который необходимо отобразить на странице. Иногда он также имеет другие части данных. Поскольку класс PDF API не имеет данных сам по себе, кто-то должен передать эти данные в PDF API. Я каждый раз передавал это в части информации как часть параметров функции, но это стало неудобно — слишком много параметров для передачи и они загромождают код.

Попробуйте решение

Чтобы уменьшить беспорядок при передаче параметров, в моем Controller я создал извлеченные данные (через Repository) для таких переменных, как $footerText и $proposalNumber, а затем использовал их, чтобы заполнить собственные свойства класса PDF API. Побочным эффектом этого является то, что теперь мой PDF API имеет соответствующие биты данных, встроенные непосредственно в API (что я считаю нежелательным, поскольку уровень данных теперь накладывается на класс API)

До сих пор я сопротивлялся искушению просто передать весь объект Repository в PDF API, потому что это будет делать то же самое - смешивать уровень данных и уровень API, плюс уровень API будет иметь неограниченный доступ к данным, что также может быть нежелательным.

Актуальная проблема

Когда я хочу четкого разделения слоев, мой код загромождается передачей нескольких параметров функции.

Когда я передаю весь Repository своему классу API, я смешиваю уровни данных и API, и слой API получает слишком много свободы для использования класса Repository.

Могу ли я каким-то образом добиться разделения слоев без беспорядка или проблем «смешивания слоев», указанных выше?

Если вам нравится видеть код, вот код ниже моих различных неудачных попыток :)

TL;DR: мои различные безуспешные попытки разделить слои или уменьшить беспорядок оказались безуспешными

//in Controller - Exhibit 1 
//Separation achieved with only data parameter passing tying layers together
//but, too much clutter -- too many parameters

//maximum layer separation but lots of annoying data passing
$data1 = $this->repository->getData1();
....
$data24 = $this->repository->getData24();
$this->pdfApi->showView($data1, $data2, $data3, ... );
//in Controller - Exhibit 2
//Layers are mixed - my data is now tied into API

//in constructor
$data1 = $this->repository->getData1();
....
$data24 = $this->repository->getData24();
$this->pdfApi->setData1($data1);
$this->pdfApi->setData24($data24);

//inside function (API already has data as part of its own vars):
$this->pdfApi->showView();
//in Controller - Exhibit 3
//layers are mixed -- entire Repository got into my API  

//in constructor
$repo = new Repository();
$this->pdfApi->setRepository($repo);

//inside function (API has full Repository access gets its own data and more):
$this->pdfApi->showView();

person Dennis    schedule 25.04.2016    source источник


Ответы (1)


Я думаю, что Приложение 1 является наиболее правильным.

//inside Controller
$data = array(
    'data1' => $this->repository->getData1(),
    //...
    'data24' => $this->repository->getData4()
):

$this->pdfApi->showView($data);

Я говорю это потому, что популярный фреймворк ZF2, который я использую, также приписывает тот же шаблон.

//inside Controller
$data = array(
        'message' => 'Hello world',
);
$view = new ViewModel($data);

В моем случае View — это PDF API.

person Dennis    schedule 26.04.2016