В этой короткой статье я постараюсь кратко суммировать виды моделей, реализации которых я наблюдал на протяжении многих лет, отмечу некоторые преимущества и недостатки каждого подхода и подведу итог — что предпочитаю именно я и почему.
Просто модели
Голые модели без каких-либо аннотаций, например:
class User { /** @var string */ public $email; }
Контроллеры и представления обычно полностью захардкожены с учетом конкретных типов входящих данных — это самый простой подход, но не самый изящный.
Модели плюс объекты-типы
Каждая модель имеет свой объект, отвечающий за конкретный тип, обычно они совпадают с именованием свойств модели и содержат мета-информацию:
class User { /** @var string */ public $email; }
class UserType { /** @var EmailInput */ public $email; public function __construct() { $this->email = new EmailInput('email'); $this->email->required = true; $this->email->unique = true; } }
Это требует более четкой работы модели, но дает возможность повторного использования кода объектов-типов, например `$qunique` может быть использована для валидации CSRF-токенов, формирования схем, уникального ID и т.д.
Подход по-прежнему простой, т.к. не требует никаких фреймворков и библиотек.
Аннотированные модели
Мета-данные внедрены внутрь исходного кода в виде аннотаций:
class User { /** * @var string * @input(type="text") */ public $first_name; }
Такой подход лежит на поверхности, он проще, чем подход моделирования через объекты-типы. Однако, парсинг аннотаций требует сложной работы с логикой, которая выполняет синтаксический анализ, валидацию, кэширование и др. На самом деле это далеко не так просто.
Мета-моделирование с кодогенерацией моделей
Предполагается создание моделей во время исполнения через фреймворк кодогенерации, это может выглядеть примерно так:
$class = new MetaClass('User'); $class->addProperty(new EmailProperty('email')); $code_generator->run($class);
Кодогенератор будет содержать модель, мета-модель и, возможно, другие вещи, такие как фабрика классов и т.д.
В то же время пассивная (во время разработки) генерация кода, в отличие от активной (во время выполнения) действительно обеспечивает статическое связывание во время разработки, но, возможно, не в полном объеме — например, при рефакторинге (изменение именования свойств) предполагает шаг генерации кода, что в свою очередь усложняет разработку, ведь вы не сможете иметь действительно автоматический рефакторинг, как это предполагает активный подход.
Само собой разумеется, это далеко не просто — вам необходим большой и сложный код для движка генератора, более тщательное проектирование и оптимизации.
Мета-моделирование по спецификации
Этот подход используется, например, в языке M#, в котором декларативная спецификация записыватется на специальном языке, скармливается парсеру и используется для кодогенерации.
Предпосылкой является краткость, но, очевидно, это происходит за счет очень высокой степени сложности реализации, начиная от языка описания моделей, которому требуется особая поддержка IDE, а также приплюсовывается вся сложность и недостатки других подходов с кодогенерацией.
Кодогенерация из объектов-типов
Подход похож на второй («Голые модели плюс объекты-типы»), но с генерацией актуальной модели через использование объектов-типов.
В некотором смысле, этот подход является одновременно самым лучшим и самым худшим из всех — вы описываете и составляете модель, реализуя свои объекты-типы с использованием всех возможностей базового языка, также вы избегаете необходимости что-либо повторять, но одновременно с этим приходят и проблемы — рефакторинг уже сформированных моделей и некоторые другие сложности, которые плодят системы кодогенерации.
Заключение
Мой фаворит — модели плюс объекты-типы, потому что:
- Избегаем генерации кода.
- Статическое связывание и автоматический рефакторинг везде.
- Нестатические имена свойств в виде строк инкапсулируются в объект-тип, не повторяются и становятся безопасными.
Подход сохраняет общую сложность на низком уровне, сохраняет высокую прозрачность, убирает необходимость тратить время на дизайн модели и полностью устраняет необходимость в фреймворке на любом уровне, только модели, объекты-типы и просто код.
Конечно, не все разработчики могут быть согласны со мной, возможно кто-то даже назовет еще пару способов, но основной посыл статьи — открыть путь к новому и вдохновить вас на получение дополнительных знаний.
ссылка на оригинал статьи http://habrahabr.ru/post/267385/
Добавить комментарий