Структура приложений

 
 
 
Сообщения:9474
Сразу предупреждаю, что приложения бывают разные, разные уровни у них могут быть, поэтому не вбивайте такую архитектуру себе в голову как догму.
Как правило простые (и не очень) приложения могут быть разбиты на следующие модули (уровни):
  • Доменная модель - сущности вашей системы, например, если вы разрабатываете "магазин", то ваша доменная модель - это Магазин, Продукт, Покупатель, Пользователь и т.д.
  • Уровень DAO - в этом уровне реализован доступ к БД или любому другому источнику данных. В классах DAO, например, могут быть такие методы как getUserByUsername(), deleteUser(), etc. Замечу, что на этом уровне нет транзакций, т.к. транзакции как правило принимают участие в бизнес операциях, на этом же уровне ни о какой логике приложения идти речи не может.
    Классы этого уровня можно помещать в модуль model, самый нижний модуль, который не зависит от других.
  • Уровень Сервисов - на этом уровне реализована бизнес логика приложения, управление транзакциями и пр. Пусть не смущает то, что Сервис может повторять методы DAO, эти методы не просто повторяют, они еще и оборачивают в транзакции методы DAO.
    В уровень Сервисов может сеттиться несколько DAO для того, чтоб удовлетворить выполнение какой-либо бизнес операции.
    Классы этого уровня можно помещать в модуль с именем controller. Этот модуль зависит от модуля model.
  • Уровень обработки Вида. Если это веб приложение, здесь будут находиться Сервлеты, Контроллеры (Spring MVC), Действия (Struts), как бы там ни было здесь осуществляется обработка запроса и генерация ответа. Однако бизнес логика приложения на этом уровне не присутствует, она делегируется уровню Сервисов. В идеале, если у нас был веб интерфейс, но мы возжелали доступ к нашему приложению еще и по средствам веб сервисов, тогда мы только добавим еще одну реализацию данного уровня и никакого дублирования кода у нас не будет, ибо уровень Сервисов останется тот же.
    Классы этого уровня можно помещать в модули по типу view-controller-springmvc, vew-controller-ws. Как правило этот модуль зависит от уровней model и controller.
  • Вид. Ну это обычный уровень работы с интерфейсом, здесь могут быть размещены, к примеру, JSP страницы.
    Этот модуль можно назвать view, зависеть он будет от модуля view-controller, иногда и от model, если он может работать с объектами доменной модели (в идеале он должен работать только с DTO, которые находятся в view-controller).


Здесь есть пример: JT Webinar: Разработка Web-приложения в среде IntelliJ IDEA.
Правда он маленький.
Изменен:17 мар 2011 19:49
 
 
Сообщения:9474
Продолжим тему. Выше приведен пример слоев приложения, где бизнес логика приложения вынесена в уровень служб. Этот подход будет работать, однако в крупных и сложных проектах у него есть большой недостаток - с течением времени логика будет усложняться и уровень служб будет состоять просто из больших методов, каждый из которых выполняет какую-то бизнес операцию. Во что это выльется:
  • Уровень служб будет переполнен логикой, со временем это превратится в одни костыли и систему уже будет практически не возможно расширять.
  • Дублирование кода, т.к. многие методы будут выполнять некоторые одинаковые операции постоянно
  • Сложночитаемость и сложнопонимаемость, ибо вся наша логика будет заключаться в больших методах
  • Процедурный подход к программированию - это трудно заметить, однако да, это будет около-процедурное программирование
Почему же тогда такое расслоение описано выше? Ну во-первых, я тогда еще много чего не понимал =) Во-вторых, такое разбиение на слои очень популярно - заметьте, что все вокруг говорят "в классах доменной модели не должно быть логики, не-долж-но!". Это так называемая анемичная доменная модель. Почему так получилось? Мое предположение, навеянное неким Chris Richardson, что эта мода пошла от EJB, т.к. в EJB 2 этот подход был всегда используем (не знаю насчет EJB 3), возможно Sun в те годы развернуло PR-компанию по тому, как должны строиться приложения. Но не будем философствовать, точно я все одно не знаю. Итак, каковы же аналоги?
Есть один J2EE шаблон проектирования, так называемый Domain Model, впервые описанный Мартином Фаулером (Martin Fowler). Говорит он о том, что бизнес логика должна лежать в классах доменной модели. Это не значит, что она должна лежать прям в ваших сущностях, которые вы сохраняете в БД, доменная модель - это нечто большее, это собственно проекция предметной области на классы, таким образом если мы говорим про какую-нибудь аэро-службу, которая может бронировать билет, то конкретно для такой задачи можно создать какой-нибудь FlightBooker, который будет именно этим и занят, и при этом вполне можно так себе давать ему доступ к DAO, например, вот так:
public class FlightBooker {
  void book(BookInfo bookInfo, FlightDao flightDao) {...}
}
Это не значит, что мы просто вырезаем наш уровень служб, он так и остается жить, просто теперь вместо того, чтоб выполнять логику приложения, он будет дергать методы других классов - это и есть обязанности Фасада (уровень служб также называют Service Facade). Причем он по-прежнему будет управлять транзакциями.
А также, не бойтесь помещать логику в сущности вашей системы, если эта логика относится к этой сущности, то почему бы и нет? Ведь, классы - это данные+поведение. Главное - знайте меру ;)
Это вроде бы все, что я хотел рассказать сегодня.
Рекомендуемая литература:
- Patterns of Enterprise Application Architecture
- POJOs in Action: Developing Enterprise Applications with Lightweight Frameworks
 
 
Сообщения:2399
ИМХО FlightBooker и есть типичный представитель уровня сервисов (ты правильно выше написал, что уровень сервисов содержит бизнес-логику).
А все описанные проблемы с переусложнением, дублированием, сложночитаемостью и процедурному стилю - это проблема авторов системы и присуща не только J2EE, но и любому приложению, где не прилагаются своевременные усилия по рефакторингу.
EJB2.x отлично подходят для организации сервис-фасадов. Это довольно популярная практика - предоставлять доступ к сервисам системы через SLSB-фасад.

 
 
Сообщения:37
Может быть сказывается мой опыт работы разработчиком БД, но почему не рассматривается вариант занесения бизнес-логики в саму БД?
В этом случае все сложные вычисления ложатся на оптимизированное ядро СУБД. Да и надежность транзакций повышается значительно.
 
 
Сообщения:160
Староверъ:
Выше приведен пример слоев приложения, где бизнес логика приложения вынесена в уровень служб.


Вы говорите о "слоях" одного приложения. Каждая служба отвечает за одну бизнес-операцию. Это хорошо. Можно ли эту бизнес-операцию вынести в отдельный сервис, т.е. в отдельное приложение? Чтобы была "распределенная технология", как заявлено в названии этого форума.
 
 
Сообщения:1517
это уже будет SOA
 
 
Сообщения:160
wedens:
это уже будет SOA


Ну, хорошо. И что? Это что-то принципиально другое?
 
 
Сообщения:9474
Quote:
Вы говорите о "слоях" одного приложения. Каждая служба отвечает за одну бизнес-операцию. Это хорошо. Можно ли эту бизнес-операцию вынести в отдельный сервис, т.е. в отдельное приложение? Чтобы была "распределенная технология", как заявлено в названии этого форума.
Quote:
Ну, хорошо. И что? Это что-то принципиально другое?
Вот, сам же отвечаешь на свой вопрос :) Даже если узлы приложения находятся на разных машинах, у приложений все равно соблюдается приблизительно одна и та же слоенность.
Quote:
ИМХО FlightBooker и есть типичный представитель уровня сервисов (ты правильно выше написал, что уровень сервисов содержит бизнес-логику).
Нет, уровень служб есть уровень служб, на этом уровне может быть много логики, но она не должна быть доменной.
Quote:
Может быть сказывается мой опыт работы разработчиком БД, но почему не рассматривается вариант занесения бизнес-логики в саму БД?
В этом случае все сложные вычисления ложатся на оптимизированное ядро СУБД. Да и надежность транзакций повышается значительно.
Ну.. логику в БД очень редко кладут, это не то место, где ее удобно хранить, тут единственный плюс - можно менять логику без перезапуска приложения. Да и транзакции-то бывают распределенными на несколько разных ресурсов, не только БД.

Похоже, что много вопросов возникает, как будет время, расширю статью эдак в пару раз, с примерами :)
 
 
Сообщения:160
Quote:
Даже если узлы приложения находятся на разных машинах, у приложений все равно соблюдается приблизительно одна и та же слоенность.


Даже если узел - маленькое приложение, реализующее 1 логику?

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

И "в крупных и сложных проектах у него есть большой недостаток". Вот мне и интересно, почему так популярны "крупные и сложные", почему не "много мелких и простых", как предлагается в SOA.
 
 
Сообщения:9474
Все в конечном итоге зависит от конкретного случая. Если такая архитектура покажется слишком сложной и отягощающей, почему бы не сделать так, как будет удобней и проще?
Но. Какова бы не была "1 маленькая логика", если мы говорим про доменную логику, она должна быть реализована следуя шаблону Доменная Модель. Иначе эту "маленькую логику" нельзя будет никак переиспользовать. Хотя и это бывает лишним, так что опять же - it depends.
Quote:
Вот мне и интересно, почему так популярны "крупные и сложные", почему не "много мелких и простых", как предлагается в SOA.
Потому что
а) моей задачей было описать популярную структуру приложений, описание нужд каждого отдельно взятого проекта может занять долгое время ;)
б) всему свое место, SOA - это хорошо, но не всегда приемлемо, да и не регламентирует SOA количество и размер приложений - это может быть 5 крупных приложений, которые общаются по средствам каких-нибудь стандартных протоколов, и это тоже может быть SOA.
Хотя, я наверное зря поставил ударение на крупные и сложные приложения, в принципе недостаток у подхода смешивания служебной и доменной логики будет проявляться везде, просто в "крупных и сложных" это может вылиться в большие проблемы.
 
 
Сообщения:2399
urslan:
Может быть сказывается мой опыт работы разработчиком БД, но почему не рассматривается вариант занесения бизнес-логики в саму БД?

1) логика в БД сложно поддается юнит-тестированию
2) приводит к привязке к вендору
3) ее очень сложно поддерживать
4) очень дорого масштабировать (особенно если мы говорим об Oracle)
Тем не менее, некоторые части все же надо делать в БД.
urslan:
В этом случае все сложные вычисления ложатся на оптимизированное ядро СУБД. Да и надежность транзакций повышается значительно.

- Надежность транзакций идеально контроллируется JTA. К тому же транзакции нужны не только на уровне чтения/записи данных, но и на транспортном уровне.
- оптимизированное ядро СУБД не оптимизировано для проведения вычислений. Гриды (Hadoop, Data Synapse) с этой задачей справляются намного лучше. Инструменты нужно использовать для того, для чего они предназначены.

 
 
Сообщения:786
Я тоже начитавшись Фаулера, после того как перешел с PHP на Java, был глубоко шокирован тем, что большинство джавистов не понимают, что они только думают, что пишут в ООП парадигме, а на деле их код, реализующий анемичную модель является чисто процедурным.

Уверен, что это относится не ко всем и существуют и нормально спроектированные проекты с применением Domain Model и Domain Driven Design.

С удовольствием устроюсь на работу в такой проект :)
 
 
Сообщения:2361
Quote:
Я тоже начитавшись Фаулера, после того как перешел с PHP на Java, был глубоко шокирован тем, что большинство джавистов не понимают, что они только думают, что пишут в ООП парадигме

Да всё Мы понимаем, однако кушать то же хочеться, а за хореаграфию почему-то никто не доплачивает, а платят за фичи. И когда задача сводиться к тому что у Маши было четыре яблока она продала два яблока Пети и нужно посчитать прибыль с учетом затрат на хранение яблок в холодильнике и налога с продаж то Data Driven Design с анемичной моделью это серебрянная пуля, так как с учетом развитости java фреймворков позволяет лабать код быстро и добавлять такие фичи тоннами оперируя стандартными паттеренами сущность/ДАО/сервис/MVC не особо напрягая свой мозг. И будьте уверены что ваше ООП честолюбие найдет где себя проявить и при таком топорном подходе, ибо модель еще нужно отобразить, а шаблоны корпаративных приложений скушны и банальны, то ли дело когда дойдет до отображение модели вот там действительно придется включать мозг когда потребуется чуть-чуть больше чем CRUD.
Изменен:31 май 2011 22:29
 
 
Сообщения:2361
Староверъ:
Продолжим тему. Выше приведен пример слоев приложения, где бизнес логика приложения вынесена в уровень служб. Этот подход будет работать, однако в крупных и сложных проектах у него есть большой недостаток - с течением времени логика будет усложняться и уровень служб будет состоять просто из больших методов, каждый из которых выполняет какую-то бизнес операцию.

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

Староверъ:

    [*]Уровень служб будет переполнен логикой, со временем это превратится в одни костыли и систему уже будет практически не возможно расширять. [/quote] Это не аргумент. Точно так же можно сказать что, угодно например уровень XXX будет переполнен логикой, со временем это превратится в одни костыли и систему уже будет практически не возможно расширять, так как сам по себе код никуда не денется перекочует в тот же уровень XXX. [quote="Староверъ"] [/*][*]Дублирование кода, т.к. многие методы будут выполнять некоторые одинаковые операции постоянно [/quote] От дублирования спасает рефакторинг. [quote="Староверъ"] [/*][*]Сложночитаемость и сложнопонимаемость, ибо вся наша логика будет заключаться в больших методах [/quote] Скажу как активно практикующий Data Driven Design, что это абсолютно не так, никаких больших методов в сервисах не существует(у меня), ибо когда приступаешь к новой задаче в имеющем солидную историю постоянно подвергающемуся качественному рефакторингу проекте большая часть функционала уже реализована другими сервисами, и нет причин не пользоваться им повторно. [quote="Староверъ"] [/*]
  • Процедурный подход к программированию - это трудно заметить, однако да, это будет около-процедурное
    программирование
Почему же тогда такое расслоение описано выше? Ну во-первых, я тогда еще много чего не понимал =) Во-вторых, такое разбиение на слои очень популярно - заметьте, что все вокруг говорят "в классах доменной модели не должно быть логики, не-долж-но!". Это так называемая анемичная доменная модель. Почему так получилось? Мое предположение, навеянное неким Chris Richardson, что эта мода пошла от EJB, т.к. в EJB 2 этот подход был всегда используем (не знаю насчет EJB 3), возможно Sun в те годы развернуло PR-компанию по тому, как должны строиться приложения. Но не будем философствовать, точно я все одно не знаю. Итак, каковы же аналоги?

Я бы просто занялся философией. Ты негодуешь относительно того, что мы не признаем факта что булка хлеба может сама себя испечь, погрузить в грузовик, выгрузить на прилавок, продать или еще хуже того сама себя съесть, да я против подхода наделить груду муки поведением, всегда есть те кто осуществляет действия(СЕРВИСЫ) и что-то над чем осуществляют действия(СУЩНОСТИ или ОБЪЕКТЫ-ЗНАЧЕНИЯ). Если ты против анемичной булки то ты автоматом против того, кто хочет съесть не порезав ножом а просто поломав руками(или другим не предусмотренным в булке способом, и не варвары это вовсе может у них просто ножа нет), а всевозможные способы поедания хлеба в саму булку ты никогда не заложишь.
 
 
Сообщения:944
Vermut:

Староверъ:

[*]Процедурный подход к программированию - это трудно заметить, однако да, это будет около-процедурное
программирование[/list]Почему же тогда такое расслоение описано выше? Ну во-первых, я тогда еще много чего не понимал =) Во-вторых, такое разбиение на слои очень популярно - заметьте, что все вокруг говорят "в классах доменной модели не должно быть логики, не-долж-но!". Это так называемая анемичная доменная модель. Почему так получилось? Мое предположение, навеянное неким Chris Richardson, что эта мода пошла от EJB, т.к. в EJB 2 этот подход был всегда используем (не знаю насчет EJB 3), возможно Sun в те годы развернуло PR-компанию по тому, как должны строиться приложения. Но не будем философствовать, точно я все одно не знаю. Итак, каковы же аналоги?

Я бы просто занялся философией. Ты негодуешь относительно того, что мы не признаем факта что булка хлеба может сама себя испечь, погрузить в грузовик, выгрузить на прилавок, продать или еще хуже того сама себя съесть, да я против подхода наделить груду муки поведением, всегда есть те кто осуществляет действия(СЕРВИСЫ) и что-то над чем осуществляют действия(СУЩНОСТИ или ОБЪЕКТЫ-ЗНАЧЕНИЯ). Если ты против анемичной булки то ты автоматом против того, кто хочет съесть не порезав ножом а просто поломав руками(или другим не предусмотренным в булке способом, и не варвары это вовсе может у них просто ножа нет), а всевозможные способы поедания хлеба в саму булку ты никогда не заложишь.


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

http://rent4.me - аренда недвижимости без посредников
 
Модераторы:wedens
Сейчас эту тему просматривают:Нет