MyCMS / Попытки / Теория создания CMS / 1.2. Файловая система и версии
Файловая система и версии.
Не смотря на казалось бы простое название, это одна из наиболее сложных, а следовательно и интересных тем. Не смотря на то, что в первой части рассказ идет framework-е, я буду иногда употреблять понятие cms, чтобы показать связанность частей framework-а как системы.
1. Файловая система.
Большинство систем управляющих сайтами действует по следующей схеме: Создается директория сайта в ней создается директория(и) движка, создаются директории с файлами, количество которых, равно количеству модулей используемых сайтом. Таким образом, получается, что при размещении, например, 30 сайтов на одной площадке, мы имеем 30 версий движков с неизвестным количеством директорий и файлов.
Огромным минусом такого размещения является то, что при обновлении (например, по причине нахождения новой уязвимости), какого-либо класса/модуля необходимо «перекапать» все 30 сайтов, чтобы обновить их реализацию. Второй минус это то, что такое размещение не обязывает разработчика к созданию гибких решений. Третий минус является следствием второго, ввиду того, что гибкость не является приоритетной задачей при построении системы, очень велика вероятность, что классы с одним назначением будут иметь расхождение, хотя бы в одну строчку, а следовательно, мы не сможем их обновить простой заменой файла. И в итоге мы получаем, 30 сайтов поддержка которых требует не малых усилий от компании, взявшей на себя такие обязательства.
Поэтому я предлагаю несколько более трудоемкое, но и более удобное в поддержке решение. Трудность заключается в том, что при реализации системы нужно максимально (но разумно) учитывать гибкость системы, но при этом в поддержке такой продукт проще. При этом если мы посмотрим на то, что сайт разрабатывается от недели до нескольких месяцев, в то время поддержки как правило от полугода до нескольких лет. Думаю, целесообразно немного больше потратить времени на разработку гибкого решения, чтобы потом можно было бы сократить затрачиваемое время на поддержку, кроме того, при реализации одного гибкого решения, мы так же можем его использовать и в прочих проектах, что значительно может сократить время разработки последующих проектов.
Итак, предлагаемое решение по размещению файлов по директориям:
Описанный выше подход иллюстрирует то, что не зависимо от функциональности сайтов, все сайты работают при помощи одного и того же движка. Данная схема позволяет одновременно реализовать все, что можно было бы реализовать при «привычном» подходе и одновременно позволяет осуществлять обновление движка путем обычной замены файлов, не зависимо от того, сколько сайтов и какого направления на нем работают.
Давайте разберем, как работает данная схема.
Начнем с того, что мы начали создавать сайт – что нам для этого необходимо:
1. Файл начальных конфигураций.
Должен содержать адрес системы,
версии главных модулей системы,
параметры доступа к mysql (и пр. службам).
2. Главный файл (index.php).
Должен содержать подключение файла конфигураций,
подключение файла инициализации системы,
создание экземпляра класса (объекта) системы (запуск конструктора),
запуск системы на получение страницы,
запуск деструктора системы.
3. Файл настроек mod_rewrite и конфигураций Apache-сервера (.htaccess).
Должен в первую очередь перенаправлять все запросы (обращения к несуществующим файлам) на главный файл. Так же в некоторых случаях должно осуществляться перенаправление js и css.
4. Файл инициализации системы (.initial/cms.php)
Должен описывать индивидуальные особенности работы системы
При обращении к какой-либо странице, все управление передается на index.php, тот в свою очередь делает подключение конфигураций, в которых обозначены все необходимые параметры для запуска системы. Далее подключает основной абстрактный класс системы, расположенный в директории .cms/system и подключает файл инициализации системы расположенный в директории .initial.
После подключения фалов создается экземпляр класса (объект – инстанцированный класс) и запускается на выполнение система, после того как система «отработала» запускается деструктор главного класса системы. Так, в общих чертах, действует предлагаемый мной вариант. Чтобы немного углубиться в описание системы перейдем к версиям.
2. Версии.
Чем дальше, тем веселее…
Как правило, данной теме, уделяют минимум внимания, я же считаю тему версий одной из важнейших. Чтобы понять важность темы, вновь представим себе, что наша система, предназначена для работы множества сайтов.
Предположим, что имеется 2-сайта, один из которых использует модуль прайс-лист, а другой, модуль меню. По сути, без разницы два это сайта пять или один, но модули прайс-лист и меню - это по функциональности «братья-близницы». Меню это тот же прайс-лист, или прайс-лист – это тот же прейскурант – кому как больше нравится. На различных сайтах функциональность этих модулей может быть несколько ограничена, но не зависимо от возможностей, данный модуль имеет конечную функциональность, при которой его можно классифицировать, как прайс-лист или меню. В идеале, нужно спроектировать и реализовать все возможные варианты функциональности модуля, например такие как, отображение списка, возможность скачивания, версия для печати, разбиение списка на страницы по группам и т. д., но на практике, обычно выходит так, что нужно сделать модуль в четко отведенное время и нет времени по одному месяцу на проектирование и реализацию самого простого модуля с учетом всех возможных вариаций его применения, если того не требует техническое задание. Да и требование технического задания не гарантирует того, что все возможные варианты конфигурации и работы модуля будет описаны. Из подобных ситуаций обычно выходят, посредством наследования, композиций и инкапсуляции объектов, но в любом случае, даже при инкапсуляции объекта - модуля нам может потребоваться слишком много времени, чтобы все правильно спроектировать. А следовательно по ходу написания и расширения системы мы будем сталкиваться с тем, что в некоторых версиях невозможно сделать гибкое и быстрое (в плане оптимальности) решение, а следовательно проще сделать новую версию/надстройку. В дальнейшем версии, различающиеся по функциональности, можно и нужно объединять, но в рамках жестких сроков проще делать некоторые расхождения, главное чтобы они были контролируемыми и не переросли из модуля прайс-лист в модуль авторизация пользователя. Вторая причина, по которой нам нужны версии – это то, что, делая надстройку путем наследования – не факт что все сайты «подвязанные» на этот модуль начнут сразу работать правильно. Поэтому, если вы знаете, что намерены внести серьезные изменения (да и если не знаете), лучше сначала создать новую версию модуля и поштучно разрешить сайтам доступ к ней, протестировав их совместимость. Явным примером несовместимости может быть изменение структуры таблиц базы данных используемых модулем или же удаление/замена некоторых функциональных блоков модуля, что может повлечь за собой некорректное отображение дизайна сайта. Еще один пример версий – это версии для различных пользователей, например для обычных пользователей и привилегированных (таких как администратор, модератор и пр.). Если например, у меня есть описание того как удалять и редактировать записи таблиц модуля и эти описания относятся только к привилегированным пользователям, то к чему мне при обращении рядового пользователя к модулю подключать эти функции, тем самым делая дополнительную нагрузку на сервер и возможно понижая безопасность модуля и системы в целом. Между тем стоит отметить, что некоторые функции могут быть общими у версий модуля для рядовых и привилегированных пользователей. Такими функциями могут быть инициализация модуля, выборка некоторых данных из базы и т.п. Логично заключить, что набор общих функций может быть ядром модуля, а, следовательно, базовым классом. Реализации для рядовых и привилегированных пользователей можно оформить как наследование или же композицию. По вопросу наследование или композиция у меня нет однозначного мнения - нужно смотреть по ситуаци, но все же я склонен к композиции. Причем базовый класс создается как абстрактный, который подключает, во-первых, нужную версию, а во-вторых, все прочие необходимые модули и классы для работы текущего модуля, естественно это можно сделать и при наследовании, но не стоит забывать, что наследование это всегда более жесткий метод программирования, следовательно, более пригодный для конечно-спроектированных моделей.
Таким образом, я рекомендую при создании модуля размещение его в папку вида:
Обратим внимание на то, что в примере имеются папки с версиями 1.0 и 1.2, но нет 1.1. Данный пример подразумевает, что текущая - дефолтовая версия 1.1 и она размещается в корневой папке модуля. То есть данная версия протестирована для всех сайтов, работает корректно и включает в себя всю необходимую функциональность версии 1.0. Версия 1.0 сохранена как вариант для «отката» назад, версия 1.2 – это экспериментальный вариант или вариант не протестированный для всех сайтов. В текущий момент, на него могут быть направлены некоторые из сайтов, но очевидно - не все. Папки css, js, tpl и возможные прочие в данном примере «опущены».
Подключаемые версии желательно записывать в конфигурации, а модуль осуществляющий подключение модулей сайта, должен обратиться к конкретной версии модуля либо загрузить дефолтовую.
Собственно, наверное, все, что я хотел бы сказать про версии сейчас… я и без того слишком сильно отклонился к понятию cms, но Вы должны понимать, что это совершенно условное понятие, потому как поддержка версий должна осуществляться и в framework и cms в равной степени. Цель данной статьи указать на то, как было бы разумнее осуществлять размещение файлов и какова ценность поддержки множества версий в рамках системы. Поэтому при проектировании Вашей CMS очень рекомендую хорошенько проработать данный вопрос, что значительно упростит дальнейшую поддержку Вашей системы и сократит вероятность полной переделки системы.
Владимир Бредихин 2006/05/04 00:45
