THE MISSING CHAPTER
---
Let’s imagine that we’re building an online book store, and one of the use cases we’ve been asked to implement is about customers being able to view the status of their orders.
---
## PACKAGE BY LAYER
----
The first, and perhaps simplest, design approach is the traditional horizontal layered architecture, where we separate our code based on what it does from a technical perspective.
----

----
* OrdersController
* OrdersService
* OrdersServiceImpl
* OrdersRepository
* JdbcOrdersRepository
----
* A good way to get started.
* Having three large buckets of code isn’t sufficient, and you will need to think about modularizing further.
* Doesn’t scream anything about the business domain
---
## PACKAGE BY FEATURE
----

----
- We have the same interfaces and classes as before, but they are all placed into a single Java package rather than being split among three packages.
- Another benefit is that it’s potentially easier to find
----
Both are suboptimal. If you’ve read this book so far, you might be thinking that we can do much better—and you’re right.
---
## PORTS AND ADAPTERS
----

----
You often see such code bases being composed of an “inside” (domain) and an “outside” (infrastructure)
----
- The “inside” region contains all of the domain concepts, whereas the “outside” region contains the interactions with the outside world
- UIs, databases, third-party integrations
----

----
- The major rule here is that the “outside” depends on the “inside”—never the other way around
- It’s missing things like interactors and objects to marshal the data across the dependency boundaries
- simplified version of UML
---
## PACKAGE BY COMPONENT
----
- Although I agree wholeheartedly with the discussions about SOLID, REP, CCP, and CRP and most of the advice in this book, I come to a slightly different conclusion about how to organize code.
----
- Package By Layer: interface needs to be marked as public
----
Newcomer
- Oh, there’s an OrdersRepository interface already built, too. I can simply dependency-inject the implementation into my controller. Perfect!”
----

----
What we need here is a guideline—an architectural principle—that says something like, “Web controllers should never access repositories directly.
* static analysis tools
* big ball of mud
----
- It’s a hybrid approach to everything we’ve seen so far, with the goal of bundling all of the responsibilities related to a single coarse-grained component into a single Java package
- Ports and adapters treat the web as just another delivery mechanism
----

----
### Definition of Component
1. business logic” and persistence code”
2. Components are the units of deployment.
3. A grouping of related functionality behind a nice clean interface”
----
A key benefit of the “package by component” approach is that if you’re writing code that needs to do something with orders, there’s just one place to go—the OrdersComponent
---
## THE DEVIL IS IN THE IMPLEMENTATION DETAILS
----
- public access modifier in languages
- encapsulation
---
## ORGANIZATION VERSUS ENCAPSULATION
- all types in your Java application public
- just like folders
- All four architectural approaches are exactly the same
----

----
They’re all identical regardless of which architectural approach you’re trying to adopt.
When you make all of the types public, what you really have are just four ways to describe a traditional horizontally layered architecture.
----
The access modifiers in Java are not perfect, but ignoring them is just asking for trouble.
----

----
### package by layer approach
The OrdersService and OrdersRepository interfaces need to be public
----
### package by feature approach
The OrdersController provides the sole entry point into the package, so everything else can be made package protected. **This may or may not be desirable.**
----
### Ports and adapters approach
The OrdersService and Orders interfaces have inbound dependencies from other packages, so they need to be made public.
----
### package by component approach
the OrdersComponent interface has an inbound dependency from the controller, but everything else can be made package protected.
----
The fewer public types you have, the smaller the number of potential dependencies.
I would certainly encourage you to lean on the compiler to enforce your architectural principles, rather than relying on self-discipline and post-compilation tooling
---
## OTHER DECOUPLING MODES
* Java 9,OSGi
* Decouple your dependencies at the source code level
----
* The source code for the business and domain OrdersService, OrdersServiceImpl, and Orders
* The source code for the web: OrdersController
* The source code for the data persistence: JdbcOrdersRepository
----
The latter two source code trees have a compile-time dependency
There are real-world performance, complexity, and maintenance issues associated with breaking up your source code in this way.
----
### A simpler approach
* Domain code
* Infra code
----
* Périphérique anti-pattern
* It’s potentially possible for infrastructure code in one area of your application (e.g., a web controller) to directly call code in another area of your application (e.g., a database repository), without navigating through the domain.
---
## Conclusion
* Destroyed in a flash if you don’t consider the intricacies of the implementation strategy.
* The devil is in the implementation details.
{"metaMigratedAt":"2023-06-15T17:48:09.293Z","metaMigratedFrom":"Content","title":"Untitled","breaks":true,"contributors":"[{\"id\":\"5525761c-1b39-465d-9c80-28d23b552681\",\"add\":8353,\"del\":2527}]"}