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

UserDataRepository breaks dependecy rules #65

Open
rohliq opened this issue Oct 30, 2015 · 7 comments
Open

UserDataRepository breaks dependecy rules #65

rohliq opened this issue Oct 30, 2015 · 7 comments

Comments

@rohliq
Copy link

rohliq commented Oct 30, 2015

Hi,

didn't UserDataRepository breaks dependency rules? Class is from data layer but implements userrepository interface which is from domain layer.

thanks
rohliq

@Trikke
Copy link

Trikke commented Nov 3, 2015

No it is correct. The implementation of the interface resides in the data layer, so that is correct. Because of the inwards dependency rule, a use case from the domain layer can know a UserDataRepository exists through an interface, but can not know (or shouldn't even care) what the concrete implementation is of that UserDataRepository ( be it disk, memory or network ). So the domain defines that a UserDataRepository exists, but it cannot know of the data layer and its implementation.

The reason you think it breaks dependency is because of the flow of control. Look at the following diagram

Image of Onion Structure
And this is the accompanying quote by Uncle Bob about crossing those boundaries

At the lower right of the diagram is an example of how we cross the circle boundaries. It shows the Controllers and Presenters communicating with the Use Cases in the next layer. Note the flow of control. It begins in the controller, moves through the use case, and then winds up executing in the presenter. Note also the source code dependencies. Each one of them points inwards towards the use cases.

We usually resolve this apparent contradiction by using the Dependency Inversion Principle. In a language like Java, for example, we would arrange interfaces and inheritance relationships such that the source code dependencies oppose the flow of control at just the right points across the boundary.

For example, consider that the use case needs to call the presenter. However, this call must not be direct because that would violate The Dependency Rule: No name in an outer circle can be mentioned by an inner circle. So we have the use case call an interface (Shown here as Use Case Output Port) in the inner circle, and have the presenter in the outer circle implement it.

The same technique is used to cross all the boundaries in the architectures. We take advantage of dynamic polymorphism to create source code dependencies that oppose the flow of control so that we can conform to The Dependency Rule no matter what direction the flow of control is going in.

I hope this explains things for you.

@android10
Copy link
Owner

@Trikke Kudos for such a great explanation!

@Trikke
Copy link

Trikke commented Nov 12, 2015

@android10 happy to help here. You got me interested in proper architecture on android and i've been digging deeper ever since. Seems natural to help a bit with all the questions!

@android10
Copy link
Owner

@Trikke good to hear! I really appreciate your help buddy.
Sometimes it gets hard to answer all the question and an extra couple of eyes/hands are super useful :)

@rohliq
Copy link
Author

rohliq commented Nov 12, 2015

thanks guys

2015-11-12 13:37 GMT+01:00 Fernando Cejas notifications@github.com:

@Trikke https://github.com/Trikke good to hear! I really appreciate
your help buddy.
Sometimes it gets hard to answer all the question and an extra couple of
eyes/hands are super useful :)


Reply to this email directly or view it on GitHub
#65 (comment)
.

@ildar2
Copy link

ildar2 commented Feb 18, 2016

UseCase output port Interface should be placed in the same UseCase layer, according to the diagram. But the question was about data layer output Interface (UserRepository) being placed in UseCase, which is domain layer.

No name in an outer circle can be mentioned by an inner circle.

But the name 'UserRepository' of outside circle (domain) is mentioned by data - the inner circle.
This is imo indeed a case of breaking dependency rule

@android10
Copy link
Owner

@ildar2 data is not the inner circle. it does not solve your problem (only provides data), domain layer does and it is where your logic sits. There is no dependency rule break up. 😄

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

No branches or pull requests

4 participants