Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Modular Architecture for Pragmatic Developers

Modular Architecture for Pragmatic Developers

Modularity and Domain Driven Design has never been on the focus of software development. We think that all these concepts can be implemented by Microservices. I believe we need to focus of some design fundamentals to boost modularity in our codebase again.

I cover the following topics for understanding the roots of modularity better:

* Layered Architecture
* Spaghetti Code / Lasagna Code / Ravioli Code
* Separation of Concerns
* Information Hiding
* Inversion of Control
* Dependency Injection
* Dependency Inversion
* Hexagonal Architecture
* Microservice Architecture
* Domain Driven Design

I delivered the deck at "DevNot's DDD and Microservices Conference" in Turkey.

Lemi Orhan Ergin

June 20, 2020
Tweet

More Decks by Lemi Orhan Ergin

Other Decks in Technology

Transcript

  1. MODULAR
    architecture
    for pragmatic developers
    lemi orhan ergin, co-founder of
    Deep Dive into Modular Architecture, Episode 1

    View Slide

  2. 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

    View Slide

  3. 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.

    View Slide

  4. presentation
    business
    persistance
    MAKE IT LAYERED

    View Slide

  5. 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

    View Slide

  6. View Slide

  7. Web
    Domain
    Persistence CONSIDERED
    HARMFUL
    Layered architecture

    View Slide

  8. 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

    View Slide

  9. 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

    View Slide

  10. 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

    View Slide

  11. 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.”

    View Slide

  12. Spaghetti code
    Multiple app entry points
    High cyclomatic complexity
    Too complex to maintain
    High coupling, low cohesion
    Lack of testing, hard to debug

    View Slide

  13. presentation
    business
    service
    application
    persistence
    third parties
    shared services
    Add more layers

    View Slide

  14. 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

    View Slide

  15. 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.

    View Slide

  16. 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"

    View Slide

  17. Split into micro services
    Microservice architecture is the
    defacto standard, right?

    View Slide

  18. A quick reminder...
    https://twitter.com/crichardson/status/1223888191272284160

    View Slide

  19. 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

    View Slide

  20. Welcome to
    small-sized and
    monolith-complex
    service jungle

    View Slide

  21. 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

    View Slide

  22. 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,

    View Slide

  23. If your so$ware is ge!ing harder and harder to develop,
    you are doing something wrong
    https://twitter.com/AjeyGore/status/1266402718140137473

    View Slide

  24. If your so$ware is ge!ing harder and harder to develop,
    you are doing something wrong
    https://twitter.com/davefarley77/status/1266846897093967874

    View Slide

  25. 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

    View Slide

  26. 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

    View Slide

  27. 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

    View Slide

  28. 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

    View Slide

  29. 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

    View Slide

  30. 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

    View Slide

  31. interface
    implementation
    INFORMATION HIDING
    DECOUPLING CONCERNS BY
    PRINCIPLE

    View Slide

  32. 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

    View Slide

  33. 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!

    View Slide

  34. 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

    View Slide

  35. 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

    View Slide

  36. 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

    View Slide

  37. 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

    View Slide

  38. 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

    View Slide

  39. cache
    interface
    cache
    implementation
    business
    object
    uses
    redis

    View Slide

  40. cache
    interface
    cache
    implementation
    business
    object
    uses
    repository
    interface
    repository
    implementation
    business
    object
    uses
    redis
    POSTGRES

    View Slide

  41. cache
    interface
    cache
    implementation
    business
    object
    uses
    repository
    interface
    repository
    implementation
    business
    object
    uses
    redis
    POSTGRES
    payment
    interface
    payment
    implementation
    business
    object

    View Slide

  42. 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

    View Slide

  43. 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

    View Slide

  44. 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

    View Slide

  45. 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

    View Slide

  46. 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:

    View Slide

  47. stay tuned...

    View Slide

  48. @lemiorhan
    LEMi ORHAN ERGiN
    stay tuned...

    View Slide