(Есть 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
(который только возвращает данные), сервис PDF API (который получает данные и не нужно заботиться или поддерживать конструкции поиска данных. И контроллер, который в значительной степени просто запрашивает данные и передает их в PDF API. И все было хорошо, пока я не столкнулся с этой проблемой:
проблема
Почти на каждой странице есть «нижний колонтитул» с сообщением и «номер предложения», который необходимо отобразить на странице. Иногда это также имеет другие части данных. Поскольку у класса PDF API нет данных, кто-то должен передать эти данные в PDF API. Я каждый раз передавал вышеизложенное для фрагментов информации как часть параметров функции, но это стало неудобно — слишком много параметров для передачи, и они загромождают код.
Попробуйте в решении
Чтобы уменьшить беспорядок в передаче параметров, в моем Controller
Я создал вытащенные данные (через Repository
) для переменных, таких как $footerText
а также $proposalNumber
и затем, используя их, я заполняю собственные свойства класса PDF API. Побочным эффектом этого является то, что теперь мой PDF API имеет соответствующие биты данных, встроенные непосредственно в API (что я считаю нежелательным, поскольку уровень данных теперь накладывается на класс API)
До сих пор я сопротивлялся искушению просто пройти весь Repository
возражать против PDF API, потому что это будет делать одно и то же — смешивать слой данных и API Layer, плюс, слой 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();
Я думаю, что Приложение 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
Других решений пока нет …