Правила     Закладки     Карма    Календарь    Журналы    Помощь    Поиск    PDA    Чат   
        СМС-ки
   
Пейджер выключен!
 
Фильтр авторов:    показать 
  скрыть
  Ответ в темуСоздание новой темыСоздание опроса

> Модели.
twin  
 ۩  [x] Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Глухой нуб
******

Профиль
Группа: Администратор
Почтальон группы
Сообщений: 15559
Пользователь №: 6543
На форуме: 8 лет, 2 месяца
Карма: 299

Трезвый :
5 лет, 11 месяцев, 9 дней


Оглавление.

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


Глоссарий.
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
PMСайт пользователяICQ
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
twin  
 ۩  [x] Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Глухой нуб
******

Профиль
Группа: Администратор
Почтальон группы
Сообщений: 15559
Пользователь №: 6543
На форуме: 8 лет, 2 месяца
Карма: 299

Трезвый :
5 лет, 11 месяцев, 9 дней


Основная проблема DDD, а, как следствие и ООП, это то, что бизнес-процессы и программный код, это не просто разные вещи, но и находятся в совершенно разных плоскостях восприятия.

Я не зря поставил эпиграфом к этому разделу вызсказывание великого оружейного мастера. Он сумел создать такое оружие, которое на голову превосходило все остальные на то время. Этот автомат был простым как в изготовлении, так и в эксплуатации. Одновременно был сумашедше надежным и эфективным.

Совместить простоту, надежность и эфективность - вот это высший пилотаж. Такое под силу не каждому.

Я в свое время проводил индивидуальное обучение программированию. Знаю, что sergeiss этим балуется иногда, обсуждали. Так вот, мы сошлись во мнении, что самое сложное в этом не объяснить технологии, а научить человека мыслить линейно. Многим это вообще не дано от природы.

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

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

К чему я это всё. А к тому, что ООП призвано упростить жизнь обывателя, каким то образом попавшего в программирование.

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

- Этот класс накладывает одну картинку на другую. Сам. Сверху. А как он это делает - не важно и не интересно.

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

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

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

Цитата
Объектно-ориентрованное программирование — это исключительно плохая идея, которую могли придумать только в Калифорнии.
(с) Эдсгер Дейкстра


Цитата
Си позволяет легко выстрелить себе в ногу; с C++ это сделать сложнее, но, когда вы это делаете, вы отстреливаете себе ногу целиком.
(с) Бьерн Страуструп


Цитата
Если бы у Java был настоящий сборщик мусора, большинство программ удаляли бы себя во время исполнения.
(с) Роберт Сьюэл


Цитата
ООП предоставляет вам множество способов замедлить работу ваших программ
(с) Патрик Киллелиа


Цитата
Коронная фраза, которую я ненавижу: “Объектов недостаточно. Нужно еще...”. Все эти годы нам нужны были фреймворки, компоненты, аспекты, сервисы (которые, похоже, любопытным образом вернули нас к процедурному программированию!)
(с) Oscar Nierstrasz


А что уж говорить про веб.

Но все это опять же лирическое отступление, дабы было понятно, почему я строю схему моделей именно так. Почему для этой схемы семантическая модель первичнее доменной. А именно потому, что отсутствует так называемый посредник между доменом и кодом.

Я плохо знаю английский. Это моя беда. И проблема именно в том, что я не могу отучиться переводить слова. Чтобы хорошо знать язык, нужно научиться на нем думать. Иначе ты становишься сам себе переводчик, и этот ненужный посредник тормозит все дело.

Слава Богу, в программировании этого недостатка у меня нет. И когда мы говорим с заказчиком на ubiquitous language, я не проецирую бизнесс-логику в сущности. А сразу думаю алгоритмами. А основа и стартовая точка любого алгоритма в веб - данные. Не важно откуда они берутся, из СУБД, из HTTP иди даже из самого скрипта.

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

Присоединённое изображение
Присоединённое изображение


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

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

Зачем ворошить старое, когда можно наворотить новое?

user posted image
PMСайт пользователяICQ
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
twin  
 ۩  Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Глухой нуб
******

Профиль
Группа: Администратор
Почтальон группы
Сообщений: 15559
Пользователь №: 6543
На форуме: 8 лет, 2 месяца
Карма: 299

Трезвый :
5 лет, 11 месяцев, 9 дней


Я специально не стал рисовать в первой схеме библиотеки, это еще больше усложнит и запутает дело.

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

Если представить себе несколько страниц, то сложность взаимодействий моделей между собой в первом случае будет гораздо большей. Я даже не возьмусь рисовать картинку. smile.gif Тут разумеется не обойтись без предварительного проектирования.

По второй схеме всё гораздо проще. Так как это фактически отдельная программа. Просто нужно нарисовать другую картинку, автономную, но которая использует те же библиотеки и те же модели (скорее сервисы), если потребуются. Это просто, так как они почти не взаимодействуют между собой. Почему "почти", а потому что это мультипарадигма. Здесь не запрещено ничего. И исключения только подтверждают правила.

В такой схеме первичны данные, вот это и нужно изначально систематизировать и проектировать, в разрез принципам DDD.

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

Однако профит от этого очевиден. Приложение получается проще, надежнее и эфективнее. Так же как ППШ в отличие от немецкого МП-40 (в миру "шмайсер") smile.gif При этом никуда не девается гибкость и расширяемость.

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

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


А теперь непосредственно к коду.


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

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

Зачем ворошить старое, когда можно наворотить новое?

user posted image
PMСайт пользователяICQ
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
  Быстрый ответ
Информация о Госте
Введите Ваше имя
Кнопки кодов
Для вставки цитаты, выделите нужный текст и
НАЖМИТЕ СЮДА
Введите сообщение
Смайлики
:huh:  :o  ;) 
:P  :D  :lol: 
B)  :rolleyes:  <_< 
:)  :angry:  :( 
:unsure:  :blink:  :ph34r: 
     
Показать всё

Опции сообщения  Включить смайлики?
 Включить подпись?
 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:

Опции темы Ответ в темуСоздание новой темыСоздание опроса