Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Indirect dependencies #11

Open
Dwite opened this issue Oct 23, 2017 · 5 comments
Open

Indirect dependencies #11

Dwite opened this issue Oct 23, 2017 · 5 comments

Comments

@Dwite
Copy link

Dwite commented Oct 23, 2017

Hello @hitherejoe ,

I have a question about dependencies. Currently, Remote module depends on Data, and Data module depends on Domain and because of that If we want to get information from Remote with Models that actually should be only in Remote we have to create a duplication of that model at each layer.

Example:
We have Remote module for the API that has method getRepositoryByPlatform(platform: Platform)
and our Platform is simple Enum class enum class Platform { IOS, ANDROID }
without duplication Platform class would be in Domain layer. But in this case if we need to specify @SerializedName for example, we would need to add Gson dependency to Domain layer, that looks incorrect from my point of view. And because of that creating Platform representation model at each layer looks like an overhead to me.

So the question is how do you handle such cases?

@erluxman
Copy link

erluxman commented Nov 2, 2017

I think this all about tradeoffs. The model duplication being done in this repo is not just because architecture restricts us from using certain Framework APIs or other logically separated APIs. It is also because a single module can treated as independent entity in some level. For example the person responsible for domain changes the "Platform" file and breaks the other modules in every place they use that Platform Enum. Rather than that Using the convention in this repo, it will only break the mapper function which can be fixed easily and specially at a single place in a single module rather than countless places where the "Platform" enums are being used. This will give more confidence to a programmer responsible for a module to bring changes. This makes the code less explosive even when it explodes when someone touches it. This is my understanding on this thing.

@Dwite
Copy link
Author

Dwite commented Nov 2, 2017

@erluxman , in this case, Remote->Data mapper is inside Remote repo, and that looks a bit strange

I mean the question is not in that each layer has own model, but how layers depend on each other

UI->Presentation->Domain<-Data<-Remote

@erluxman
Copy link

erluxman commented Nov 2, 2017

Yeah this has been one of my question too. I had made a issue in its original repo (not android architecture one). That confuses me too but the principle in itself is justifiable. I am also looking at the project and see if I can do something to make it more clear and concise.

@Dwite
Copy link
Author

Dwite commented Nov 2, 2017

@erluxman well, it looks a bit strange that we do a separate "independent" modules, that actually have 1:1 dependency to business logic, and if we would like to reuse "Remote" layer, it will have to add new Mapper for new "Data" layer, instead of "Data" writing mapper by itself and "Remote" being easily pluggable unit

@hitherejoe
Copy link
Collaborator

Hey @Dwite & @erluxman - the BufferooRemoteDataStore.kt in the data layer is not actually the implementation of the remote source, but more of an abstraction of this logic out of the BufferooDataRepository.kt class. This Remote source is just an example of a way to organise things, it is not necessarily needed to follow clean architecture, for example, you could communicate with the remote layer via the interface directly from the BufferooDataRepository. The Remote->Data mapper is inside of the Remote layer because of the directions in which the dependencies point - whilst this written out may look different from the clean architecture onion diagram, you can still separate these modules out into the diagram and it would represent a clean approach. IN my view, data should not know about the source modules (remote and cache) but instead, they should be injected in - which is how we have done it in this project. I feel this keeps the data layer unknown to outer sources. But with any projects, it is up to you how you structure things (whatever works best for you and your team :) )

Remote is still an easily pluggable unit at this point, the data layer only has an interface which is used by the remote layer - the data layer does not depend on the remote layer in any way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants