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

 
 
 
Сообщения:128
Vermut:
Честно говоря .NET и архитектуру обсуждать вообще не хочеца, если у самого главного босса семь пятниц на недели, и каждые полгода смена приоритетов, то что там вытворяют open-source сообщества которые вообще ни чем не ограничены, так как .NET стандартов не предусматривает, то даже страшно предстваить архитектурную выкханалию творящуюся в мире .NET.


Именно по этому, больше и не занимаюсь дотнетом, а вплотную занялся жабой.

:arrow: Вообще вопрос был по архитектуре/структуре проектов на жабе.
 
 
Сообщения:2436
Всю ынтерпрайз архитектуру ёмко и точно уже описал Фаулер: Представление->Бизнес-логика->Инфраструктура. А уже реализация каждого отдельного слоя зависит от тонкостей проекта. Та картинка которую ты привел, вполне подходит под стандартный веб проект имеющий пользовательский интерфейс, сосбственно это то что Старовер описал в первом посте этой темы.
 
 
Сообщения:50
Не ругайте громко, что влез в тему(топик) с немного несоответсвующим вопросом :wink:. Я почти ничего не знаю о слоях и архитектуре приложений, но захотелось разобраться в этих вопросах (желательно прочитав пару-тройку статей или гайд, т.к. пока что хочется уделить больше времени изучению фреймоворков).
Посоветуйте please "ок" статьи. В теме упоминалась книга Фаулера. Это ли она "Архитектура корпоративных программных приложений" ?
 
 
Сообщения:390
Староверъ:
Продолжим тему. Выше приведен пример слоев приложения, где бизнес логика приложения вынесена в уровень служб. Этот подход будет работать, однако в крупных и сложных проектах у него есть большой недостаток - с течением времени логика будет усложняться и уровень служб будет состоять просто из больших методов, каждый из которых выполняет какую-то бизнес операцию. Во что это выльется:
  • Уровень служб будет переполнен логикой, со временем это превратится в одни костыли и систему уже будет практически не возможно расширять.
  • Дублирование кода, т.к. многие методы будут выполнять некоторые одинаковые операции постоянно
  • Сложночитаемость и сложнопонимаемость, ибо вся наша логика будет заключаться в больших методах
  • Процедурный подход к программированию - это трудно заметить, однако да, это будет около-процедурное программирование


Шаблон Method Object элементарно решает озвученные проблемы, любой метод сервиса который по нашему мнению стал слишком большим мы можем вынести в отдельный класс:
public class FlyService {

    private FlightDao flightDao;

    void book(BookInfo bookInfo) {
        BookTransaction transaction = new BookTransaction(flightDao);
        transaction.book(bookInfo);
    }
   
}


Староверъ:

Есть один J2EE шаблон проектирования, так называемый Domain Model, впервые описанный Мартином Фаулером (Martin Fowler). Говорит он о том, что бизнес логика должна лежать в классах доменной модели.

Фаулер стар и уже сам не понимает что говорит и пишет. Он написал один бестселлер это "Рефакторинг", остальные труды достаточно посредственны. Фаулер не является авторитетом в Domain Driven Design, Эрик Эванс куда более компетентен в этой области, в своей книге Domain Driven Design он как раз пишет что предметная область выражается через:
1. Сущности - Объекты из предметной области обладающие уникальности существования.
2. Объекты значения - То же объекты из предметной области но не обладающие уникальностью существования, например нам не нужно отличать 5 долларов от других пяти долларов.
3. Сервисы/службы: реализуют операции которые не принадлежат какому-то конкретному объекту и их нецелесообразно помещать в какую-нибудь сущность.

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

Староверъ:

Это не значит, что она должна лежать прям в ваших сущностях, которые вы сохраняете в БД, доменная модель - это нечто большее, это собственно проекция предметной области на классы, таким образом если мы говорим про какую-нибудь аэро-службу, которая может бронировать билет, то конкретно для такой задачи можно создать какой-нибудь FlightBooker, который будет именно этим и занят, и при этом вполне можно так себе давать ему доступ к DAO, например, вот так:
public class FlightBooker {
  void book(BookInfo bookInfo, FlightDao flightDao) {...}
}
Это не значит, что мы просто вырезаем наш уровень служб, он так и остается жить, просто теперь вместо того, чтоб выполнять логику приложения, он будет дергать методы других классов - это и есть обязанности Фасада (уровень служб также называют Service Facade). Причем он по-прежнему будет управлять транзакциями.
А также, не бойтесь помещать логику в сущности вашей системы, если эта логика относится к этой сущности, то почему бы и нет? Ведь, классы - это данные+поведение.

Ты здесь занимаешься гаданием по Фаулеру, ничего такого ни он ни Эванс не писал. Может быть предлагаемый тобой подход работоспособен но к DDD он никакого отношения не имеет.
 
 
Сообщения:128
Здесь была ссылка на пиратскую книгу. А теперь ее нет :Р
Администрация.
 
 
Сообщения:53
Тоже не понял, чем FlightBooker Старовера отличается от Сервиса? Да, он выполняет операции в рамках модели, но по-существу это отделение бизнес логики от сущности модели.
Или из-за того, что этот класс будет расположен в пакете модели - это уже не сервис?

Где можно посмотреть пример реализации сущностей модели и бизнес логики по DDD?
А то действительно, у фаулера какое-то противоречивое изложение данной информации.
 
 
Сообщения:2436
Litle:
Тоже не понял, чем FlightBooker Старовера отличается от Сервиса? Да, он выполняет операции в рамках модели, но по-существу это отделение бизнес логики от сущности модели.

От сервиса отличается тем что имеет состояние связанное с бизнесс операцией, в то время как сервисы же всегда stateless. Я тоже иногда создаю классы аналогичные FlightBooker, если по ходу реализации бизнесс операции выясняется что кода в сервисе нужно написать слишком много. Только я такие классы помещаю в пакет вместе с сервисами, или в подпакет пакета с сервисами, и я согласен с sgdread, что это не открытие америки и FlightBooker это всего лишь вспомогательная часть сервисного слоя, но не в коем случае не самодостаточный архитектурный слой.

Litle:
Или из-за того, что этот класс будет расположен в пакете модели - это уже не сервис?

Это уже в любом случае не сервис, так как FlightBooker не является stateless. Что касается помещения такого класса в модель то это является стратегической ошибкой, потому как размещение таких классов в модели будет как магнит стягивать в модель всё больше и больше классов(я далее опишу почему на примере того же FlightDao), пока у тебя полпроекта в модели не окажется и в конце концов не прийдём к тому что модель перестанет быть моделью, по ней ничего нельзя будет сказать о предметной областью, потому что пакеты с моделью будут перегруженны костылями абстрагирующими модель от других частей приложения. Закончится это в конечном итоге всё рано или поздно очень плачевно и даже костыль в виде шаблона detached interface(помещение интерфейса в один пакет а реализация в другом) не поможет избежать циклических зависимостей между пакетами.
Объясняю: хоть по коду Старовера это и не видно, но он уже подразумевает применение detached interface. Если он и интерфейс и реализацию FlightDao поместит в пакет dao, то перед ним встанет проблема цикла между пакетами: ДАО выполняет персистентные операции над моделью то есть зависит от модели, а модель в лице FlightBooker в свою очередь будет дергать методы FlightDao, то есть зависить от ДАО. Чтобы решить такую вод задачку Старовер предпочтет будет вынужден вынести интерфейс FlightDao в модель, а реализацию в оставить в пакете dao, этим он уйдёт от циклов в исходном коде, но никуда не уйдёт от циклов между архитектурными слоями в рантайме. И костыль с detached interface Вы будете вынуждены повторять из раза в раз, когда по ходу выполнения бизнесс операции нужно что-то сохранить в базу, проверить права доступа, отправить по JMS или вам просто банально понадобится выполняя одну оперцию дернуть реализацию другой уже готовой бизнесс операции.

Litle:
Где можно посмотреть пример реализации сущностей модели и бизнес логики по DDD?

Лучше Вам этого не видеть и я Вам это говорю на полном серьёзе. Можно почитать код распространяемый вместе с книжками по DDD:
  • Применение DDD и шаблонов проектирования: проблемно-ориентированное проектирование приложений с примерами на C# и .NET. Джимми Нильссон.
  • Предметно-ориентированное проектирование (DDD). Структуризация сложных программных систем. Эрик Эванс.

Чтобы скачать и посмотреть код, сами книжки покупать не нужно. А после просмотра исходного кода, Вам эти книжки покупать не захочется. Причем заметьте у авторов книг есть куча времени, на то чтобы написать код красиво, а требования у них всегда вымышленные и они в любой момент могут подогнать неудобные требования под свои нужды. И при всё при этом код к этим книгам представляет антирекламу DDD. Если модифицировать подход Старовера и помещать классы анологичные FlightBooker в сервисы вместо модели, то его подход будет в десятки раз роботоспособнее и прозрачнее, чем то что предлагают проповедники DDD.
 
 
Сообщения:129
Vermut:
Вам эти книжки покупать не захочется
Что бы вы посоветовали почитать в плане практической реализации корпоративных приложений? Читал туториал по JavaEE, но он про конкретные технологии. Фаулера тоже читал, рассказывает про общие принципы, рекламирует 'domain model'. У меня, то ли в силу малого опыта, то ли в силу специфики задач/инструментов, каждый раз получается анемичная модель, которую он критикует. Хотя, это даже моделью назвать сложно, скорее просто набор разрозненных абсолютно анемичных сущностей, логика связывания и обработки которых реализуется внешним кодом.
 
 
Сообщения:944
К сожалению у всех каждый раз получается анемичная модель :) прямо как в том анекдоте про отечественный автопром.
Потому что spring или ejb, потому что они навязывают анемичную модель в вашем проекте. Потому что 90% программеров привыкли писать мало того, что анемичный код так ещё и под соусом того что статик методы не имеют состояния, в половине системы (в хэлперах как миниум) присутствуют статик методы.

Если вы начнете писать ООП код, вы рискуете быть не понятым, в лучшем случае. Так что на джаве жизни нет, сплошная анемичная модель и процедурщина. У меня есть смутные сомнения, что из за этого многие мигрировали в другие языки, в scala например.

https://db.tt/V3pEz6WlVJ - облачное хранилище данных
 
 
Сообщения:564
nullvoid:
К сожалению у всех каждый раз получается анемичная модель :) прямо как в том анекдоте про отечественный автопром.
Потому что spring или ejb, потому что они навязывают анемичную модель в вашем проекте.


А я так думаю что spring здесь не совсем причем. Анемичная или нет модель определяется во многом предметной областью. Java это в основном энтерпрайз, а там как то плохо с поведением объектов предметной области, какое например поведение может быть у скажем платежного поручения. Однако если посмотреть в сторону геймдева, то там модель на ооп очень даже хорошо ложится.
Все ИМХО.
 
 
Сообщения:148
Ну, на скале-то простор точно поболее будет)
Особенно помогает правильное применение имплиситов.
 
 
Сообщения:129
izon:
Анемичная или нет модель определяется во многом предметной областью
И спецификой конкретной задачи. У меня получается, что если посередине полноценная доменная модель (данные+связи+поведение), которая с задней стороны отображается в реляционную СУБД, а с другой используется удалённым десктопным клиентом, то приходится вручную делать и отображение в БД (и внимательно его поддерживать) и 'Data Transfer Object' на каждый чих со стороны клиента. Если же отказываюсь от модели предметной области (т.е. даже от связей), то, по крайней мере в видимой мне сейчас части, трудозатраты снижаются - все сущности и код отображения в БД автогенерируются на основании несложных метаданных и никакого ручного вмешательства не требуют, те же сущности без дополнительных затрат передаются и используются на удалённом клиенте. Всё поведение в классах без состояния, ну, т.е. состояние у них есть, но к предметной области оно отношения не имеет.
Изменен:22 апр 2015 18:57
 
 
Сообщения:129
nullvoid:
Потому что 90% программеров привыкли писать мало того, что анемичный код так ещё и под соусом того что статик методы не имеют состояния, в половине системы (в хэлперах как миниум) присутствуют статик методы.
Да, после очередной итерации всё классы, отвечающие за специфику предметной области, полностью лишились состояния (незачем им знать про транзакции и хранилище данных) и превратились просто в средство разбиения поведения на логические блоки. От трансформации их в группы статик-методов пока удерживает лишь мысль, что для некоторых сложных блоков логики можно будет реализовать вариативность поведения через наследование или параметризацию объектов.
Изменен:23 апр 2015 07:41
 
 
Сообщения:1517
kotelok:
От трансформации их в группы статик-методов пока удерживает лишь мысль, что для некоторых сложных блоков логики можно будет реализовать вариативность поведения через наследование или параметризацию объектов.

добро пожаловать в функциональное программирование. там какраз есть ADT (algebraic data types) и функции над ними. "вариативность поведения" обеспечивается через ad-hoc полиморфизм (type classes) и полиморфные функции .
типичная Spring/JEE "архитектура" со всякими там моделями/сервисами/дао - это и не ООП и не ФП.
WertLex:
Ну, на скале-то простор точно поболее будет)
Особенно помогает правильное применение имплиситов.

и в это большая проблема скалы, что там слишком много простора. если бы убрали наследование и различия между методами и функциями, получился бы нормальный функциональный язык. так то он конечно функциональный, но использовать его далеко не всегда удобно.
Изменен:23 апр 2015 14:39
 
 
Сообщения:148
Я бы так сказал:
там достаточно много простора, чтобы писать хороший код. И ровно столько же просторов, чтобы писать плохой.
При этом имхо, кое чего там таки не хватает. Иногда компилятор подтупливает на сложных дженериках, очень не хватает вот прям чистых функций. Прикрутили бы какую аннотацию, чтоли. Знаю, много всего бы это задело и не так все это просто, но тем не менее.

А насчет нормального функционального языка тоже не очень согласен. Имхо, вся мощь Scala в том, что она и FP и OOP одновременно.

К слову, если есть какой-нибудь годный проект на примете, в котором очень удачно реализована модель предметной области, то с радостью бы посмотрел.
 
Модераторы:wedens
Сейчас эту тему просматривают:Нет