At the core of every successful software application lies good design. It's what makes apps user-friendly, systems reliable, projects manageable, and the work enjoyable. In this keynote, I delve into why design holds such significance in software, dissecting the essential principles of effective design and showcasing real-world examples of its impact.
SaaStr Workshop Wednesday w/ Lucas Price, Yardstick
Keynote about Software Design Principles and Patterns
1. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
Head of Enterprise Application and
Architecture Design
Giovanni Costagliola
Email: giovanni.costagliola@nexusat.it
LinkedIn: @giovannicostagliola
GitHub: @mrbogomips
@bogoware
2. GIOVANNI COSTAGLIOLA — (C) 2024
A Pragmatic Journey in the Enterprise Application Making
DesignPatternsandPractices
16. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
Enterprise Applications are about the display, manipulation,
and storage of large amounts of often complex data and the
support or automation of business processes with that data.
— Martin Fowler (2002), Patterns of Enterprise Architecture
• Examples of Enterprise Applications (from Wikipedia):
• order processing,
• procurement,
• production scheduling,
• customer information management,
• hr management,
• accounting
EnterpriseApplication
17. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
Software Architecture refers to the high-level structure
of a software system and the discipline of creating such
structures and systems. It encompasses both static
aspects (components, modules, …) that dynamic aspects.
«The purpose of a Software Architecture is to facilitate development, deployment, operation, and
maintenance of the software system contained within it.
[…] the architecture of a system has very little bearing on whether that system works.»
— Robert C. Martin (2018), Clean Architecture
SoftwareArchitecture
19. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
• A complex system that works is invariably found to have evolved from a simple system that
worked.
• A complex system designed from scratch never works and cannot be patched up to make it
work.
• You have to start over with a working simple system.
— John Gall (1975), Systemantics: How Systems Really Work and How They Fail, p. 71
Gall’sLaw
20. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
• Deliver working software frequently, from a couple of weeks to a couple of months, with a
preference to the shorter timescale.
• Working software is the primary measure of progress.
• Simplicity — the art of maximizing the amount of work not done — is essential.
— https://agilemanifesto.org/
AgileManifesto
21. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
The Domain
Problem Space
• The Land of “What”
• The owner is the Domain Expert, the
Customer
• It’s typically very dynamic and in
continuous evolution
• Often it’s not clear either to the
“Experts”
22. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
The Analysis Model
Problem Definition
• The Land of “Understanding”
• Where “Requirements” are defined
• Co-owned by the Domain Experts and
the Developers (Designer is a Developer)
• Where strategic DDD comes in place
• Ubiquitous Language
• Bounded Contexts
23. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
The Design Model
Solution Space
• The land of “How”
• Owned by Developers (Architects and
Designers are Developers too)
• Understood by the Domain Expert
• Where tactical DDD comes in place:
• Aggregates, Entities, Domain Events,
Value Objects, Policies, Commands,
Queries, Repositories, …
24. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
Constraints
The Design Dimensions
• The Scope Scale (the Domain)
• Architectural Level
• The Domain Level (Core vs. Subdomains)
• The Component Level
• The Time Scale (the Scheduling)
• The Sprint
• The Epic
• The App Life-Cycle
• The Resources Scale
• Infrastructure and Tooling
• People
• Budget
26. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
Ifthereisaproblemyoucan’tsolve,
thenthereisaneasierproblemyoucansolve:
findit!
— G Pólya (1945), How to Solve It
28. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
ComplexvsComplicated
Complex
Complicated
Easy Simple
PROBLEM SPACE SOLUTION SPACE
29. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
ComplexvsComplicated
Complex
Complicated
Easy Simple
DOMAIN DESIGN
30. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
• A domain that involves numerous elements and behaviours is complex
• The solution to a problem could be complicated to understand
• The complexity is inherent to the nature of the problem and it is not under control
• The complication is inherent to the solution and can be simplified introducing new
abstractions
• A strategic approach is essential to dominate a complex domain
• The design of a complex domain passes through many layers of abstractions
ComplexvsComplicated
34. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
• Effectiveness: must achieve the desired outcome and solve the problem it was intended to
address
• Feasibility: should be practical and feasible to implement within the constraints of the situation,
including available resources, time, and technical capabilities
• Acceptability: stakeholders should find it acceptable and be willing to adopt or support it
• Efficiency: an adequate solution should use resources optimally
• Sustainability: can be maintained and sustained over time without significant degradation in
performance or effectiveness
• Adaptability: should be flexible and adaptable to changes, it should be easy to evolve the system
Solution’sRequirements
38. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
DesignPrinciplesareguidelinesthat
aidtoshapethestructureandthe
architectureofyoursystem.
39. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
Organizationswhichdesignsystemsare
constrainedtoproducedesignswhicharecopiesof
thecommunicationstructuresofthese
organizations.
— Conway’s Law
40. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
SOLID is a set of five principles selected by Robert C. Martin (Uncle Bob) for writing maintainable
and scalable Objected-Oriented software.
• Single Responsibility Principle (SRP)
• Open-Closed Principle (OCP) credited to Bertrand Meyer (1980)
• Liskov Substitution Principle (LSP) credited to Barbara Liskov (1988)
• Interface Segregation Principle (ISP)
• Dependency Inversion Principle (DIP)
— Robert Martin (2000), Design Principles and Design Patterns
SOLIDPrinciples
41. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
A module should be responsible to one, and only one, actor.
Implications:
• A class should have only one reason to change
• Gather together the things that change for the same reason. Separate those things that change for
different reasons.
SingleResponsibilityPrinciple(SRP)
42. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
Single
Responsibility
Principle
(SRP)
Bad Practice
43. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
Single
Responsibility
Principle
(SRP)
Good Practice
44. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
Software entities (classes, modules, functions, etc.) should
be open for extension, but closed for modification
Implications:
• You should be able to extend the behaviour of your system without modifying your existing code
Open-ClosedPrinciple(OCP)
45. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
Open-Closed
Principle
(OCP)
Scenario
User can choose between two different formats.
Potentially many other formats will beadded to the system.
ORDER REPORT PAGE
FORMATS
CSV HTML
46. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
Open-Closed
Principle
(OCP)
Bad Practice
47. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
Good Practice
Open-Closed
Principle
(OCP)
48. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
LiskovSubstitutionPrinciple
Barbara Liskov
LSP
49. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
LiskovSubstitutionPrinciple(LSP)
Where:
• S is a subtype of T
• is a property
That statement says that S can be substitute to T if:
1. S is a subtype of T
2. S is “undistinguishable” from T: all the properties that hold for
T hold for S too
ϕ
S ≤ T → ∀x : T . ϕ(x) → ∀y : S . ϕ(y)
Barbara Liskov
50. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
Objects of a superclass should be
replaceable with objects of a
subclass without affecting the
correctness of the program
Implications:
• a subclass should be able to substitute its parent class
without altering the behaviour of the program
LiskovSubstitutionPrinciple(LSP)
51. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
It’s subclassing on steroids!
Not only a structural subtyping,
But a behavioural subtyping
LiskovSubstitutionPrinciple(LSP)
52. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
Implications:
• Subtype method’s params should be contravariant
• Subtype method’s return values should be covariant
• Subtype can throw exceptions that are subtypes of those thrown by Supertype
• Subtype cannot have stronger preconditions
• Subtype cannot have weaker postconditions
• Subtype cannot have weaker invariants
• Subtype cannot support state changes unsupported by Supertype
LiskovSubstitutionPrinciple(LSP)
53. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
LiskovSubstitution
Principle(LSP)
Subtype method’s params
should be contravariant
54. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
LiskovSubstitutionPrinciple(LSP)
Shapes
Rectangles
Squares
55. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
LiskovSubstitutionPrinciple(LSP)
Shapes
Rectangles
Squares
56. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
LiskovSubstitutionPrinciple(LSP)
Shapes
Rectangles
Squares
S ≤ T → ∀x : T . ϕ(x) → ∀y : S . ϕ(y)
57. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
LiskovSubstitutionPrinciple(LSP)
Shapes
Rectangles
Squares
ϕ= Sides can have different lengths
ϕ
ϕ
58. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
LiskovSubstitutionPrinciple(LSP)
59. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
Clients should not be forced to depend on interface that
they not use.
Implications:
• Split large interfaces of unrelated operations on specific interfaces tailored to coherent
concerns
• Reduce the dependency surface area to prevent future issues
InterfaceSegregationPrinciple(ISP)
60. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
InterfaceSegregationPrinciple(ISP)
61. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
• High-level modules should not depend on low-level
modules. Both should depend on abstractions.
• Abstractions should not depend on details. Details should
depend on abstractions.
Implications:
• easier substitution of components
• facilitates testing
• promotes flexibility and extensibility in software systems
DependencyInversionPrinciple(DIP)
62. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
Dependency
Inversion
Principle
(DIP)
63. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
• Avoid (true) duplication
• True duplication vs accidental duplication
• The revealing question is: «Does the two things MUST change together?»
• YES implies true duplication
• NO implies accidental duplication
• Business Logic Duplication vs Implementation Duplication
• Avoid Business Logic Duplication via Strategy Pattern (aka Policy Pattern)
• Avoid Implementation Duplication via Code Factorization
DRY(Don’tRepeatYourself)
64. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
• UI: the forms for the Customer and those for the Supplier are identical
• Accidental Duplication, they will naturally change independently, duplication is safe
• Implement two forms where initial code is cut and pasted with minimal or no changes
• BIZ: Managers and Employees have different segregation rules over Projects entities and they must be applied in
different use cases
• True Biz Logic Duplication, the rules must change accordingly, duplication is unsafe
• Introduce the Strategy Pattern to manage the rules and their consistent application across the components
• CODE: the fiscal identifier (i.e. CodiceFiscale) is used in many places of the code
• True Implementation Duplication, the algorithms are the same, duplication is unsafe
• Refactor your code introducing a ValueObject that encapsulate the logic
DRY–Examples
65. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
DRY–Examples
Hey Giò…
tieniti forte!
Andrea Milano
66. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
DRY–Examples
Hey Giò…
tieniti forte!
Andrea Milano
69. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
DesignPatternsareprovensolutions
torecurrentproblems
70. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
• Their definitions includes a context and a problem statement that
includes often forces and constraints
• They are classified by the scale of applicability and the area of pertinence
• Scale: Architectural Design Patterns vs Software Design Patterns
• Area: Messaging Patterns (Architectural) vs Creational Patterns
(Software)
• Examples: Broker, Pub/Sub, Saga (Messaging Patterns) vs Singleton,
Factory, Builder (Creational Patterns)
DesignPatterns
71. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
Object-Oriented
Design
Patterns
73. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
Architectural
Design
Patterns
74. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
• Monolithic Architecture refers to an application built as a
single, tightly integrated unit.
• All components and features of the application are
interconnected and interdependent.
• The entire codebase is typically deployed and scaled as a
single unit.
MonolithicArchitecture
75. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
• Microservices Architecture is an approach to designing
and building software applications as a collection of small,
independent, and loosely coupled services.
• In a microservices architecture, each service represents
a self-contained unit that encapsulates a specific
business capability.
• These services communicate with each other through
well-defined APIs, often over a network.
MicroserviceArchitecture
76. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
MonolithvsMicroservices
Single
Deployment
Tier
77. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
Monolithic Architecture Microservice Architecture
Architecture Style Single-tier architecture
Multi-tier architecture with independent, loosely
coupled services
Deployment Deployed as a single unit Each microservice can be deployed independently
Scalability Scaled as a whole application Can scale individual microservices based on demand
Development Centralized development Decentralized development with independent teams
Technology Stack Homogeneous stack Heterogeneous stack
Communication In-process communication Inter-process communication through APIs and protocols
Fault Isolation A failure in one module can impact the entire system Failures are isolated to individual microservices
Flexibility and Agility Limited flexibility due to the monolithic structure Offers greater flexibility, agility, and ease of updates
Dependencies Tight coupling between modules Loosely coupled services, minimizing dependencies
Scaling Resources Resources scale uniformly Resources can be allocated based on specific service
needs
Complexity Simpler structure and deployment Complex architecture due to distributed nature
Testing Comprehensive system testing required Easier unit testing and independent testing of
microservices
Data Management Centralized database Each microservice have its own database
Ownership and Accountability Centralized ownership and accountability Decentralized ownershi: each microservice has its
owner
Cost and Resource Usage Efficient resource utilization More complex resource management, potential duplication
Infrastructure Dependency Dependent on the overall infrastructure
Individual microservices can leverage different
infrastructures
Communication Overhead Minimal communication overhead within the
application
Overhead introduced by inter-service communication
Scaling Development Teams Limited scalability of development teams Easier scalability with independent teams
78. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
• N-Tier
• Event-Driven / Reactive
• Big Data / Big Compute
• SOA
• CQRS
• P2P
• Serverless
• Event Sourcing
• Saga
• Choreography
• …
OtherArchitecturalPatternsAndStyles
80. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
LayeredArchitecture
PRESENTATION
DOMAIN
DATA SOURCE
— Martin Fowler (2003), Patterns of Enterprise Application Architecture
81. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
LayeredArchitecture
PRESENTATION
DOMAIN
DATA SOURCE
— Martin Fowler (2003), Patterns of Enterprise Application Architecture
82. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
LayeredArchitecture
PRESENTATION (GUI, WEB API, …)
DOMAIN (BUSINESS LOGIC)
DATA (DB, FILE SYSTEM, …)
Source Code Dependency
Runtime Dependency
83. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
LayeredArchitecture
PRESENTATION (GUI, WEB API, …)
DOMAIN (BUSINESS LOGIC)
DATA (DB, FILE SYSTEM, …)
Source Code Dependency
Runtime Dependency
84. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
LayeredArchitecture
PRESENTATION (GUI, WEB API, …)
DOMAIN (BUSINESS LOGIC)
DATA (DB, FILE SYSTEM, …)
Source Code Dependency
Runtime Dependency
85. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
LayeredArchitecture
PRESENTATION (GUI, WEB API, …)
DOMAIN (BUSINESS LOGIC)
DATA (DB, FILE SYSTEM, …)
Source Code Dependency
Runtime Dependency
86. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
Domain
LayeredArchitecture
PRESENTATION (GUI, WEB API, …)
USE CASES (COMMANDS, QUERIES, POLICIES)
DATA (DB, FILE SYSTEM, …)
Source Code Dependency
Runtime Dependency
CORE LOGIC (ENTITIES, VALUE OBJECTS, CORE ALGORITHMS)
87. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
Domain
LayeredArchitecture
PRESENTATION (GUI, WEB API, …)
USE CASES (COMMANDS, QUERIES, POLICIES)
DATA (DB, FILE SYSTEM, …)
Source Code Dependency
Runtime Dependency
CORE LOGIC (ENTITIES, VALUE OBJECTS, CORE ALGORITHMS)
ABSTRACTIONS
ADAPTERS ADAPTERS
IMPLEMENTATIONS IMPLEMENTATIONS
88. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
TheCleanArchitecture
— Robert C. Martin (2018), Clean Architecture
89. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
An Enterprise Application must support
• The use cases: providing with the features required by the business
• The operation: supporting the workload required by the business
• The maintenance: simplifying the bug fixing and the testability
• The development: enabling and sustaining the evolution of the system
• The deployment: allowing concurrent teams to work productively together
• Must be: effective, understandable, enjoyable, cost-effective
GoodQualitiesofanEnterpriseApp
90. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
A Good Enterprise Application Architecture should
be:
• Independent from Frameworks and Tools
• Testable: The business rules can be tested
without the infrastructure services available
• Independent from Ports and Gateways
• Independent of UI: Web, Mobile, Rest API, …
• Independent of DB: MySQL, SQLServer,
Oracle,… Mongo, Redis,
• Independent of any External Agency/System:
Payment Gateway, Invoicing Service, Logistic,
…
GoodQualitiesofanEnterpriseApp
92. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
TransactionScriptvsDDD(DomainLogicPatterns)
Transaction Script Domain Model
Definition
Organizes business logic by procedures where
each procedure handles a single request from the
presentation.
An object model of the domain that
incorporates both behavior and data.
Simplicity High Moderate to High
Scalability Limited High
Code Duplication Possible, mitigated via DRY Addressed via Domain Objects
Abstraction Limited High
Adaptability Limited High
Learning Curve Low Moderate to High
Time and Resources Low Moderate to High
93. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
TransactionScriptSample
Command Handler (CQRS)
Token Service
Issue new Token
94. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
DDDSample
Command Handler (CQRS) Lead Aggregate
Lead Management Service
Assign Lead
102. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
Strategic Patterns
• Ubiquitous Language, Core Domain, Generic Subdomains, Bounded Context, Context
Map, Shared Kernel, Customer/Supplier, Conformist, Open Host Service, Published Language,
Separate Ways, Anti-Corruption Layer, Big Ball of Mud, Continuous Integration
Tactical Patterns
• Model-Driven Design, Layered Architecture, Domain Services, Entities, Value Objects,
Aggregates, Domain Events, Repositories, Factories
Domain-DrivenDesignPatterns
103. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
• A shared vocabulary and set of terms specific for a Bounded Context that is understood
and consistently used by both domain experts and developers throughout the software
development process in a specific
• It accurately reflects the concepts and language of the problem domain, promoting
effective communication, shared understanding, and alignment between stakeholders and
technical teams.
• The language should be used consistently in every form of communications and in the
implementation
• The language is a valuable asset of the solution
UbiquitousLanguage
104. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
• A large Domain can be decomposed into independent Subdomains
• Subdomains are classified in:
• Core: where competitive advantage lies, the business core.
• Supporting: provides features required by the core domain to operate.
• Generic: common functionalities that are shared among different domains and have well-
established solutions
DomainandSubdomains
105. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
DomainsandSubdomains
WineShop (E-Commerce)
DOMAIN
PRODUCT MANAGEMENT
AND SALES
Core
TICKETING
Generic
CATALOG
BILLING
LOGISTICS
TOKEN SERVICE
ACCOUNTS
Supporting
107. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
• Explicitly define the context within which a model applies.
• Set clear boundaries in terms of team organization, usage within specific parts of the
application, and physical manifestations such as code bases and database schemas.
Implications:
• A BC has its own Ubiquitous Language. Terms and meanings are not related to other Contexts
• A BC is also a tool to organise the work in case of large domains
• Bus fits naturally in an Microservice Architecture
• BCs lie in the Solution Space, while Domains lie in Problem Space
BoundedContext
108. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
Bounded
Contexts
and
Subdomains
— V. Vernon (2013), Implementing DDD
109. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
In Model-Driven Design the Analysis and Design Models
should be very cohesive and the Ubiquitous Language
should be the glue
Analysis Model focuses on understanding the requirements and capturing the essence of the Domain
Initial stages, capturing the requirements, use-cases and high level diagrams
Design Model focuses on the solution, translating requirements into design decisions and implementation details
After analysis, defining the solution, UML diagrams (classes, packages, sequence, deploy, …)
Model-DrivenDesign
110. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
• Value Objects represent elements of the domain
without a proper identity
• They are immutable: i.e. once created they cannot be
altered
• They support equality by value: i.e. two instances that
have same value are considered equal
• Examples: Colour, Currency, Height, FiscalCode, IBAN,
UnitOfMeasure, etc.
• They encapsulate the most fundamental algorithms of
the domain
ValueObject
111. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
• Entities represent elements of the domain with a
proper identity and lifecycle
• They are identified by an Id: i.e. two entities with same
attributes but two different ids are not the same
• They support equality by Id: i.e. two entities are equal
iff they fave the same id
• Example: Order, Customer, Employee, etc.
• They are used to give structure to the Domain and use
Value Objects and Entities to accomplish the goal
Entity
112. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
Tobe,ornottobe,thatisthequestion
113. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
QuizTime–RecognizeVOvsE
Banknote Money
Employee EmployeeId
Location Address
Weight
114. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
QuizTime–RecognizeVOvsE
Banknote Money
Employee EmployeeId
Location Address
Weight
115. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
QuizTime–RecognizeVOvsE
Banknote Money
Employee EmployeeId
Location Address
Weight
116. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
• An Aggregate is a graph of Entities conceptually
related
• It is a Unit of Logic Consistence: i.e. a context to
define and apply invariants among participants
• It is a Unit of Transactional Integrity: an
aggregate MUST be persisted atomically
• It is a Unit of Deploy: an aggregate cannot be split
among logic or physical layer
• An aggregate is manipulated only via a designated
entity called Aggregate Root that is responsible to
hide the internals and honour all the invariants
Aggregate
119. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
Repository
• Abstract and encapsulate the logic for persisting and
retrieving domain objects from a data source. It serves
as an intermediary between the domain model and the
data access layer
• Implications:
• Provided all data access logic is very localized it will
simplify the maintenance and the evolution of the DAL
• They tipically work in conjunction with UoW
• Cautions:
• Repositories SHOULD NOT break the Aggregate
Integrity
• Repositories are not Reporting Queries see CQRS
• Attention when used with the Specification Pattern
120. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
• It represents a meaningful and observable fact that has happened within the system
• Are used to capture and communicate important domain-specific activities or outcomes,
allowing different parts of the system to react or respond accordingly
Implications
• Can be used to implement in-memory inter-aggregate communication
• Some designers advocate to use them also as Integration Events… IMHO it depends
• In an Event Sourcing Architecture they represents the state changes tracked by the domains
DomainEvent
121. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
• Domain Services encapsulate logic or behaviour that doesn't naturally fit within the boundaries of a
single domain object
• They often represent complex operations or workflows that involve multiple entities
• Examples:
• PaymentService: Responsible for processing payments and handling payment-related logic, such
as verifying payment methods, authorizing transactions, and updating payment statuses.
• AuthenticationService: Manages user authentication and authorization processes, including
verifying user credentials, generating access tokens, and enforcing security policies.
• InventoryService: Handles inventory management operations, such as tracking stock levels,
reserving or releasing inventory, and updating product availability
DomainService
122. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
• CQRS is a design pattern that segregates the responsibility of handling commands (write
operations) from queries (read operations) in a software system.
• Write operations and Read operations are in different modules, and are essentially independent
Implications
• It promotes a clearer separation of concerns
• Allows for different models, data stores, and optimization techniques
CommandQueryResponsibilitySegregation
123. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
CQRS
UI
User
COMMAND ORM / EF
QUERY SQL / DAPPER
Repositories
124. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
CQRS
UI
User
COMMAND ORM / EF
QUERY ELASTIC API
Repositories
Projections
Eventual Consistency
126. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
• Structured programming is a programming paradigm aimed at improving the clarity, quality,
and development time of a computer program
• Goto Statements Considered Harmful (E.W. Dijkstra, 1968)
• «Flowcharts can compute any computable function» Böhm-Jacopini Theorem
StructuredProgramming
127. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
• Object-oriented programming (OOP) is a programming paradigm that organizes software
design around objects, rather than functions or procedures
• Key principles are encapsulation, inheritance, and polymorphism
• OOP enables developers to model real-world entities as objects, facilitating the creation of
modular, maintainable, and scalable software systems
Object-OrientedProgramming
128. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
• Functional programming is a programming paradigm that treats computation as the evaluation
of mathematical functions
• Mathematical functions are pure: FP avoids changing-state and mutable data
• Key principles are Pure Functions, Immutability, Higher-Order-Functions, Recursion,
Referential Transparency
• FP fits well with Event Sourcing
• FP provides patterns like Functors and Monads that abstract away control flow and enable
elegant pipeline-style coding
FunctionalProgramming
129. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
• Functors and Monads are Functional Programming Design
Patterns
• A Functor allows one to apply a function to values inside
a generic type without changing the structure of the generic
type (usually via Map(…))
• A Monad allow to restrict the access to the value based on
specific semanthic (usually via Bind(…)). Two typical monads
are:
• Maybe<T> (aka Option): encapsulate optional result
• Result<T> (aka Either): encapsulate fallible result
FunctorsandMonadsFPPatterns
A Tree acting as a Functor
Null
If (ok) {} else {}
If (exist) {} else {}
130. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
FunctorsandMonadsFPPatterns
C# Conceptual Code. For a real implementation you could
refer to: Bogoware.Monads (GitHub, NuGet)
131. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
Monadsand
Processing
Abstractions
132. GOOD DESIGN MATTERS — (C) 2024 GIOVANNI COSTAGLIOLA
Monadsand
Processing
Abstractions
Bogoware.Monads (GitHub, NuGet)