2

As I understand, when following the Low Coupling High Cohesion Principle, I should keep together the code that is related to same theme, splitting the code into modules/submodules by its "domain" or, in other words by what "topic" it is about, not by its "type".

  • E.g. it can be considered a bad idea to keep all interfaces together just because they're interfaces and keep all classes in other place. Or to keep all controllers in one place just because they're controllers, and all adapters in other. Etc.

  • A better option is to keep all code relating to shopping cart in one place, and all code related to goods in other. - So as they're are kinda modules. The Shopping cart folder will contain all code related to it: all controllers, adapters, entities, repositories etc - because they're all about the same thing.

On the other hand, a good clean architecture implies a clear division onto separate "layers", so that upper layers know nothing about lower ones.

  • first of all, there is a separate 'library' level - like web server, input-output, or data structures (e.g. map or deque) - they should "know" nothing about other layers.
  • then, at the top level there are some domain classes modelling domain entities and their relations, e.g. shopping cart and goods, maybe some business rules - they also "know" nothing about other layers,
  • next, there is some application logic, that describes the way in which your application allows to use those domain objects
  • and there is an infrastructure layer - the classes that use system layer and implement some interfaces required by upper layers.
  • finally, "on top of that all" (actually, at the bottom) - there is also a composition root level, which wires everything together, it may be familiar with every class and their dependencies and supplies them, maybe DI container, main() function etc.

It'd be cool if there'd be a way to highlight that e.g. all objects from one layer are somehow related and should use one layer but not use another.

- How to organize the code? What are best practices?

As a very simplified example - should it be like

- bookstore
    - customers
        - customer entity
        - customers repository interface
        - customers repository implementation
    - books
        - book entity
        - books repository interface
        - books repository implementation
        - book list view
        - book details view
        - amazon book adapter

or like

- domain
    - customers
        - customer entity
        - customer repository interface
    - books
        - book entity
        - books repository interface
- infrastructure
    - repositories
        - books repository implementation
        - customers repository implementation
- views
    - book list view
    - book details view
- adapters
    - amazon book adapter

But I'm not sure if this example illustrates the question well.

5
  • 2
    It is better to have views separated (like in the second example), since the views might not map 1:1 to domain objects. – JacquesB Dec 28 '20 at 21:38
  • yeah, i thought of this too - there could be multiple "skins". but in my practice, it's usually a single one. btw, applications also may be multiple. e.g. there may be at least some different interfaces: one with gui, one - as a web api, and one as a cli for example – whyer Dec 29 '20 at 2:47
  • 1
    If this is just about where to put your files, always put them where they are easy for you to find. – Robert Harvey Dec 29 '20 at 15:59
  • @RobertHarvey yeah, but is there a way to place files that highlights the architecture concepts and not messes the things up? otherwise it'd be difficult to keep in mind all those concepts, which, over time, will lead to breaking them :( – whyer Dec 29 '20 at 16:52
  • Your application will work properly no matter where you put your files. Put them where they are most convenient to you. My personal preference? Organize them around domains or departments. If your application isn't that large, then it doesn't matter where you put them. – Robert Harvey Dec 29 '20 at 16:58
4

If your goal is to keep related things together, here is an article of mine about packaging. In short:

  1. Packages should never depend on sub-packages.
  2. Sub-packages should never introduce new concepts, just more detail.
  3. Packages should reflect business concepts, not technical ones.

This is all derived from getting the structure to be readable, therefore maintainable.

If you sometimes feel this is at odds with "layering", that is no accident. A "layered" architecture inherently emphasizes technical details (like persistence, presentation, etc.), which is at odds with organizing using business concepts.

Here is another article of mine explaining why the layered architecture is a remnant of our procedural past and should be treated as such.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.