6

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
  • 205
  • 2
  • 6

3 Answers3

4

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.

Mythos
  • 1,378
  • 1
  • 8
  • 21
0
example -- This is bounded context,as a solution to your problem domain.
├── application -- This is use case,your user story will be reflected here.
├── domain -- This is domain,your business logic will be implemented here.
│   ├── model -- This is the business entity.
│   │   ├── feature1 
│   │   └── feature2
│   ├── service -- This is domain service.
│   └── repository -- This is repository interface.
└── infrastructure
    ├── remote -- Implementation of any call use case.
    │   ├── contorller
    │   └── listener
    └── repository -- Repository implementation.

Regarding your question, you can refer to the aggregate design of DDD for the entity part.

1..n entities and 0..n value objects are combined into an aggregate, and the outermost entity is the aggregate root.

The interaction logic between aggregates is implemented through domain services.

Every aggregation is cohesive, don't make aggregations depend on each other, otherwise there will be strong coupling, the responsibility is no longer single and it is difficult to test.

domain does not depend on the other two packages.

application depend on domain but not depend on infrastructure.

infrastructure.remote depend on application,this is use case entrance.

infrastructure.repository implement domain.repository.

infrastructure.remote and infrastructure.repository never depend on each other.

Guidance and communication are welcome, and you can reply me if you have any questions.

The English above is translated by Google, please understand some wording problems.

-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

MartinPeek
  • 22
  • 3