MODULAR
architecture
for pragmatic developers
lemi orhan ergin, co-founder of
Deep Dive into Modular Architecture, Episode 1
Slide 2
Slide 2 text
LEMi ORHAN ERGiN
co-founder, Craftbase
founder, Software Craftsmanship Turkey
alumni, Sony, eBay, ACM, iyzico
programming, since 2001 with love
practitioner, modular design for years
speakerdeck.com/lemiorhan
@lemiorhan
Slide 3
Slide 3 text
We build webapps
webapp user
database
CRUD operations could be the most implemented feature in
software history. Whatever you aim to build, you will need your
data to be saved, updated, deleted and retrieved.
Slide 4
Slide 4 text
presentation
business
persistance
MAKE IT LAYERED
Slide 5
Slide 5 text
Layered architecture
Web
Domain
Persistence
From a certain layer, we can
only access components in the
same layer or in a layer below.
LAYERS OF Isolation
Slide 6
Slide 6 text
No content
Slide 7
Slide 7 text
Web
Domain
Persistence CONSIDERED
HARMFUL
Layered architecture
Slide 8
Slide 8 text
No way to understand what the code is about
Domain logic is sca!ered throughout the layers
Hard to understand where domain logic is
Layers encourage horizontal coupling
DDD do not work on partitioned architecture
Many uncategorized components
Slide 9
Slide 9 text
Your architectures should tell readers about the system,
not about the frameworks you used in your system.
SCREAMING ARCHITECTURE
https://blog.cleancoder.com/uncle-bob/2011/09/30/Screaming-Architecture.html
Screaming Architecture, Robert C. Martin
Slide 10
Slide 10 text
Web
Domain
Persistence
Architecture sinkhole anti-pa!ern
The fast lane reader anti-pa!ern
You have to be self-disciplined
Domain logic sca!ered throughout the layers
Database/state drives the design
Uncategorized helper and utility classes
Monolith in nature
Changing existing code instead of adding new
Hard to change over time
When it grows, it’s hard to test
Open for hacking your own code
Documentation is critical
The Inconvenient truth
Slide 11
Slide 11 text
Dependencies are out of control
Business and infra logic mixed
Lack of testing, hard to maintain
Information is duplicated or global
Any change triggers a ripple effect
Big ball of mud
defined in a paper released in 1997 by Brian Foote and Joseph Yoder
“A Big Ball of Mud is a haphazardly structured, sprawling,
sloppy, duct-tape-and-baling-wire, spaghetti-code jungle.”
Slide 12
Slide 12 text
Spaghetti code
Multiple app entry points
High cyclomatic complexity
Too complex to maintain
High coupling, low cohesion
Lack of testing, hard to debug
Slide 13
Slide 13 text
presentation
business
service
application
persistence
third parties
shared services
Add more layers
Slide 14
Slide 14 text
Order, Account, Image
Product, Restaurant, Matching
Payment, Scheduler, Invoice
Messaging, Balance, Location
and new integrations to
Ka#a, Redis, MongoDB, etc.
Add new flows & Features
Slide 15
Slide 15 text
Requests pass-through between each layers
Changes cause the ripple effect
Data mapped objects again and again
Lasagna/Baklava code A layered architecture becomes a lasagna when you push
yourself obey architectural standards. Better than spagetti, but
code smells continue.
Slide 16
Slide 16 text
we build monoliths "A monolith is an application with an over-engineered micro and
macro design but a completely under-engineered architecture"
Sandro Mancuso, from his talk "a case for outside-in design"
Slide 17
Slide 17 text
Split into micro services
Microservice architecture is the
defacto standard, right?
Slide 18
Slide 18 text
A quick reminder...
https://twitter.com/crichardson/status/1223888191272284160
Slide 19
Slide 19 text
ravioli code
Hands on Game Development Patterns with Unity 2019, David Baron
Ravioli code is the result of overzealous encapsulation and an
architecture that's divided into too many individual classes.
Bit size, independent components
seems good but over-use can cause
over-engineered, not understandable,
unreadable so$ware.
"Everything should be made as simple
as possible, but not simpler"
- Albert Einstein
Slide 20
Slide 20 text
Welcome to
small-sized and
monolith-complex
service jungle
Slide 21
Slide 21 text
Robert C. Martin
Author of Clean Code and Clean Coder
Owner of cleancoders.com training site
If your so$ware is ge!ing
harder and harder to develop,
you are doing something wrong
https://twitter.com/unclebobmartin/status/555013005751377920
Slide 22
Slide 22 text
If your so$ware is ge!ing harder and harder to develop,
you are doing something wrong
https://twitter.com/mob__mentality/status/1273982958831980546
partitioning,
Slide 23
Slide 23 text
If your so$ware is ge!ing harder and harder to develop,
you are doing something wrong
https://twitter.com/AjeyGore/status/1266402718140137473
Slide 24
Slide 24 text
If your so$ware is ge!ing harder and harder to develop,
you are doing something wrong
https://twitter.com/davefarley77/status/1266846897093967874
Slide 25
Slide 25 text
If your so$ware is ge!ing harder and harder to develop,
you are doing something wrong
a so!ware system must be decomposed into parts
that overlap in functionality as li"le as possible.
SEPARATION OF CONCERNS
make sure to not mix different dimensions, concepts together
a set of information that affects the
code of a computer program
PRINCIPLE
Slide 26
Slide 26 text
If your so$ware is ge!ing harder and harder to develop,
you are doing something wrong
Edsger W. Dijkstra coined the term to describe the
mentality behind modularization, which allows the
programmer to reduce the complexity of the system
being designed.
SEPARATION OF CONCERNS
PRINCIPLE
Slide 27
Slide 27 text
COUPLING COHESION
the strength of independence
connections between classes/modules
sense of belonging together
how we keep code on a unified purpose
SEPARATION OF CONCERNS
the main goal of design principles is to
improve the separation of concerns
PRINCIPLE
Slide 28
Slide 28 text
HIGH COUPLING
dependent to frameworks & technologies
components leak implementation details
hacking code to add new features
changing code starts riddle effect
hard to refactor
LOW COHESION
new features require many places to work
sca"ered knowledge cause complex tests
hard to understand the whole design
blurring responsibilities, long methods
hard to reuse
SEPARATION OF CONCERNS
PRINCIPLE
Slide 29
Slide 29 text
SEPARATION
OF CONCERNS
INFORMATION HIDING
INVERSION OF CONTROL
DEPENDENCY INJECTION
DEPENDENCY INVERSION
COUPLING
COHESION
wiring
direction
shape
isolation
responsibility
dependency
THE MODULARITY MINDSET
PRINCIPLE
PRINCIPLE
PATTERN
PRINCIPLE
Slide 30
Slide 30 text
INFORMATION HIDING
DECOUPLING CONCERNS BY
hiding the area of complexity (i.e implementation details and design decisions)
from the rest of the so!ware system through interfaces and private constraints
PRINCIPLE
Slide 31
Slide 31 text
interface
implementation
INFORMATION HIDING
DECOUPLING CONCERNS BY
PRINCIPLE
Slide 32
Slide 32 text
INVERSION OF CONTROL
refers to additional responsibilities a class can have,
other than its main responsibility, like object creation,
dependency binding and application flow
THE HOLYWOOD PRINCIPLE: DON’T CALL US, WE’LL CALL YOU!
PRINCIPLE
Slide 33
Slide 33 text
instead of driving the car by yourself you call a taxi and taxi driver drives the car
delegate control to someone
else who will drive the flow
PRINCIPLE
INVERSION OF CONTROL
THE HOLYWOOD PRINCIPLE: DON’T CALL US, WE’LL CALL YOU!
Slide 34
Slide 34 text
INVERSION OF CONTROL
Separate WHAT-TO-DO part from WHEN-TO-DO part
implementation
event-handlers
interfaces
event triggers
THE HOLYWOOD PRINCIPLE: DON’T CALL US, WE’LL CALL YOU!
dependency injection pa"ern
observer pa"ern
strategy pa"ern
callback pa"ern
Make someone DRIVES THE FLOW
PRINCIPLE
Slide 35
Slide 35 text
DEPENDENCY INJECTION
decouples the creation of an object from its use
configuration, construction of an object,
i.e. the creation of the object and handling
the dependencies of that object
objects should not be responsible for looking
up the resources or collaborators on which they
depend. IoC container does it for the objects.
can be implemented by constructor injection,
se"er injection or method injection
subtype of IoC, focusing on one aspect:
component assembly
PATTERN
Slide 36
Slide 36 text
abstractions should not depend on details
details should depend on abstractions
DEPENDENCY INVERSION
PRINCIPLE
high-level modules should not depend on low-level modules
both should depend on abstractions
business code integration code
interfaces implementation
we don't care how the behavior is implemented and
which implementation will be used
The D of SOLID Principles
MAKE THE BUSINESS INDEPENDENT OF EXTERNAL SYSTEMS
Slide 37
Slide 37 text
PRINCIPLE
cache
interface
cache
implementation
business
object
uses
domain, business code
code we really care about
changes o!en
integrations, infra code
write once and forget
hard to change
abstractions should not depend on details
details should depend on abstractions
DEPENDENCY INVERSION
high-level modules should not depend on low-level modules
both should depend on abstractions
HIGH LEVEL MODULE LOW LEVEL MODULE
Slide 38
Slide 38 text
PRINCIPLE
cache
interface
cache
implementation
business
object
uses
domain, business code
code we really care about
changes o!en
integrations, infra code
write once and forget
hard to change
abstractions should not depend on details
details should depend on abstractions
DEPENDENCY INVERSION
high-level modules should not depend on low-level modules
both should depend on abstractions
HIGH LEVEL MODULE LOW LEVEL MODULE
safe for
refactoring
safe for
refactoring
Slide 39
Slide 39 text
cache
interface
cache
implementation
business
object
uses
redis
Slide 40
Slide 40 text
cache
interface
cache
implementation
business
object
uses
repository
interface
repository
implementation
business
object
uses
redis
POSTGRES
Slide 41
Slide 41 text
cache
interface
cache
implementation
business
object
uses
repository
interface
repository
implementation
business
object
uses
redis
POSTGRES
payment
interface
payment
implementation
business
object
Slide 42
Slide 42 text
cache
interface
cache
implementation
business
object
uses
repository
interface
repository
implementation
business
object
uses
redis
POSTGRES
payment
interface
payment
implementation
business
object
business
object
queue
interface
queue
implementation RABBITMQ
Slide 43
Slide 43 text
cache
interface
cache
implementation
business
object
uses
repository
interface
repository
implementation
business
object
uses
redis
POSTGRES
payment
interface
payment
implementation
business
object
business
object
queue
interface
queue
implementation RABBITMQ
business
object
business
object
business
object
rest
controller
soap
controller
command-line
controller
uses
uses
uses
REQUEST
REQUEST
REQUEST
Slide 44
Slide 44 text
cache
interface
cache
implementation
business
object
uses
repository
interface
repository
implementation
business
object
uses
redis
POSTGRES
payment
interface
payment
implementation
business
object
business
object
queue
interface
queue
implementation RABBITMQ
business
object
business
object
business
object
rest
controller
soap
controller
command-line
controller
uses
uses
uses
REQUEST
REQUEST
REQUEST
infra
domain
application
Slide 45
Slide 45 text
cache
interface
cache
implementation
business
object
uses
repository
interface
repository
implementation
business
object
uses
redis
POSTGRES
payment
interface
payment
implementation
business
object
business
object
queue
interface
queue
implementation RABBITMQ
business
object
business
object
business
object
rest
controller
soap
controller
command-line
controller
uses
uses
uses
REQUEST
REQUEST
REQUEST
HEXAGONAL
ARCHTECTURE
Allow an application to equally be driven by
users, programs, automated test or batch scripts,
and to be developed and tested in isolation from
its eventual run-time devices and databases.
- Alistair Cockburn, 2005
Slide 46
Slide 46 text
cache
interface
cache
implementation
business
object
uses
repository
interface
repository
implementation
business
object
uses
redis
POSTGRES
payment
interface
payment
implementation
business
object
business
object
queue
interface
queue
implementation RABBITMQ
business
object
business
object
business
object
rest
controller
soap
controller
command-line
controller
uses
uses
uses
REQUEST
REQUEST
REQUEST
HEXAGONAL
ARCHTECTURE
puts the domain center of architecture
inverts dependencies towards domain code
design driven by business needs
ENABLER OF DDD: