[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Модели.
twin
Оглавление.

Сделать сложно - очень просто. Сделать просто - очень сложно.
© Г.С. Шпагин, создатель ППШ


Глоссарий.
1. Модели - активные скрипты приложения, выраженная кодом бизнесс-логика.
2. Домен - здесь: предметная область.
3. Доменная модель - организованная и структурированная предметная область.
4. Семантическая модель - структура связанных таблиц СУБД
5. Сущность - конкретно выраженный объект, описывающий какую то часть модели. (Собака)
6. Абстракция - объект, или несколько взаимосвязанных объектов, не имеющих конкретных свойств, но описывающий какую то группу однотипных сущностей. (Животные)
7. DDD (Domain-driven design) - способ пректирования структуры приложения в неизвестной предметной области
8. Предметная область - то, чего хочет заказчик, но не никак может объяснить. smile.gif
9. UML (Unified Modeling Language) - Унифицированный язык моделирования бизнесс-процессов и структуры приложений в виде графического описания объектов.
10. Ubiquitous language - вездесущий язык. Язык, понятный заказчику и исполнителю. Основа DDD.


Все, что написано раньше - прелюдия.
А вот сейчас самая главная тема, из-за чего весь сырбор. Модели. В чем принципиальное различие между построением приложения по схеме классического объектного проектирования, и по схеме сборки библиотек и сервисов.

Буду писать долго, в нескольких частях, несколько дней, в свободное время. Пожалуйста, пока не перебивайте. Если хотите, откройте новую тему, я их свяжу.

Сначала нужно разобраться, как устроены программы на академическом ООП. Я уже писал в разделе про DDD, что они проектируются и строятся, как единое, цельное здание. Пошло это из прикладной сферы программирования. Просто многие разработчики упорно не видят разницы между десктопными и веб приложениями. Все от того, что по по первому написана куча книг, а по второму практически ничего нет. А если и есть, то эти материалы - просто попытка перетащить принципы из одной в другую.

Сначала пример из прикладной сферы. Главный принцип ООП - все является объектами. Объекты общаются друг с другом, посылая сообщения.

Вот допустим мы разрабатываем игру. World of Tanks smile.gif И нам нужен танк. Он состоит из разных частей, которые:
1. Могут производить действия
2. Могут быть заменяемы
3. Могут изменять состояние.

Допустим мы определили, что должна быть система управления, башня и пушка. Корпус и ходовую часть опустим для простоты.

Можно описать это объектами. UML рисовать не буду, у редактора вышел срок бесплатного использования, а платить я не собираюсь, ибо не юзаю все равно. На словах.

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

Но есть же еще абгрейд. Второй пункт - пушка должна быть заменяема. И тут композиция уже не подходит. Тут сложнее, тут нужна более тонкая связь - зависимость. Потому что где то должен быть склад (или магазин) пушек. Мы должны выбрать нужную и прикрутить к башне. А старую выкинуть к примеру. Значит объект "башня" должен не просто содержать объект "конкретная пушка", а уметь принимать от объекта "магазин пушек" любую другую. А значит они должны быть унифицированы. Тут уже нужен какой то пооаждающий паттерн. Допустим фабрика.

Делать она должна однотипные объекты. А чтобы это было так, нужно писать однотипные классы. Для этого есть следящие механизмы - контракты к примеру. Или абстрактные классы. Это всё понятно и знакомо. ООП в веб пргораммировании работает похожим образом.

А вот тут самое интересное и главное отличие. Третий пункт. Если вражина попал своим снарядом в пушку, то она должна изменить свое состояние на "сломана". И хранить это состояние, пока мы её не заменим, купив в магазине. Потребуются деньги. А для этого мы должны оттранспортировать танк в ангар, а сами пойти их заработать, забыв про него на время. Но танк должен оставаться таким, каким мы его оставили - сломанным.

Организовать все это в одну кучу без проекта достаточно трудно. Я писал в первой теме про "несчастных прикладников".

Нужно тщательно определить доменные объекты и связи между ними. Иначе можно что-то упустить, и пушка не подойдет к башне или мы сделаем фабрику пушек, а механизм абгрейда не предусмотрим. И будем облизываться на красивую орудию, не имея возможности поставить её на свой любимый танчик.

Вот так же примерно проектируются веб-приложения "тру программистами". Вот эти же принципы почему то спроецированы на них. Это объявлено "новейшими технологиями" и "бэст-практикс". И понятно почему. Веб намного моложе прикладного программирования. Да и самого ООП моложе. И потянулись эти принципы вместе с программистами, перешедшими из одной сферы в другую. Так как иначе они делать и не умели.

Однако, как говорят в Одессе, это две большие разницы. Веб и прикладные софты.

В десктопных приложениях это более чем оправдано. Всё это потому, что в прикладной сфере объекты живут долго. Пока враг не поломал пушку, она будет стрелять. А сломанной она будет оставаться, пока не заменим или не починим. Даже если мы занимаемся другими делами. Зарабатываем деньги или грабим корованы.

Более того, этот объект с текущим состоянием можно сохранить. Допустим засейвиться. (Давно не играл в игры, может сейчас по другому говорят smile.gif ). Или отложить игру на потом, сохранив состояние объектов. Потом запустить снова и продолжить с того места, где вчера остановился.

И главное - эти объекты нужны на протяжении всей игры и потребоваться могут в любой момент. А значит они висят в оперативке вместе со своим состоянием, пока работает программа.

А что же в веб? А в веб совершенно не нужно долго хранить состояния объектов. Они нужны только для формирования отклика. То есть конкретной страницы.

Нам совсем не обязательно организовывать такие запутанные связи между объектами. Потому что при генерации каждой страницы мы всегда инициируем их чистыми, пустыми. Без состояния. Можно конечно их сериализовать и сохранить в той же базе, но это нужно достаточно редко. Потому что гораздо проще хранить данные. Все равно объект будет создан заново. Не важно, создаем мы его уже заполненным или он запросит данные в момент создания.

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

Вот это основное различие почему-то в упор не видят адепты классического ООП в веб приложениях. В них первична модель отдельной страницы, а не доменная модель. Именно она должна формировать данные для отклика. А с подготовкой этих данных вполне справляются библиотеки и хэлперы. В веб-приложениях объекты вовсе не обязательно должны быть связаны между собой так сильно. Да и сами объекты тут совсем не обязательны по большому счету. Достаточно выстроить правильную систему управления. И здесь более уместна ассоциация с котеджным поселком, чем с монолитным небоскребом.

В веб-проектах (в подавляющем большинстве) связи организованы на уровне данных. Если сравнивать с танками, то получится так.

1. Запрос (HTTP) на формирование страницы системы управления -> генерация страницы -> отклик -> остановка программы.
2. Запрос (HTTP) на состояние танка -> запросы в СУБД на получение данных -> создание текущего состояния -> отклик -> остановка программы
3. Запрос (HTTP) на поворот башни -> запросы в СУБД на изменение данных -> создание текщего состояния танка -> отклик -> остановка программы.

На каждое действие - запуск программы с чистого листа. И неминуемая остановка. А взаимосвязи только через СУБД. Вот там эти связи очень важны, ибо на них всё зиждется. А на уровне PHP даже сущности не всегда нужны. Можно обойтись просто командами.

Некоторые программисты вообще максимум логики переносят в СУБД. Организуя хранимые процедуры, триггеры и так далее. Остается только запросить и получить то, что нужно для отклика.

Организовывать поверх уже связанных данных в СУБД огромный слой абстракции в виде взаимосвязанных объектов, на мой взгляд, не просто лишне и расточительно по ресурсам. Но и достаточно сильно усложняет разработку. Смешнее всего для меня, это использование Active Record. Этот паттерн придуман как раз для представления данных в виде объектов. А в веб это получается змея, кусающая себя за хвост.

Вот потому я и говорил - не нужно тратить время на предварительное проектирование проекта на уровне взаимодействия объектов. Из DDD в веб полезен только ubiquitous language. Общий язык между заказчиком и программистом. То, что нужно сначала проектировать доменую модель, а потом базу, не всегда оправдано. Только когда веб-приложение разрабатывается по принципам десктопного. Что само по себе нонсенс, хотя он возведен в ранг "бэст-практикс". По сути доменную модель целиком проектировать вообще не нужно. Можно проектировать отдельные страницы, хэлперы и библиотеки. Ну и эволюционное проектирование тут как нельзя кстати.

Резюмируя: организовывать связи между объектами достаточно полезно в десктопных приложениях. В веб это не обязательно, если не сказать - вредно.

Как обойтись без этого, построив гибкое и расширяемое приложение, а главное - простое в разработке даже большой командой, я покажу дальше.

_____________
Если вам недостаточно собственных заблуждений, можно расширить их мнениями экспертов.

Нужно уважать мнение оппонета. Ведь заблуждаться - его святое право.

Настаивал, настаиваю и буду настаивать на своем. На кедровых орешках.

user posted image
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.