Size: a a a

Android Architecture

2017 February 08

AE

Alexey Elisov in Android Architecture
у меня есть репозиторий
UsersRepository
, который имеет метод
List<User> UsersRepository.getAll()

так вот в локальной бд у меня одни сущности а из сети приходят другие, понятно что
User
будет приводиться к
UserViewModel
в интеракторе. Но в данном случае придется ещё делать общую сущность, к которой нужно приводить сущности из сети и локальной бд, а затем возвращать из репозитория
источник

AE

Alexey Elisov in Android Architecture
вопрос: что у меня не так?
источник

I

Ivan in Android Architecture
А зачем в бд сохранять другие сущности?
источник

AE

Alexey Elisov in Android Architecture
блин, реально, зачем мне дублировать их
источник

AE

Alexey Elisov in Android Architecture
чет сделал разные и не подумал)
источник

AE

Alexey Elisov in Android Architecture
а, я вспомнил почему
у меня был случай, когда я юзал орм и там не подходили сущности из сети
источник

AE

Alexey Elisov in Android Architecture
т.к. в сущности нужно было хранить список других объектов, а орм не поддерживало этой штуки
источник

IC

Ilya Chirkov in Android Architecture
Что ж это за орм, которая не умеет в связи 1 ко многим
источник

AE

Alexey Elisov in Android Architecture
там не поддерживались именно List
источник

I

Ivan in Android Architecture
ORM Sadness
источник

AE

Alexey Elisov in Android Architecture
sugarORM
источник

NK

ID:221287170 in Android Architecture
Вопрос: есть 2 радио баттона, в зависимости от их значений, меняется некоторые параметры edittext, куда выносить эту логику, в презентер или дальше в интерактора?
источник

AD

Andrew Dementiev in Android Architecture
ID:221287170
Вопрос: есть 2 радио баттона, в зависимости от их значений, меняется некоторые параметры edittext, куда выносить эту логику, в презентер или дальше в интерактора?
параметры на что влияют? если только на отображение, то я бы вообще во вью оставил
источник

EM

Eugene Matsyuk in Android Architecture
Так вот про книги. Приведу список тех, которые, как мне кажется,должен прочитать каждый)
1. Паттерны проектирования. Банда четырех.
Основа основ.
2. Effective Java 2. Joshua Bloch.
Хорошо вправляет мозги, особенно начинающим. Когда я первый раз прочитал данную книгу, я не понимал, как я раньше то жил =) Хорошие советы, как писать хороший код на Java.
3. Чистый код. Роберт Мартин.
Тоже отличная книга, рассказывающая, как не гавнокодить.
4. Совершенный код. Макконнелл.
Тоже отлично прочищает мозги.
5. Экстремальное программирование. Кент Бек.
Как писать с TDD. Учит мыслить тестами.
6. The Clean coder. Робер Мартин.
Хорошие советы разработчикам.
7. Working effectively with Legacy code. Michael Feathers.
Про боль, которая знакома каждому. Как бороться с легаси.
8. Refactoring. Мартин Фаулер.

В каждой книге вы найдете что-то свое. Найдете свои ответы на свои же вопросы
источник

NK

ID:221287170 in Android Architecture
Andrew Dementiev
параметры на что влияют? если только на отображение, то я бы вообще во вью оставил
меняю hint и inputType параметры у EditText.
источник

AD

Andrew Dementiev in Android Architecture
ну и оставь во вью, если данные в одно и то же место уходят
источник

EM

Eugene Matsyuk in Android Architecture
Alexandr Zherebtsov
Повспоминал немного инфы на этот счет. Начну с рассказа почему считаю, что репозитории и их интерфейсы не должны храниться вместе в слое данных. Некоторое время назад, у меня была задача на новом проекте использовать Realm вместо привычного Sqlite. При этом была вероятность, что где в середине проекта мне захочется вернуться назад к Sqlite.  Архитектура, которая позволяла менять дата слой, незатрагивая других выглядела выгодно. Кoнечно, нужно было бы перпеписать большой объем кода, сопастовимый с объемом кода, если интерфейсы репозиториеев хранить в дате слое. Но в случае, если хранить интерфейсы репозиторий в дате, то получается, что бизнес логика знает о деталях реализции моей БД. Возможно даже это означает, что мне придется как то в эти детали вникать, например, мы иногда в моделе дата слоя можем сохранить сложную структуру прям json'ом и парсить при необходимости в объекты. Поместив интерфейс репозитория в слой с бизнес-логикой я смогу гарантировать, что мне никогда не придется вникать в подобные вещи, так как в слой с бизнес-логикой мне зайдут уже модели бизнес-логики. Стоит отметить, что это был мой первый проект с такой архитектурой и я некоторых вещей не понимал еще и на всякий случай, чтобы не сбится с пути и чтобы точно с Realm ничего не заскочило в логику, сделал по примеру Фернандо слой с бизнес-логикой java модулем (кстати так поступаю до сих пор). Таким образом, действительно поменять Realm на что то другое стало проще. Правда, я сразу лишился некоторых фичей реалма, заперев его в слое данных. Дядюшка Боб, кстати, говорит о том, что интерфейсы и их реализации не должны лежать в одном пакете, несмотря на то что у них сильная физическая связь. Он считает правильным, когда интерфейс принадлежит клиенту, который его использует [1]. Так же он об этом писал в своей статье по архитектруре, там же про то, что логика не должна зависисеть от дата слоя. "Independent of Database. You can swap out Oracle or SQL Server, for Mongo, BigTable, CouchDB, or something else. Your business rules are not bound to the database." [2] Собстенно он же пишет, что ничто не должно влиять на слой с бизнес правилами: "We do not expect changes in this layer to affect the entities. We also do not expect this layer to be affected by changes to externalities such as the database, the UI, or any of the common frameworks. This layer is isolated from such concerns." [2]
В целом получается, что такую схему зависимостей я выбрал потому, что в теории она позволяла мне с минимальными усилями мигрировать на другую БД и она была описана в статьях и книжках, что сводило к минимуму вероятность ошибок с моей стороны.

Фаулер, кстати, такую архитектуру называет Hexagonal architecture [3]. Он считает, что в разделенной на слои архитектуре, зависимости должны быть направлены сверху вниз, представление зависит от бизнес-логики, бизнес-логика от дата слоя. Но также говорит о том, что возможен такой вариант, когда бизнес-логика не зависит ни от одного слоя. При этом дополнительно выделяет слой "Data Mapper" [4]. Точнее не он сам выделяет, просто рассказывает об этом.

Есть еще одна замечательная книга от Марка Симана (работал в Microsoft), посвященная DI в .NET. Из .NET там только конкретные примеры и описания IoC-контейнеров, в остальном там много хорошего теоретического материала, по DI лучше литературы вы не найдете, кстати, так что очень советую. Так вот, он там рассматривает простенькое приложение на ASP.NET MVC. Подробно рассматривает каждый из трех слоев, рассказывает, что в каком слое у него есть. Сначала он рассматривает неверную, на его взгяд реализацию, аргументирует и рефакторит в сторону независимого слоя с бизнес-логикой.[5]

По поводу связи слоя презентации и бизнес-логики, то у меня сейчас презентеры в основном используют модели бизнес-логики. И не всегда даже маппят их в модели UI, хотя конечно такое приходится делать в некоторых случаях, но мапперы в слое презентации свои.
Наконец-то подоспел ответ =)

 1. Бизнес-логика и модели данных. Знаете, я соглашусь с тем, что Бизнес-логика не должна ничего знать о моделях данных Даты-уровня и UI-уровня. Эти знания ей ни к чему. Плюс да, во всех источниках бизнес-логика представляется максимально изолированной от всех слоев. А тут я ее наоборот загружаю лишними данными и серьезно завязываю на конкретные модели. Поэтому Репозиторий должен предоставлять Интерактору уже готовые бизнес-модели, а Интерактор выдает ui уже обновленные, но тоже свои бизнес-модели, UI при необходимости мапит их.
 2. Место Репозитория. Я бы не стал относить Репозиторий чисто к бизнес-логике. Но это это и не Дата-уровень. По мне, Репозиторий - это надстройка над Датой, с которой непосредственно взаимодействует бизнес-логика. Именно Репозиторий решает, откуда брать данные и как.
 3. Обязанности Репозитория + вопросы кеширования. С осознанием того, что Бизнес-логика ничего не знает о моделях Даты, и что она получает уже готовые бизнес-модели от Репозитория, роль Репозитория несколько меняется. Теперь это не просто проводник запросов в сеть или БД. Теперь Репозиторий отвечает за маппинг данных, выбор источников данных, а также за кеширование. Интерактору выдается просто готовые модели. Раньше у меня Интерактор знал о моделях Даты и мог сам принимать решения, как кешировать. Но это не верно и не очень красиво.
Есть возражения, что если осуществлять еще и кеширование, то как-то много всего будет в Репозитории. Ну тут остается только посоветовать - делегируйте во вспомогательные классы. У Фернандо показан хороший пример делегирования через Фабрику и DataStore (в статье http://hannesdorfmann.com/android/evolution-of-the-repository-pattern, раздел Evolution of the Repository Pattern term). Там фабрика решает, какой DataStore задействовать для конкретного id.
Если для принятия решения о кешировании нужна информация с другого Репозитория, то пускай Интерактор передаст через аргумент метода нужную инфу в Репозиторий. Вообщем тут Интерактор отвечает за взаимодействием и необходимый обмен информацией между Репозиториями. Например у одного репозитория запросил, какой режим сейчас (пользовательский или демо), а в другой репозиторий передал эти данные для получения корректного списка операций.
modeRepository.getMode()
   .flatMap(mode -> operationsRepository.getOperations(mode))
 4. Исходя из вышесказанного Репозиторий должен тестироваться.
 5. Если вам нужно сделать приложение быстро, можно, конечно, не заморачиваться с маппингом, а передавать модель, полученную с запроса. Но если приложение чуть более серьезное и долгое, то лучше маппить. Так как по своему опыту, по Дате-уровне или по логике получения данных всегда что-то может поменяться. Бизнес-логика про это вообще не должна знать.
 6. Про проектирование. У меня в докладе показано проектирование снизу вверх. Но почитав источники Александра соглашусь, что проектирование сверху-вниз намного более привлекательней, да и позволяет быстро получить результат.


Один бы я не дошел до этого. Вот что значит коллективный разум! Еще раз спасибо Александру за отличный вопрос и очень развернутое свое мнение. Заставил меня несколько переосмыслить некоторые вещи.
источник

B

Beka in Android Architecture
источник

М

Михаил in Android Architecture
Такой вопрос. Есть проект, как в сказках про 3к строк кода в простой активити. Нужен рефактор и разделение на слои. Вопрос: с чего начать переезд?
источник

М

Михаил in Android Architecture
И вообще как спланировать такое?
источник