На мой взгляд, это совсем не так, как это подразумевается. И это нарушение СУХОЙ.
Идея состоит в том, что объект сущность / домен в середине моделируется так, чтобы представлять домен настолько хорошо и максимально удобно, насколько это возможно. Он находится в центре всего, и все может зависеть от него, так как сам домен не меняется большую часть времени.
Если ваша внешняя база данных может хранить эти объекты напрямую, то сопоставление их с другим форматом для разделения слоев не просто бессмысленно, но создает дубликаты модели, а это не является намерением.
Начнем с того, что чистая архитектура была создана с учетом другой типичной среды / сценария. Приложения для бизнес-серверов с огромными внешними слоями, которым нужны специальные типы объектов. Например, базы данных, которые производят SQLRow
объекты и нуждаются SQLTransactions
в возврате к элементам обновления. Если бы вы использовали их в центре, вы бы нарушили направление зависимости, потому что ваше ядро зависело бы от базы данных.
С облегченными ORM, которые загружают и хранят объекты сущностей, это не так. Они делают сопоставление между своим внутренним SQLRow
и вашим доменом. Даже если вам нужно поместить @Entitiy
аннотацию ORM в объект вашего домена, я бы сказал, что это не устанавливает «упоминание» о внешнем уровне. Поскольку аннотации - это просто метаданные, никакой код, который их не ищет, их не увидит. И что более важно, ничего не нужно менять, если вы удалите их или замените их аннотацией другой базы данных.
Напротив, если вы меняете свой домен, и вы сделали все эти мапперы, вам придется многое изменить.
Поправка: Выше немного упрощено и может даже ошибаться. Потому что в чистой архитектуре есть часть, которая хочет, чтобы вы создавали представление для каждого слоя. Но это должно быть видно в контексте приложения.
А именно следующее здесь https://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html
Важно то, что изолированные, простые структуры данных передаются через границы. Мы не хотим обманывать и передавать строки сущностей или базы данных. Мы не хотим, чтобы структуры данных имели какую-либо зависимость, которая нарушает правило зависимости.
Передача сущностей из центра в направлении внешних слоев не нарушает правила зависимости, но они упоминаются. Но это имеет смысл в контексте предполагаемого применения. Передача сущностей будет перемещать логику приложения наружу. Внешние слои должны были бы знать, как интерпретировать внутренние объекты, они фактически должны делать то, что должны делать внутренние слои, такие как слой «сценарий использования».
Кроме того, он также разделяет слои, поэтому изменения в ядре не обязательно требуют изменений во внешних слоях (см. Комментарий SteveCallender). В этом контексте легко увидеть, как объекты должны конкретно представлять цель, для которой они используются. Кроме того, эти слои должны общаться друг с другом в терминах объектов, которые созданы специально для целей этой коммуникации. Это может даже означать, что существует 3 представления, по 1 на каждом уровне, 1 для передачи между уровнями.
И есть https://blog.8thlight.com/uncle-bob/2011/11/22/Clean-Architecture.html, адрес которого указан выше:
Другие люди беспокоятся о том, что результатом моих советов будет много дублированного кода и многократное копирование данных из одной структуры данных в другую на всех уровнях системы. Конечно, я тоже этого не хочу; и ничто из того, что я предложил, неизбежно приведет к повторению структур данных и нарушению полевого копирования.
Это IMO подразумевает, что простое копирование объектов 1: 1 является запахом в архитектуре, потому что вы на самом деле не используете надлежащие слои и / или абстракции.
Позже он объясняет, как он представляет все «копирование»
Вы отделяете пользовательский интерфейс от бизнес-правил, передавая простые структуры данных между ними. Вы не позволяете своим контролерам ничего знать о бизнес-правилах. Вместо этого контроллеры распаковывают объект HttpRequest в простую ванильную структуру данных, а затем передают эту структуру данных объекту-интерактору, который реализует сценарий использования, вызывая бизнес-объекты. Затем интерактор собирает данные ответа в другую ванильную структуру данных и передает их обратно в пользовательский интерфейс. Представления не знают о бизнес-объектах. Они просто смотрят в эту структуру данных и представляют ответ.
В этом приложении есть большая разница между представлениями. Данные, которые передаются не только сущности. И это оправдывает и требует разных классов.
Однако применительно к простому приложению Android, такому как средство просмотра фотографий, в котором у Photo
сущности имеется около 0 бизнес-правил, а «сценарий использования», который их касается, практически отсутствует и на самом деле больше заботится о кэшировании и загрузке (этот процесс должен выполняться IMO. более подробно), точка для создания отдельных представлений о фотографии начинает исчезать. У меня даже возникает ощущение, что сама фотография является объектом передачи данных, в то время как реальный уровень бизнес-логики отсутствует.
Существует различие между «отделить пользовательский интерфейс от бизнес-правил путем передачи простых структур данных между ними» и «когда вы хотите отобразить фотографию, переименуйте ее 3 раза в пути» .
Кроме того, я вижу, что эти демонстрационные приложения не могут представить чистую архитектуру, потому что они придают огромное значение разделению слоев ради разделения слоев, но эффективно скрывают, что делает приложение. Это противоречит тому, что сказано в https://blog.8thlight.com/uncle-bob/2011/09/30/Screaming-Architecture.html, а именно:
архитектура программного приложения кричит о вариантах использования приложения
Я не вижу такого акцента на разделении слоев в чистой архитектуре. Речь идет о направлении зависимостей и сосредоточении внимания на том, чтобы представлять ядро приложения - сущности и варианты использования - в идеально простой java без зависимостей вовне. Дело не столько в зависимости от этого ядра.
Поэтому, если ваше приложение на самом деле имеет ядро, которое представляет бизнес-правила и варианты использования, и / или разные люди работают на разных уровнях, разделите их по назначению. Если вы просто пишете простое приложение, не переусердствуйте. 2 слоя с плавными границами может быть более чем достаточно. И слои могут быть добавлены позже.
BankAccount
но с конкретными правилами приложения, что вы можете делать с этой учетной записью.@SerializedName
аннотации Gson в модель предметной области? Или вы бы создали новый объект, отвечающий за отображение веб-ответа на модель домена?Вы действительно поняли это правильно. И нет никакого нарушения DRY, потому что вы принимаете SRP.
Например: у вас есть бизнес-метод createX (имя строки), а затем у вас может быть метод createX (имя строки) на уровне DAO, вызываемый внутри бизнес-метода. Они могут иметь одну и ту же подпись и, возможно, есть только делегация, но у них разные цели. Вы также можете использовать createX (имя строки) в UseCase. Даже тогда это не является избыточным. Я имею в виду следующее: «Одни и те же подписи не означают семантику». Выберите другие имена, чтобы очистить семантику. Называя себя, это никак не влияет на SRP.
UseCase отвечает за логику для конкретного приложения, бизнес-объект отвечает за логику, не зависящую от приложения, а DAO отвечает за хранение.
Из-за различной семантики все уровни могут иметь свое собственное представление и коммуникационную модель. Часто вы видите «сущности» как «бизнес-объекты», и часто вы не видите необходимости разделять их. Но в «огромных» проектах необходимо приложить усилия для правильного разделения слоев. Чем больше проект, тем выше вероятность того, что вам нужна разная семантика, представленная в разных слоях и классах.
Вы можете думать о разных аспектах одной и той же семантики. Пользовательский объект должен отображаться на экране, он имеет некоторые внутренние правила согласованности и должен где-то храниться. Каждый аспект должен быть представлен в другом классе (SRP). Создание картографов может быть проблемой в заднице, поэтому в большинстве проектов, над которыми я работал, эти аспекты сведены в один класс. Это явно нарушение ПСП, но на самом деле это никого не волнует.
Я называю применение чистой архитектуры и SOLID «социально неприемлемым». Я бы работал с этим, если бы мне позволили. В настоящее время мне запрещено это делать. Я жду момента, когда мы должны подумать о том, чтобы воспринимать SOLID серьезно.
источник
Нет, вам не нужно создавать классы моделей в каждом слое.
Entity (
DATA_LAYER
) - это полное или частичное представление объекта базы данных.DATA_LAYER
Mapper (
DOMAIN_LAYER
) - фактически это класс, который конвертирует Entity в ModelClass, который будет использоваться наDOMAIN_LAYER
Посмотрите: https://github.com/lifedemons/photoviewer
источник