So there was some kerfuffle about layers last week. Let's break it down a little.
First, let’s talk about modules: modules exploit information hiding by putting implementation behind clause grained facade; it makes code easier to reason about, and reduces coupling to the details making change easier.
So what goes in a module? The key white paper is  Parnas,  https://www.win.tue.nl/~wstomv/edu/2ip30/references/criteria_for_modularization.pdf don’t use flow of control for modules, use single responsibility. We get improved cohesion through this, and reduce shotgun surgery. Don't create modules around flow of control.
Do I need modules? Not if you don't have sufficient complexity to make change difficult without them. If you don't need modules, then the rest that follows doesn't apply to you either.
If I do want modules, how do I manage a module's dependencies? Layers.
Layers do two things: they help prevent circular dependencies between modules, create a movement from coarser to a finer grain; from abstraction to detail; and they help us reason about the responsibilities of a group of modules that have a similar role.
Layers are not necessarily: Presentation->Domain->Infra. That is a common one, but lots of different layering strategies possible. DDD suggests layers within Domain for example. Entity layer vs. Application Workflow very common.
Do I need layers? Not if you have so few modules that you would not really see dependency concerns become an issue.
If I do want layers, why clean/ports&adapters/BCE? For example: https://alistair.cockburn.us/hexagonal-architecture/ Because a traditional layered architecture often has the details of the domain depend on infrastructure? These architectures have all the I/O on the outside and depend inwards.
Why is it undesirable for the domain to depend on the infrastructure?
First, it makes it easier to reason about the API of the domain and calls to it, if I don't have to worry about whether it is calling infrastructure.
Second, it makes it far easier to get under test if I don't have to worry about replacing I/O that may lead to shared fixture or slow test issues.
Third, it means my domain does not have any dependencies itself which makes it easier to re-use with new infrastructure or presentation and it doesn't get impacted by changes to the infra modules.
What about Dependency Inversion? If I need to depend on something in the layer above, instead of the concrete thing, I depend on a contract that specifies the thing (implicit of explicit) and the layer above provides me something that fulfils that contract.
Do I need an IoC container for that? Only if the web of dependencies is complex, otherwise you can just create instances and pass them down. You may need a 'composition root' to assemble all the parts of the graph you need to start that request.
And that is it, not the monster some would have you believe.
You can follow @ICooper.
Tip: mention @twtextapp on a Twitter thread with the keyword “unroll” to get a link to it.

Latest Threads Unrolled:

By continuing to use the site, you are consenting to the use of cookies as explained in our Cookie Policy to improve your experience.