Деловая неделя

Предметная логика прежде всего требуется в общении с посетителями, а такое общение начинается с Вида. Поэтому будем создавать Толстые Тупые Уродливые Шаблонизаторы!

ЕЖЕНЕДЕЛЬНАЯ РЕКЛАМНАЯ ГАЗЕТА ДЛЯ ПРЕДПРИЯТИЙ «Деловая неделя» (Иркутск)

Данные и Представление: «проблема разъёма»

Это продолжение исследования, начатого в статье http://dn.ir2.ru/asimmet.aspx.

Шаблон проектирования Дамп (dump) или Калька

Такой шаблон может применяться в некоторых специфических случаях: например, для программы-редактора mysql-таблиц http://ir2.ru/ct/mmedit/. Он работает, как это ясно из названия, по принципу «точного» вываливания содержимого mysql-таблиц в html-таблицы, отображаемые в браузере:

mmedit.gif

Редактор mmedit (Mysql Mini Editor) отображает не только таблицы, но и вообще любые запросы, возвращающие ресурс. Он отвечает одному из главных принципов фреймворка – полное безразличие к обрабатываемым данным (базы данных и таблицы в пределах mysql можно заменять как угодно). Это идеальная схема общения Данных и Представления (когда все всем пофиг, никто ни о ком ничего не знает).

Что делать, когда вывести данные в HTML надо не однородно (как ячейки таблицы), а произвольно, например, как в каталоге ссылок irweb.ir2.ru:

link_descr.gif

– когда в первой строке три элемента (Ссылка на сайт, Город, Дата), во второй – один (Краткое описание), в третьей – два (Ссылка на полное описание, Раздел)? Можно упрямо пытаться применить всё тот же Дамп-Кальку – например, упаковав каждый из элементов в тэги p и назначив части из них стили float:left, а другой части float:right. В принципе, это возможно. О плавающем позиционировании имеют право не знать ни Данные, ни Шаблонизатор, а заниматься им будет только Финишный Шпаклёвщик – CSS.

Такое восстановление «линейности», однако, уже сопряжено с дополнительной условностью – порядком вывода полей из mysql-запроса, если мы хотим, чтобы по-прежнему «никто ничего ни про кого не знал». А это значит, что кому-то кое-что придётся узнать. А именно: Представление должно частично сработать как Экстрактор и выдать предписание Данным, в каком порядке выводить поля запроса.

Это можно сделать с помощью управляющего данными массива. Нам всё равно нужен будет такой массив – хотя бы для русских наименований полей (в варианте вывода в пользовательскую таблицу), так почему бы заодно не использовать его и для сортировки:

Теперь для вывода данных в нужном порядке надо просто использовать foreach не для массива $data, а для массива $names, а уже потом обращаться по индексу к $data (хотя такого индекса в $data, по закону подлости, может и не оказаться -:).

Проблема разъёма (асимметрия Данных и Представления)

Все наши попытки сохранить равновесие всё равно катятся под откос, из-за того что часть элементов у нас – ссылки, а для вывода одной ссылки нужно больше одного поля данных. То есть, если Данные – электрическая розетка, а Представление – вилка, то в розетке будет в данном случае больше дырок, чем стержней в вилке, – и возникнет та самая проблема (плохого) разъёма, проблема невозможности простой, линейной состыковки:

Одному элементу «Ссылка на сайт» в Представлении соответствуют два поля в массиве Данных: url и title (как и должно, в общем-то, быть для ссылки). Опытные разработчики скажут: "Ну и в чём проблема?" Попросту возьмём и заполним шаблон:

А проблема в том, что это уже будет не Калька-Дамп, и вообще никакой не шаблон проектирования (на что, впрочем, на---ть), но система утратит главное свойство фреймворка – независимость от материала. Упоминание конкретных полей (url, title) связывает код по рукам и ногам; в следующий раз, когда таблица будет другая (или понадобится вывести другие поля из этой же), нам придётся найти и поменять этот конкретный участок кода (и не один этот). А в идеальном фреймворке должно быть достаточно поменять только mysql-запрос (как это происходит в упомянутом выше mmedit).

Варианты исправления «Плохого разъёма»

Вариант 1. Вылавливать ссылки из структуры полей mysql. Это нормальная договорённость: находить в запросе первичные ключи (адрес ссылки) и поля с именем "name" (текст ссылки) в той же таблице, где ключ. Схема решает наш конкретный вопрос на 75%: три ссылки из четырёх (считая, что Город тоже может быть ссылкой) строятся именно по такой схеме. Но главная ссылка url->title (ради которой делается Каталог) в схему не укладывается.

Вариант 2. Добавить в управляющий массив метки, объединяющие по два поля, необходимых для создания ссылки. Он, собственно, не исключает Вариант 1, а дополняет его: часть ссылок помечается на основании «автоматики» – вылавливания пар primary key => name, а другая часть – произвольно (на основании предметной логики – требований жизни).

Вариант 3. Можно сделать и немного наоборот: воплотить требования предметной логики в структуру таблицы (исправить структуру) – заменить в Главной таблице ссылок наимнование title на name (а url и так является первичным ключом), и тогда Вариант 2 в данном случае станет вовсе не нужен. Но мы не можем гарантировать, что он не понадобится для каких-то других произвольных объединений элементов (не обязательно ссылок).

Управляющий массив

Управляющий Данными массив... Нет, управляющий преобразованием Данных массив принадлежит (относится к) Представлению. Массив или целый Объект. Что он делает? Он ожидает от Данных некоторых конкретных полей и описывает, что с этими полями делать. В идеале он ожидает некоторых классов полей (как в Варианте 1 исправления Плохого разъёма). В менее идеальном случае – конкретных полей. Что будет, если этих полей нет в Данных? Ничего: обработчик массива сверит Данные с условиями и отправит (преобразованные или нет) Данные дальше – в шаблонизатор. То есть это такой гигантский IF: если находит, что ищет, переводит Данные в более сложную форму, а в случае отсутствия необходимых условий должен срабатывать метод Калька-Дамп (Даные вываливаются в шаблон Представления «не глядя», без конкретных имён).

Последнее означает, что шаблонизатор должен работать по принципу Кальки всегда: он получает какие-то Данные в виде массива и с помощью foreach обувает их в один и тот же HTML. Что, в свою очередь, означает, что речь идёт о мелком шаблонизаторе (низкоуровневом): сгенерировать меню, анонсы, список объявлений... Результат его работы, в свою очередь, становится частью данных для более крупного шаблона. Разумеется, если это уже шаблон всей страницы, там тэги могут быть индивидуальны, там шаблон – это просто произвольный шаблон вида:

Общая схема работы Толстого Уродливого Шаблонизатора

1. Самый главный шаблон (уровня страницы) требует заполнения своих элементов (принцип Экстрактор): $menu = build_menu(); $list_item = build_list(1); //...

2. Функции типа build_menu() с помощью собственного sql-запроса (они сами определяют его) извлекают Данные из базы (Экстрактор), сверяют Данные со своим собственным управляющим массивом и преобразуют в случае выполнения некоторых условий; передают подготовленные Данные в цикл Простого шаблонизатора (работающего по принципу Дамп-Калька); возвращают готовый HTML своего уровня.

Гм. А что делает орган работы с Данными (и когда)? И что делает Худосочный Контроллер (ХК)? Ну, ХК, предположим, разбирает УРЛ и на основе полученных результатов выбирает Самый Главный Шаблон (тип выводимой страницы). А орган работы с Данными подключается в тот момент, когда мелкие строительные функции пытаются что-то получить из базы. Или не подключается, если нужный массив данных уже был получен (и сохранён, закэширован) другой функцией.

Работа с Данными – это именно работа с БД (типа CRUD). А где же Предметная Логика («бизнес-логика», как говорят сраные буржуи)? Ясно, что в бизнес-слое... и ещё в том, что мы переименовали поле title в поле name. И что вообще решили выводить часть информации из БД в виде ссылок. А решение это воплощено где-то в глубине одной из строительных функций, которая работает на Представление (на наш ТТУШ).

Что, неправильно? ;-) А вот и правильно :-Р. Логика прежде всего требуется в общении с посетителями, а такое общение начинается с Вида. Ни одна веб-студия шагу не сделает по функционалу без утверждения дизайна. Все на службу ТТУШ!

D.M., admin

Читать все комментарии (0)

Добавить комментарий:

*Автор:
E-Mail:
*Текст: