Я хочу стать архитектором ПО:
Это хорошая цель для разработчика
Я хочу управлять командой и принимать важные решения о базах данных, фреймворках и веб-сервисах и все такое.
Хм. Ну, тогда ты вовсе не хочешь стать архитектором ПО.
Конечно хочу! Я хочу быть тем человеком, который принимает все важные решения.
Это хорошо, но ты не перечислил важных решений. Ты перечислил решения, не играющие особой роли.
В смысле? База данных – это не важное решение? Знаешь, сколько мы денег тратим на них?
Скорее всего слишком много. И нет, база данных – это не одно из самых важных решений.
Как можно такое говорить? База данных находится в самом центре системы! Там собраны все данные, они сортируются, индексируются и к ним осуществляется доступ. Без нее не будет системы!
База данных это просто устройство ввода-вывода. Так получилось, что она предоставляет некоторые полезные инструменты для сортировки, запросов и отчетов, но все это – вспомогательные аспекты в рамках системной архитектуры.
Вспомогательные? Это безумие.
Да, вспомогательные. Бизнес-правила твоей системы, возможно, используют некоторые из этих инструментов. Но они не существенны для бизнес-правил. Если нужно, то можно заменить эти инструменты другими инструментами, но бизнес-правила останутся теми же.
Ну, да, но придется переписывать весь код, потому что он использует инструменты оригинальной базы данных.
Ну, в этом твоя проблема.
Что ты имеешь ввиду?
Твоя проблема в том, что ты веришь, что бизнес-правила зависят от инструментов базы данных. Это не так. Во всяком случае, они не должны зависеть если ты разработал хорошую архитектуру.
Это безумие. Как я могу создавать бизнес-правила, которые не используют инструменты, которые нужно использовать?
Я не сказал, что они не используют инструменты базы данных. Я сказал, что они не должны зависеть от них. Бизнес-правила не должны знать какую конкретную базу данных ты используешь.
Как заставить бизнес-правила использовать инструменты без знания, что это за инструменты?
Нужно инвертировать зависимость. У тебя база данных зависит от бизнес-правил. Сделай так, чтобы бизнес-правила не зависели от базы.
Ты говоришь какую-то белиберду.
Наоборот. Я говорю на языке архитектуры ПО. Это принцип инверсии зависимостей. Низкоуровневые аспекты должны зависеть от высокоуровневых аспектов.
Больше белиберды! Высокоуровневые аспекты (я так понимаю, ты говоришь про бизнес-правила) вызывают низкоуровневые (я так понимаю, ты имеешь ввиду базу данных). Так что высокоуровневые модули зависят от низкоуровневых так же, как вызывающие зависят от вызываемых. Все это знают!
В рантайме это правда. Но в момент компиляции нам нужно инвертировать зависимость. Исходный код высокого уровня не должен упоминать исходный код низкого уровня.
Ну блин! Нельзя вызвать что-то, не упоминая его.
Конечно можно. В этом суть объектной ориентации.
Суть объектной ориентации в моделировании реального мира, в комбинации данных и функций в связанные объекты. В организации кода в интуитивную архитектуру.
Так тебя научили?
Все это знают. Очевидно, что это правда.
Не сомневаюсь. Не сомневаюсь. И все таки, используя принципы объектной ориентации можно на самом деле вызвать что-то не упоминая этого.
OK. Как?
Ты знаешь, что в объектно-ориентированном дизайне объекты посылают сообщения друг другу?
Да. Конечно.
А ты знаешь, что отправитель сообщение не знает тип получателя?
Это зависит от языка. в Java отправитель знает как минимум базовый тип получателя. В Ruby отправитель знает как минимум то, что получатель может обработать посланное сообщение.
Да. Но ни в одном, ни в другом случае отправитель не знает конкретного типа получателя.
Ага. ОК. Да.
Следовательно, отправитель может быть причиной запуска функции в получателе, при этом не упоминая тип получателя.
Ага. Правильно. Это я понимаю. Но отправитель все еще зависит от получателя.
В рантайме, да. Но не при компиляции. Исходный код отправителя не упоминает и не зависит от исходного кода получателя. Исходный код получателя зависит от исходного кода отправителя.
Нееее. Отправитель все еще зависит от класса, которому посылается сообщение.
Возможно, нам нужны примеры. Я буду писать на Java. Сначала пакет отправителя:
package sender;
public class Sender {
private Receiver receiver;
public Sender(Receiver r) {
receiver = r;
}
public void doSomething() {
receiver.receiveThis();
}
public interface Receiver {
void receiveThis();
}
}
Теперь пакет получателя.
package receiver;
import sender.Sender;
public class SpecificReceiver implements Sender.Receiver {
public void receiveThis() {
//do something interesting.
}
}
Заметь, что получатель зависит от отправителя. Также заметь, что SpecificReceiver зависит от Sender. И ничего в отправителе не знает о получателе.
Да, но это читерство. Ты вставил интерфейс получателя в класс отправителя.
Теперь ты начинаешь понимать.
Понимать что?
Принципы архитектуры, конечно же. Отправители владеют интерфейсами, которые получатели должны реализовывать.
Если это значит, что придется использовать вложенные классы, то...
Вложенные классы это всего лишь один из способов добиться цели. Есть другие.
ОК, погоди. Причем тут базы данных? Мы начали с этого.
Давай взглянем на другой код. Вот первое бизнес-правило:
package businessRules;
import entities.Something;
public class BusinessRule {
private BusinessRuleGateway gateway;
public BusinessRule(BusinessRuleGateway gateway) {
this.gateway = gateway;
}
public void execute(String id) {
gateway.startTransaction();
Something thing = gateway.getSomething(id);
thing.makeChanges();
gateway.saveSomething(thing);
gateway.endTransaction();
}
}
Это бизнес-правило особо ничего не делает.
Это просто пример. У тебя скорее всего много таких классов, реализующих разные правила.
ОК, что это за Gateway
там?
Он предоставляет все метода доступа к данным, которые использует бизнес-правило. Вот его реализация:
package businessRules;
import entities.Something;
public interface BusinessRuleGateway {
Something getSomething(String id);
void startTransaction();
void saveSomething(Something thing);
void endTransaction();
}
Заметь, что это не пакет businessRules.
Ага, ОК. А что за класс Something
?
Он представляет простой бизнес-объект. Я положил его в пакет под названием entities.
package entities;
public class Something {
public void makeChanges() {
//...
}
}
И, наконец, вот реализация BusinessRuleGateway. Этот класс знает о самой базе данных:
package database;
import businessRules.BusinessRuleGateway;
import entities.Something;
public class MySqlBusinessRuleGateway implements BusinessRuleGateway {
public Something getSomething(String id) {
// use MySQL to get a thing.
}
public void startTransaction() {
// start MySQL transaction
}
public void saveSomething(Something thing) {
// save thing in MySQL
}
public void endTransaction() {
// end MySql transaction
}
}
Опять же, заметь, что бизнес-правила вызывают базу данных во время исполнения, но во время компиляции это делает пакет database. Он упоминает и зависит от пакета thebusinessRules.
Ок, ок, кажется, я понял. Ты просто используешь полиморфизм чтобы скрыть реализацию базы данных от бизнес-правил. Но все еще нужен интерфейс, который предоставляет бизнес-правилам доступ ко всем инструментам базы данных.
Нет, вовсе нет. Мы не пытаемся предоставить бизнес-правилам все инструменты базы данных. Наоборот, наши бизнес-правила создают интерфейсы только для того, что им требуется. Реализация этих интерфейсов уже может вызывать подходящие инструменты.
Ага, но если бизнес-правилам нужны все эти инструменты, то придется положить их все в интерфейс gateway
.
Ах. Вижу, что ты все еще не понимаешь.
Не понимаю чего? Мне кажется, все предельно ясно.
Каждое бизнес-правило определяет интерфейс лишь для необходимого ему способа доступа к данным.
Стоп. Что?
Это называется принцип разделения интерфейса. Каждый класс бизнес-правила будет использовать только часть механизмов базы данных. Поэтому каждое бизнес-правило предоставляет интерфейс, дающий ему доступ только к этим механизмам.
Но это значит, что придется иметь дело с кучей интерфейсов, и кучей маленьких классов реализации для вызова других классов базы данных.
Хорошо. Вижу, что теперь ты начинаешь понимать.
Но это бардак и трата времени! Зачем такое делать?
Чтобы содержать все в чистоте и экономить время.
Ой, все! Это просто куча кода ради кода.
Наоборот, эти важные архитектурные решения позволят откладывать нерелевантные решения.
Что ты имеешь ввиду?
Помнишь, ты начал с того, что хотел стать архитектором ПО? Ты хотел принимать все самые важные решения?
Да, этого я и хочу.
Среди этих решений были база данных, веб-сервер и фреймворки.
Ага, и ты сказал, что это не важные решения. Ты сказал, что они не играют особой роли.
Верно. Не играют. Важные решения, которые принимает архитектор ПО, позволяют НЕ принимать решения по поводу базы данных, веб-сервера и фреймворков.
Но нужно принять эти решения вначале!
Нет, не нужно. На самом деле, нужно сделать так, чтобы была возможность принимать эти решения намного позже в цикле разработки – когда будет больше информации.
Горе – это архитектор, который преждевременно выбирает базу данных, а потом понимает, что плоской файловой структуры было бы достаточно.
Горе – это архитектор, который преждевременно выбирает веб-сервер, а потом понимает, что команде нужен был простой socket-интерфейс.
Горе – это команда, чей архитектор преждевременно навязывает на нее фреймворк, а потом понимает, что фреймворк предоставляет не нужные им возможности и добавляет ограничения, с которыми невозможно жить.
Благословенна команда, чьи архитекторы предоставили способ откладывания всех этих решений до момента, когда у команды будет достаточно информации для их принятия.
Благословенна команда, чьи архитекторы так хорошо изолировали их от ресурсоемких устройств ввода-вывода и фреймворков, что команда способна создавать быстрые и легкие среды тестирования.
Благословенна команда, чьи архитекторы волнуются о по-настоящему важных вещах, и откладывают не важные.
Ерунда. Я ничего не понимаю.
Ну, возможно, поймешь лет через десять… Если не перейдешь в менеджеры.
Комментарии (36)
Botchal
12.10.2016 13:10Стильно, творчески, понятно. Спасибо, очень понравилось, не сухо.
От себя внёс бы правку вместо реплики «Ну, возможно, поймешь лет через десять» привёл бы пример про недостаточность данных в начале разработке. Когда просят одно, а потом оказывается, что это немного другое. Или пока идёт разработка бизнес логика может измениться (например, вслед за потребностями рынка). И поэтому следует принимать эти решения, намного позже и делать всё оптимально гибко.Vladek
12.10.2016 15:08+2Требований всегда два: программа должна работать и быть готовой к изменениям.
Scf
12.10.2016 13:35+1Хороший текст. Много букв, объясняющих простую мысль — архитектуру не проектируют. Архитектура растет, развивается и преобразуется вместе с ростом кодовой базы. И самое сложное в работе архитектора — не загнать самого себя в угол, построив то, что невозможно будет изменить в нужную сторону. А с другой стороны гибкость = сложность. А сложность означает высокую стоимость внесения изменений, что приводит в тот же угол. Примерно так.
Fesor
12.10.2016 21:37А с другой стороны гибкость = сложность. А сложность означает высокую стоимость внесения изменений, что приводит в тот же угол.
Вот очень хорошая фраза. Но проблема как мне видится в том что слова сложность и гибкость воспринимаются разработчиками оочень по разному.
Например штуки вроде инкапсуляции призваны понижать сложность и в целом положительно влияют на гибкость системы. С другой стороны если сильно загоняться по инкапсуляции может возникнуть ситуация с увеличением связанности между компонентами. И уже надо искать баланс.
Так же есть еще такая штука… вот вроде взять и изолировать работу с базой в отдельном объекте (gateway) — это не сложно. Это не то что бы сильно дольше, и это не требует каких-то глубоких познаний в программировании. Но "размазать по контроллерам же проще". Нет у людей понимания что проще — это когда мысль заложенная кодом прослеживается явно. "Простые" решения частенько приводят к "сложным" проблемам.
Ладно… я походу упоролся… но мне кажется вопрос сложности в ПО крайне интересным потому как я часто замечаю среди неопытных разработчиков извращенную трактовку сложности.
Akon32
12.10.2016 14:02+4Многовато воды. 15 реплик, прежде чем привести пример кода, вместо того, чтобы сразу сказать "интерфейсы!"
А при проектировании "архитектором" интерфейса хранения данных неплохо бы иметь в виду какой-нибудь вариант реализации (опыт использования конкретных СУБД или создания файлового хранилища), чтобы знать, что придуманный интерфейс реализовать можно.
Иначе может получиться, что интерфейс-то есть, реализацию написали, а использовать систему нельзя — слишком плохо/медленно/etc всё работает из-за интерфейса, который в принципе нельзя реализовать эффективно.
Ещё опасно надеяться на то, что где-то есть реализация нужных фич (функциональности/надёжности/скорости), или что эти фичи как-то можно реализовать, не зная наверняка, как.
Благословенна команда, чьи архитекторы предоставили способ откладывания всех этих решений до момента, когда у команды будет достаточно информации для их принятия.
Могу предположить, что так не бывает, хотя к этому и надо стремиться.
Информация поступает уже после реализации. Иногда поступает такая информация, что приходится выкидывать все интерфейсы, реализацию, клиентский коди горе-архитектора, чтобы переписать всё нормально, чтобы этим можно было пользоваться.
До следующей подобной итерации. Это немного печально, но в этом суть ПО — его (как правило) можно переписать.
aon24
12.10.2016 14:23+2В практической области это означает, что наиболее опытным программистам следует поручать разработку инструментальной части, т.е. создание проблемно-ориентированного фреймворка
tangro
13.10.2016 10:47-1Автора покусали джависты. Если уж начал рассказывать о независимости подсистем — надо было делать это на примере очередей сообщений, AMQP или ZeroMQ, микросервисов. А то «зафиксируем тут у нас Java, интерфейсы, SQL — а дальше будем потом что-то решать». Что вы там уже будете решать, если зафиксировали язык, платформу, тип БД. Вам уже на этом этапе всё продиктуют традиции, обстоятельства и безысходность.
Akon32
13.10.2016 12:04В идеале, да.
С другой стороны, делать полностью независимые от платформы/языка подсистемы — это ещё более "java-way" (очень суровый энтерпрайз, в смысле). Может получиться слишком абстрактно для обучения. Да и для жизни тоже.
Fesor
13.10.2016 12:16Акцент делался на инверсии зависимостей, а не на фиксации платформы. В фиксации платформы нет ничего плохого, но вот сегодня у вас бизнес правило (или ограничение) реализуется в рамках вашей системы, а завтра вы решили реализовать в микросервисе. И проблема та же.
да и не умея писать нормальные монолиты микросервисы делать не стоит. Проблем будет больше.
AnnieOmsk
16.10.2016 07:21Рахим, какая прелесть! Прямо порадовал таким переводом. Давай еще :-) Дядя Боб рулит, впрочем, как и всегда.
occam
17.10.2016 07:22-1Большое спасибо, Рахим. Очень много свежих взглядов на ожидания к архитектору. По мне так, ни логику — ни платформы, прибивать гвоздями глупо. Все очень быстро меняется. Как, ну как, можно заложить логику или платформы на весь жизненный цикл fb или aws?
Я вот, может быть, тоже хотел бы стать архитектором ПО. Но таким архитектором, который в первый день (не астрономический) проекта способен заложить такие statements, которые в следующие 6 дней позволят полностью обойтись без архитектора. Шажок вперед с твоей помощью сделан, спасибо большое!DrPass
17.10.2016 10:11-1> Как, ну как, можно заложить логику или платформы на весь жизненный цикл fb или aws?
Вы просто не учитываете тот момент, что зачастую изменения можно, а иногда и нужно игнорировать. Да, работая с каким-то вендорским сервисом, вам деваться некуда — это будут решать за вас, и вам для вашей же безопасности потребуется прослойка, которая абстрагирует вас от изменений API (насколько это возможно). Но если речь идёт, например, о СУБД или какой-либо библиотеке, то тут у вас уже больше вариантов для манёвров. Нередко оказывается, что ценность ПО и/или обрабатываемых им данных на порядки выше, чем ценность миграции на новые версии. И в таких случаях, например, может быть правильнее пожертвовать переносимостью в угоду стабильности ядра приложения.occam
17.10.2016 12:34Нет. Вы не правы. Кроме вендорского сервиса еще есть простой человеческий фактор, когда команда платформы, даже самой совершенной платформы, теряет лидера и начинает плавно рассыпаться, понятно, что этот процесс занимает не один год, но для нашего с вами проекта эти 2-3 года станут временем застоя. Плавали-знаем. Из какой экосистемы привести примеры: Oracle, IBM, MS, что вам стало бы понятнее на конкретном кейсе?
kvothe
17.10.2016 14:03Если можно — Oracle или MS, мне тоже интересно послушать.
occam
17.10.2016 21:22Без проблем. Начнем с Oralce. Кстати, до облачного экстаза, были весьма последовательны в реализации принципов middleware. Апдейты похоронного архива думаю у вас на контроле. К счастью, Database цветет и прибавляется новыми поколениями, а вот дальше по тексту меня, возможно, не поймут.
Видите ли, в моем мире, проект внедрения бизнес-приложения на готовой платформе считается проектом разработки.
Взять за пример crm, поверьте, что не бывает в enterprise двух одинаковых crm. Каждый проект — это отдельные (новые) модели управления лояльностью, аналитики, прогнозирования — это очень долгие и непростые поиски, не всегда получается укладываться в заданный функционал и очень большая ошибка, когда слои бизнес-приложения верстают под конкретную платформу. В недалеком прошлом этой граблей был получен бесценный опыт, когда после мучительного и долгого совместного выбора с дорогим и хорошим кастомером fusion apps, через некоторое время был получен новый deathlist, в котором у fusion уже не было будущего.
Не промолчим и про хостовую примаверу, которая обеспечивает рабочие процессы строительных компаний, имеющих думаю не меньше 30% в общем объеме вводов в эксплуатацию жилых площадей в 2013-16. Поверьте, намного дешевле (имея ТЗ на примере внедренной примаверы) найти программиста, который запустит сервис управления проектным офисом с нуля, чем аналитика, который поможет в миграции с примаверы.
DrPass
17.10.2016 16:37+1> Кроме вендорского сервиса еще есть простой человеческий фактор, когда команда платформы,
> даже самой совершенной платформы
Я по этому поводу с вами совершенно согласен… но от этой проблемы, в общем-то, механизма защиты вообще нет. У лидеров проектов с взаимозаменяемостью крайне плохо. Если команда очень большая, и можно выдвинуть нового лидера, считай, повезло.occam
17.10.2016 20:43С 1ой стороны нет механизмов, а может и есть? Об этом и пишу, о том, как интересно думать о них, видеть примеры и искать свои решения. Плюсую сэру fesor в точном описании стратегии aws, не сказать, чтобы они добежали до финиша, но общее направление весьма новоуровневое. Что-то очень интересно происходит в 1С, могу ошибаться, но, возможно, именно в этой команде появится первый для России подтвержденный пример, когда архитектор сознательно формировал среду разработки, не зависящую в дальнейшем от архитектора. Вопрос навскидку, сколько вы думаете СУБД поддерживает 1С: Предприятие?
DrPass
17.10.2016 23:51+1> Вопрос навскидку, сколько вы думаете СУБД поддерживает 1С: Предприятие?
Вы, на самом деле, приводите отличный контрпример :) Это система, которая была изначально жестко привязана к одной файловой нативной СУБД. И когда пришло время и спрос, её «отвязали» и дали возможность использовать другие СУБД.
Fesor
17.10.2016 14:30+1не забывайте еще о языке программирования. Вы на него завязались и уже никуда не слезите. И абстрагироваться от оного у вас не выйдет (только микросервисы разве что спасают но они привносят тот уровень сложности, который оправдан на малом проценте проектов).
Базы данных — так же. Нет смысла полностью от них абстрагироваться, но отделять логику от оных — вполне. То есть банальный DAO решает проблему так же как и data mapper или active record (да да, если обернуть data-model в обертку предоставляющую объектную модель, что-бы наша бизнес логика использовала active record тупо как атрибуты, то тогда все хорошо и плохо только с точки зрения юнит тестирования, и то есть варианты).
Менять базы данных никто обычно не планирует. А вот добавлять еще — это можно. Вполне может возникнуть ситуация при которой придется хранить часть данных в другой СУБД которая просто эффективнее справляется с задачей. А еще есть CQRS что бы творить вообще магические вещи. А еще — Event Sourcing что-бы совсем абстрагироваться от хранилища (на запись во всяком случае).
У того же FB есть проблемы с "прибитыми гвоздями" решениями. Часть они решают (HHVM, Hack вместо php), часть — нет (long polling вместо websockets) ну и т.д. Но у них и ресурсов побольше и задачи другие.
А AWS используют микросервисы что-бы скейлиться. Да и при их масштабе по другому уже не выйдет. Опять же микросервисы это эдакий способ снижения связанности. Вы всегда можете критическое место переписать за адекватные строки без ущерба проекту.
DrPass
На самом деле посыл статьи не о «хорошей практике» в создании архитектуры, а о практике, применимой в частных случаях. Абстрагирование от конкретных платформ неизбежно порождает ещё один набор промежуточных сущностей. И одна из задач архитектора как раз и состоит в том, чтобы решить — целесообразно ли в рамках проекта эти сущности плодить, или требования и перспективы проекта таковы, что выгоднее «прибить гвоздями» логику к платформе.
napa3um
Многие «архитекторы» просто не видят этих сущностей над БД или JVM, о том «боль» автора, ИМХО. А использовать привычный технологический стек, конечно, не возбраняется, нужно лишь думать таким образом при разработке системной архитектуры, будто этот стек неважен.
DrPass
> нужно лишь думать таким образом при разработке системной архитектуры, будто этот стек неважен.
Да не получится так думать на самом деле. Это допустимо лишь в том случае, когда переносимость — изначальное бизнес-требование к проекту. Во всех остальных случаях ответ на вопрос «что к чему прибивать гвоздями» всегда имеет численное выражение в человеко-часы и деньги, и должен быть решён одним из первых, на самых ранних этапах проектирования.
napa3um
Ну, возможно, поймешь лет через десять… Если не перейдешь в менеджеры. :)
DrPass
Поздно уже. Я прошел этап, когда писал программы на коленке, а вечером играл в третьих героев, прошел этап, когда я всерьез относился ко мнению падавана в этой статье, прошел этап, когда я всерьез относился к созданию гибких архитектур, и теперь я понимаю, что из всего этого лучше всего было играть в третьих героев.
napa3um
Но этап, на котором «точно знаешь» этапность своего жизненного пути и заранее предполагаешь тот объём знаний, который ещё только будет освоен в будущем, возможно, ещё не пройден. Вы сами заговорили о себе, я просто поддержал беседу в ироничном ключе автора статьи, ничего личного (сам я на этапе третих героев пока). :)
DrPass
Естественно. Возможно, в восьмых «героях» меня ждет откровение (хотя и маловероятно). Но вот от гибкой архитектуры я его уж точно не жду :)
napa3um
*тьих
Bringoff
Такая архитектура нужна не только для переносимости между платформами. Пример из своей области (Android) — нужно какую-то ленту новостей отображать. Клепаешь что-то на коленке. Чтобы побыстрее выкатить MVP кэширование в базу не впиливаешь, а каждый раз подгружаешь с инета. Но потом таки наступает момент, когда и кэш можна уже впилить, — а у тебя GUI знает, что данные с инета идут. Вот тут ты и попал.
DrPass
Я же не говорю, что эта архитектура не нужна :) Я говорю, что её нужно применять не «by default», а осознанно, взвесив все «за» и «против», и определившись с инструментарием на самом раннем этапе проектирования.
wing_pin
А потом появляются нытики, которым изначальный выбор %DATABASE_NAME% не подешел, а прямо сейчас уже поздно что-то менять и приходится жрать кактусы.
khim
Нытики есть и будут всегда, но простая истина заключается в том, что не бывает «бесплатной гибкости». Если у вас, реортически, %DATABASE_NAME% можно поменять, а на пректике — там всегда MySQL, то по прошествии 10 лет шансов на смену базы всё равно нет, а затраты на поддержку абстракции — есть.
YAGNI — очень хороший принцип, чесслово. Добавляйте гибкость там, где вы точно знаете когда вы будете её использовать. Если у вас в следующем релизе запланировано кеширование данных с бекенда — дело одно, а если вы это закладываете «на всякий случай» — совсем другое.
Fesor
это значит что на момент выбора базы данных у разработчика не-было ни малейшего представления что он собирается сделать.
Приведу пример. Например делали мы проект на mysql и все было замечательно. А потом всплыла работа с геоданными и т.д. Не вопрос, ставим рядом elasticsearch, дублируем туда данные (только то что нужно) и используем их для построения необходимых агрегаций.
Ну то есть если для конкретной задачи ваша база данных не подходит — это не повод "менять все", это лишь повод поставить рядом ту что подходит и как-то решить проблему малой кровью. Когда все "прибито гвоздями" это будет дороже, а когда есть пространство для маневра (DAO, Table Gateway, Data Mapper) — все довольно легко решается. Ну а если база данных не подходит для доброй половины задач — ну явно что-то не так пошло. Значит разработчик не разобрался зачем оно ему надо. И сейчас это проблема — многие берут тулзы не потому что они им нужны — а потому что в тренде все.
А всего-то надо разобраться с простейшей идеей разделения ответственности. И жить станет проще.
Vladek
Эти сущности плодятся для того, чтобы выбранная платформа не диктовала как строить приложение. Иначе ядро программы («бизнес-логика») размажется ровным слоем по выбранным фреймворкам и станет надстройкой, а не полноценной и отдельной сущностью.
С временем жизни проекта количество платформ может увеличиться, ядро программы должно общаться с любой из них одинаковым образом. Ядро программы может вообще пережить выбранную платформу.
DrPass
> чтобы выбранная платформа не диктовала как строить приложение.
А что в этом, собственно, плохого? Если платформа позволяет решить задачу так, как надо, и нет потребности делать переносимое решение, то почему бы и не сделать его платформенно-зависимым?
> С временем жизни проекта количество платформ может увеличиться
> Ядро программы может вообще пережить выбранную платформу.
А может и не увеличиться, а может и не пережить. И у кросс-платформенного решения есть своя цена. Причём она может выражаться не только в упомянутых выше деньгах и человеко-часах. Это может быть и цена производительности решения, и его масштабируемости, и его сроках выхода на рынок. Поэтому я не могу утверждать, что такая архитектура лучше или хуже. Всё, что я могу утверждать — что сначала надо делать оценку, а потом решать, подходит она конкретно для вашего проекта, или нет.
Fesor
А еще ядро может исчезнуть. Микросервисы нынче в тренде и все такое. Бац так и нет ядра — распределенное приложение со всеми плюсами и минусами.