Комментарии к коду - Katemare/Entlink GitHub Wiki

Table of Contents

Выполняемые задачи

  1. Показать сущность, сохранённую в базе данных (БД). Пример: страница покемона.
  2. Показать форму для ввода новой сущности. Пример: создание нового покемона.
  3. Сохранить новую сущность, введённую через форму. Пример: сохранение созданного покемона.
  4. Показать форму для редактирования сущности, сохранённой в БД. Пример: редактирование созданного покемона.
  5. Сохранить отредактированные данные сущности, уже существующей в БД. Пример: сохранение отредактированного покемона.
  6. Найти сущности из БД согласно критерию. Пример: найти огненных покемонов.
  7. Показать список сущностей из БД. Пример: показать огненных покемонов.
  8. Показать статистику некоторых сущностей из БД. Пример: посчитать огненных покемонов.
Как показ, так и другие действия с сущностями могут задействовать не все составляющие их данные. Например, редактирование не включает комментарии, оценки и прочее. Просмотр может не включать какие-нибудь все изображения - они могут быть на другой страницы. Редактирование всё же может включать связанные сущности: например, редактирование списка атак - добавление новых, создание новых, удаление из списка, изменение типа связи.

Судя по всему, некоторые фрагменты показа могут быть временными сущностями, возникающими только во время показа. Например, именно так может быть легче всего сделать статистику и списки.

Основная структура

Покемон, атака покемона, название атаки покемона, связь атаки с покемоном - всё это сущности.

Сущность создаётся с помощью абстрактного класса-фабрики. Первая стадия сущности - это объект класса Entity. Мы не всегда знаем заранее, какого "типа" должен быть этот объект (покемон, атака, текст...). Когда мы уже знаем тип - например, когда получили данные из БД - мы можем установить тип объекта. Далее мы обращаемся к фабрике данного типа - абстрактному классу EntityFatory_<type>. Она создаёт структуру, которая далее заполняется по мере надобности.

Сущность известного типа может иметь два под-объекта: хранитель (наследник EntityStorage) и поведение (наследник EntityBehavior). Конкретные названия классов задаются фабрикой или, редко, процессами, которые требуют существование данной сущности. Хранитель не связан строго с поведением: одно и то же число или название может храниться разными методами. Поведение не должно быть зависимо от этих методов.

Объекты хранителя и поведения не обязаны создаваться сразу. Они создаются при первом запросе к соответствующим им функциям, хотя во многих случаях это очень скоро.

Данные

По сути все более ли менее сложные сущности являются набором простых значений: числа, текст, даты, идентификаторы... Поэтому все сущности, не являющиеся базовыми, создаются фабриками-наследниками EntityFactory_combo. От обычной фабрики их отличает наличие модели: массива, хранящего данные о внутренних сущностях согласно некоторому формату. Базовые сущности, напротив, не знают заранее, как они будут использоваться - в качестве названия, числа или даты чего - поэтому у них не может быть этой информации.

Пример модели из фабрики изображений:

static $model=array(
	'nam'=>array( // сущности с названием файла.
		'table'=>'pictures', // таблица, в которой хранится это значение.
		'type'=>'string' // тип сущности, хранящей это значение.
	),
	'path'=>array( // сущность с относительным адресом
		'table'=>'pictures',
		'type'=>'string'
	),
	'thumb'=>array( // сущность с информацией о том, есть ли у картинки миниатюра
		'table'=>'pictures',
		'type'=>'string',
		'optional'=>1, // эта сущность не является обязательной, её может у изображения и не быть.
		'default'=>'none' // значение по умолчанию.
	)
);

Когда сущность-комбинация получает команду "показать себя" и определяется с форматом, она ставит в очередь получение дочерних сущностей, нужных в формате. Когда дочерние сущности успешно создаются и получают данные, они в свою очередь выполняют команду "показать себя", и так пока дело не дойдёт до базовых сущностей, которые уже ничего не запрашивают. Если дочерняя сущность является базовой, она получает сокращённую версию модели, касающуюся только её (например, сущность-строка с названием файла - первый элемент массива выше). Сущности-комбинации уже имеют собственные модели.

Слово "дочерние" здесь используется условно. Часто мы можем определить логически, что значение атаки - это дочерняя сущности к её атаке. Однако если речь идёт об отношениях сложных сущностей, то какая сущность является "главной" - сказать нельзя. На странице покемона его атаки будут выглядеть как дочерние. Однако на странице атаки также есть список покемонов. Что касается комментариев, рейтингов и других подключаемых модулей, то они вовсе не могут быть предусмотрены в моделях заранее. Вероятно, они будут подключаться с помощью "крючков". В модель следует добавлять только те "дочерние" сущности-комбинации, которые часто являются частью одного модуля (например, "Покемоны") и часто будут показываться на странице просмотра "родительской" сущности.

EntityStorage, или Хранитель

Это абстрактный класс, экземпляр наследника которого создаётся в каждой сущности, тип которой нам уже известен. Этот класс выполняет следующие функции:

  • Делает все необходимые действия, чтобы когда информация понадобилась - она была как можно скорее получена.
  • Делает все необходимые действия для записи информации.
  • Записывает данные о том, откуда была получена информация - БД, пользовательский ввод, значение по умолчанию... Также записывает данные об ошибках процесса получения информации.
  • Оценивает надёжность информации относительно того, откуда она была получена.
  • Этот класс не осуществляет непосредственно запросы к БД, хотя составляет их.
У этого класса не очень много наследников, потому что существует не очень много типов хранения.
  • EntityStorage_combo: Хранитель для сущностей-комбинаций. В особенности они отличаются тем, что не имеют "значения", а составлены из других сущностей. Поэтому они хранятся следующим образом:
    • Уникальный идентификатор и тип в таблице entities.
    • Сущности-поля в таблицах согласно модели.
    • Сущности, на которых указывают связи, в таблице entities (и далее согласно их собственным хранителям).
  • EntityStorage_combo_member: Хранитель для сущностей-значений, которые являются полями таблиц и не имеют своего идентификатора. Этот тип хранения существует для
  • EntityStorage_compact: Хранитель для простых значений, для которых есть подходящие стандартные поля в entities. Таким образом вся сущность хранится в одной таблице.

EntityBehavior, или Поведение

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

  • Осуществляет подготовку к показу сущности, то есть передаёт хранителю информацию о том, какие данные понадобятся.
  • Составляет собственно показ сущности.
  • Проверяет легальность сведений, учитывающий тип сущности. Например, чтобы уровень изучения атаки покемона не был выше 100.
Наследников этого класса очень много, их число приближается к числу типов сущностей.
⚠️ **GitHub.com Fallback** ⚠️