Skip to content

Instantly share code, notes, and snippets.

@vicly
Last active January 22, 2021 01:43
Show Gist options
  • Save vicly/b7b57664943a3cb321b99a864f260e36 to your computer and use it in GitHub Desktop.
Save vicly/b7b57664943a3cb321b99a864f260e36 to your computer and use it in GitHub Desktop.
[Arch Note] #Arch

Onion

https://herbertograca.com/2017/09/21/onion-architecture/

Onion Archtecture

Hexagonal

https://herbertograca.com/2017/11/16/explicit-architecture-01-ddd-hexagonal-onion-clean-cqrs-how-i-put-it-all-together/

Hexagonal

Layered

Use just the layers we need, the tiers we need, and nothing more

Mid 90

Layered Architect

Early 20s

DDD

  • UI: translating the user’s inputs into application commands; user can be human or other applications
  • Application Layer: Orchestrates Domain objects to perform tasks required by the users. It does not contain business logic
  • Domain Layer: contains all business logic, the Entities, Events and any other object type that contains Business Logic
  • Infrastructure: The technical capabilities that support the layers above, ie. persistence or messaging.

Domain events**

  • run in memory, only for intra-domain communication, within the same transaction scope
  • raised from the domain entity class before transaction is committed

Integration events

  • cross transactions, to propagate state changes to other microservices
  • raised outside the domain entity class, after transaction is committed
  • can convert one or aggregate more domain events to Application Event

How to maintain consistency between microservices when failures happen

eventual consistency based on states.

In serviceX.updateX(X)

  1. Stage1
    1. Transaction 1 begins
    2. change entity in memory
    3. save entity X to DB
    4. save event E with state "ready to publish"
    5. Transaction 1 commits
  2. Stage2
    1. Transaction 2 begins
    2. EventBus.publish(E) remove call, might fail
    3. save event E with state "event already published"
    4. Transaction 2 commits
  • If Stage2.2 fails, background process will regularly handle "ready to publish"
  • It guarantee event published to EventBus at least once, you need to make sure the event carries enough information for the consumer to detect the duplicate and discard it.

Listener

react to only one event, have multiple method reacting to it, e.g.

class UserRegisteredEvent {}

class UserRegisteredEventListener {
  void notifyNewUserAboutHisAccount()
  void notifyAdminThatNewUserHasRegistered()
}

Subscriber

react to multiple events, have multiple method reacting to it.

An good example to manage transactions, RequestTransactionSubscriber reacting to events like RequestReceivedEvent, ResponseSentEvent and KernelExceptionEvent, and bind to them the start, commit and rollback of transactions, respectively, each in their own method like startTransaction(), finishTransaction() and rollbackTransaction().

Hexagonal

https://herbertograca.com/2017/11/16/explicit-architecture-01-ddd-hexagonal-onion-clean-cqrs-how-i-put-it-all-together/

Hexagonal

Packaged by component

Flow of control

Dependency direction

  • Tool
    • e.g. CLI Web server, RDB Server, Queue Server
    • CLI tells application to do something, and application tells DB engine to do something
  • Adapter
    • the code unit connects tool to core
    • NOT belong to business logic
    • Primary/Driving adapter: tell application to do something
      • Wrap around a port and translate input to a method call in application core
      • E.g. Adapter is a controller, and Ports can be a Service interface or a Repository interface required by the controller
    • Secondary/Driven adapter: told by application
      • Implement a port, injected into application core
  • Port
    • just a specification; nomrally implemented as interface
    • belong inside the business logic
    • created to fit the Application Core needs and not simply mimic the tools APIs.
  • Application Core organisation
    • Application Layer
      • define processes(user case) that can be triggered by UI
      • contains Application Services (and their interfaces) as first class citizens
      • also contains the Ports & Adapters interfaces (ports) include ORM interfaces, search engines interfaces, messaging interfaces and so on
      • also contains the triggering of Application Events, which represent some outcome of a use case
      • Application Service
        • use a repository to find one or several entities
        • tell those entities to do some domain logic
        • and use the repository to persist the entities again
    • Domain Layer
      • contain the data and the logic to manipulate that data, that is specific to the Domain itself, and it's independent of the business processes that trigger that logic, they are independent and completely unaware of the Application Layer.
      • Domain Service
        • handle domain logic involves more than one entities
        • know nothing about classes in application layer, e.g. application service, repository
        • can use other Domain Service, and Domain Model
    • Domain Model
      • In the very centre, depend on nothing
      • where Domain Event lives

Functional

Tech capability, not related to the domain, e.g. Layer, Factory, Repository, ViewModel, etc.

Conceptual

Business capability, related to the domain, e.g. User, Checkout

Package

Classes grouped together

Module

Funcational package, reflect tech capability, decoupled, can be swapped by another implementation, e.g. Security Model, ORM, or high level Client, Server.

Modules provide for Functional cohesion.

Component

Conceptual package, reflect business capability, decoupled, reflect bounded context,

Components provide for Conceptual cohesion

Application

the user-facing code, built on top of components, e.g.

shop UI for user to place order, another admin UI for shop admin to manage product, stock, etc., both built on top of same business components.

System

a set of applications work together, e.g. shopUI, adminUI, 3rd-party payment

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment