Accessing and Using entities of other features in Clean Architecture

592

Solution 1

The better question is, why would you seperate the domain layer over several features? In clean architecture the domain model is suggested to be one package at it self which has no dependencies to other packages.

Therefore you I would put the domain model into an own package and let the different features access it by their use cases.

Clean architecture by Uncle Bob

Solution 2

Contrary to what MartinPeek says, NOWHERE in the Clean Architecture book is it written that "the domain model is suggested to be one package". The popular clean architecture diagram is in no way a guide on how you should implement your application's directory structure. In fact, Uncle Bob has clearly stated that a 'Screaming' architecture will have its application use cases visible from the top. And in its last chapter called "The Missing Chapter" contributed by Simon Brown, he evaluates different ways of packaging and starts off with how packaging by layer violates Clean architecture rules.

When you implement packaging by layer your source directory will have different subdirectories such as domain/entities, use-cases, data-access-gateway/repositories, web-api, presenters, views, etc. which screams Clean Architecture, but not the intent of your system i.e. Healthcare Management Application, or Shopping Cart Service. And when you try to make a single change in a single feature, you'll have to consequently make changes across 4 different packages.

If you want to implement Clean architecture truthfully, then instead of dividing your packages according to horizontal layers, you should divide it vertically across the layers. You should have the application layer (domain entities and use cases) in the root directory itself. Each package should map to a domain in your business logic, this way all the use cases and entities that change for the same reason are packaged together, and all the use cases and entities that change for a different reason are segregated. That way, you'll end up with a directory structure like so: database, api, employee, wages, taxes. And without even giving you any hint you have a general idea of what this application might be about.

You can have data access layer, API, and UI related modules in their own separate packages inside the root directory as well, and have the use cases access them, OR you can even have them encapsulated inside the "vertical slice" itself, as Uncle Bob states:

If you decouple the elements of the system that change for different reasons, then you can continue to add new use cases without interfering with old ones. If you also group the UI and database in support of those use cases, so that each use case uses a different aspect of the UI and database, then adding new use cases will be unlikely to affect older ones.

But of course, that has its own pros and cons.

For further reading, I found this blog very helpful when I first started off: Explaining Clean Architecture

Coming to your question,

can I use entities of feature1 and feature2 in my main feature?

Entities are allowed to talk to each other, in fact its part of any business logic, but as we go higher up the layers from abstraction towards concretion, you should keep things more segregated. Again, when you make a change, you shouldn't need to change use cases that have nothing to do with that change. So I would suggest you to create a separate use case that accesses both entities, or create a separate entity that is an aggregate of feature1 and feature2 entities, and implement a new feature to access it. And then you can have your main feature use this newly created use case.

Share:
592
Ali Raghebi
Author by

Ali Raghebi

Updated on December 16, 2022

Comments

  • Ali Raghebi
    Ali Raghebi over 1 year

    I've created feature packages for every part of my application and my project structure looks like this :

    app
        core
        features
            main
                domain
                data
                ui
            feature1
                domain
                    entities
                        entity1
                        entity2
                    …
                data
                ui
            feature2
                domain
                    entities
                        entity1
                        entity2
                    …
                data
                ui
    

    My question is that can I use entities of feature1 and feature2 in my main feature? And if it is not correct way, Is there any better solution for this? Thank you all.

  • Ali Raghebi
    Ali Raghebi over 3 years
    Should I separate whole domain layer(including repository contracts and usecases)? Or only the entities?
  • MartinPeek
    MartinPeek over 3 years
    Only the Entities, UseCases would be another own layer often refered as application layer :)