Skip to content

Instantly share code, notes, and snippets.

@JogoShugh
Last active April 24, 2024 13:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JogoShugh/267da018e39fd7c62aff50265d9ed019 to your computer and use it in GitHub Desktop.
Save JogoShugh/267da018e39fd7c62aff50265d9ed019 to your computer and use it in GitHub Desktop.
Learning Domain-Driven Design book notes
image
  • Storing only "current state" completely loses all business value of "how things got this way over time" (time traveling lost)
  • Think about showing how event-sourced projections do the same level of work that is traditionally done by complicated SQL queries and graph building from disparate data sources -- but when combined with read-models they do them ahead of query time so as to optimize the retrieval of such data when it's used.

Disadvantages

Learning curve

  • Different thinking
  • Requires training

Evolving the model

  • Immutability forces complication here
  • Greg Young wrote "Versioning in an Event Sourced System" boook on the subject

Architectual complexity

  • Introduces "moving parts" -- covered in CQRS chapter

Beware of these when deciding whether or not to use an event-sourced domain model. Simpler, "current state" based approaches may be sufficient in many scenarios. Chapter 10 gives rules of thumb.

FAQS

Performance of aggregate rehydration

  • Make sure to benchmark actual vs feared impact
  • Consider aggregate lifespan and number of events within this window
    • Fewer than 10k events is usually not a problem
    • Snapshot pattern can be introduced to mitigate
      • Cached representations of the aggregate's current state up to recent time period.
      • Note that this is how EventStoreDB works with projections (TODO: Link to CommitStream examples)

Enormous data generattion; does it scale?

  • Easy to shard all events for aggregates to specific nodes / stores

Deleting data for GDPR or other needs?

  • Apply forgettable payload pattern
    • Encrypt sensitive data with customer-specific key
    • Delete key when customer requests or other occurence dictates

Why Can't I Just Write Logs to a Text File and use it for Audit?

  • Error prone
  • Two-stage transaction, subject to rollback, partial failure

Why can't I keep using a current-state based model and just use logs to a logs table in DB tx?

  • Prone to engineer forgetting to apply consistency
  • Log table schema usually degrades into chaos

Why can't I just use DB triggers to take a snapshot to populate "history" tables?

  • Only includes dry facts
  • No capture of business intent or user intent at all
  • No ability for really projecting alternate reports of read models via "time travel"

Conclusion

  • Event-sourced domain model adds dimension of Time
  • All aggregate changes expressed as domain events
    • As opposed to simply changing a database row or document's "currentn state"
  • This gives ability to "time travel" for alternate reports and read models
  • Gives deep insight ability

Quiz attempt

  1. A
  2. C
  3. B -- B & C
  4. A

Covers tactical design decisions related to orchestrating interactions and dependencies between system components.

Bus Logic vs Arch Patterns

  • Easy for bus logic to get diffused amongst layers or duplicated
    • Causes chaos when changes are needed
  • Chosing correct arch pattern is crucial to properly support bus logic
  • Explored here:
    • Layered Arch
    • Ports & Adapters
    • CQRS

Layered Arch

  • Very common horizontal layering:
    • UI (or API)
    • Bus logic
    • Persistence
  • The classics:
    • PL
    • BLL
    • DAL

Presentation Layer

Can be:

  • GUI
  • CLI
  • API
  • Message broker subscriptions for ingesting external events
  • Message topics for outgoing event publication

Business Logic Layer

  • Encapsulates bus logic as described in Chaps 5 - 7
    • Eric Evans: the heart of software

Data Access Layer

  • Provides persistence
    • Originally, meant "the database"
    • Broader in modern world
  • NoSQL document dbs
    • Operational store
    • Search index for dynamic queries
    • in-memory db for perf-optimized queries
  • Includes:
    • Access to external systems
    • Cloud storage
    • etc

Communication Between Layers

  • Top-down where higher layers depend only upon next-lower-layer
    • Reduces coupling
    • However, it still forces many layers to change all at once for most changes

Variation

Service layer

  • Provides operations and coordinates app response for each
    • Commonly a Controller calls upon a Service and adapts the incoming params and outgoing response for its respective technological context
  • Acts as facade for BLL. Example:
image
  • All those methods are "business oriented", with no PL-specific leakage
  • Benefits
    • Can be reused in N PL contexts
      • Web UI
      • API
      • CLI
      • etc

Similar terminology

  • PL = UI layer
  • Service Layer = application layer
  • Business logic layer = domain layer = model layer
  • Data access layer = infra layer

When to use Layered Arch

  • Good for Transaction Script or Active Record
  • But, challenging for Domain Model pattern
    • Aggregates and Value Objects should have no dependency on infra

Optional: Layers Versus Tiers

  • Often confused with "N-Tier arch"
  • Layer is logical boundary
  • But, Tier is a physical boundary
  • Example:
image

Ports & Adapters

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