Domain-Driven Design with Golang読書メモ

1 A Brief History of Domain-Driven Design
Three pillars of DDD
Ubiquitous language
Strategic design
Tactical design
Adoption of DDD
When should you use DDD?
scorecardを例示
Further reading
Design a DDD-oriented microservice by Microsoft (2022); available at https://docs.microsoft.com/en-us/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/ddd-oriented-microservice
Find Your Business Domains to Start Refactoring Monolithic Applications by Amazon Web Services (AWS) (2022); available at https://aws.amazon.com/blogs/mt/find-your-business-domains-to-start-refactoring-monolithic-applications/
Apply Domain-Driven Design to microservices architecture by IBM; available at https://www.ibm.com/garage/method/practices/code/domain-driven-design/

2 Understanding Domains, Ubiquitous Language, and Bounded Contexts
Setting the scene
Domains and sub-domains
もうひとつの考え方は、ビジネスの世界だ。ドメイン駆動設計という言葉を読むたびに、ビジネス問題駆動設計と読み替えることができるだろう。
Ubiquitous language
Benefits of ubiquitous language
Bounded contexts
Open Host Service
Anti-corruption layer

3 Entities, Value Objects, and Aggregates
cover the following topics
What is an entity, and how should I use it?
What are some common pitfalls when designing entities, and how can I avoid them?
What is a value object, and how should I use it?
What is the aggregate pattern, and how should I use it?
How do I discover aggregates?
Working with entities
へー
import "github.com/Rhymond/go-money"
// We use a specific money library as floats are not good ways to represent money.
...
startingPrice money.Money
Generating good identifiers
A warning when defining entities
Anemic models
A note on object-relational mapping
Working with value objects
不変性と副作用のない関数の原則に従うことで、私たちはバリュー・オブジェクトを推論しやすくし、ユニットテストを書きやすくした。複数の異なる入力と予測可能な出力で、非常にシンプルなテストを書くことができる。これは、システムの長期的なメンテナンスに役立つだろう。
How should I decide whether to use an entity or value object?
このオブジェクトを不変のものとして扱うことは可能か?
そのオブジェクトはドメイン概念を測定、数値化、記述するものですか?
その値によって、同じ型の他のオブジェクトと比較できますか?
これらの質問に対する答えがすべてイエスなら、バリュー・オブジェクトはあなたのユースケースに適しているでしょう。
The aggregate pattern
⭐
aggregateの例として、注文、チーム、walletを紹介していた
Discovering aggregates
⭐
Designing aggregates
Aggregates beyond a single bounded context

4 Exploring Factories, Repositories, and Services
- The factory pattern – we will discuss what it is and when it is useful
- The repository pattern – we will walk through some examples to help you understand how they differ from database tables
- Services – we will look at domain services, application services, and infrastructure services and the difference between them all
Introducing the factory pattern
Entity factories
エンティティ ファクトリ関数を設計する場合、ファクトリ関数に構造体の ID を生成させるか、または ID をパラメータとして渡すかを決定する必要があります。どちらの方法でもかまいませんが、よほどの理由がない限り、ファクトリ関数にIDを生成させることをお勧めします。
Implementing the repository pattern in Golang
⭐
リポジトリレイヤーで陥りがちな間違いの1つに、データベーステーブルごとに1つの構造体を作成するというものがあります。これは避けるべきです。代わりに、集約ごとに1つの構造体を作成するようにします。次の図に、その概要を示します
Understanding services
Domain services
⭐
before
after
Having this logic in a single-domain service means that if other clients want to implement our behavior, they can use our service, and our business invariants will be automatically enforced.
Domain services are perfect for when we need to compose domain logic in a stateless manner.
stateless -> infrastracture層を使うものはstateful?
Application services
⭐⭐
アプリケーション・サービスは、他のサービスやリポジトリを構成するために使用される。アプリケーションサービスは、様々なモデルの間で行われるトランザクション保証を管理する役割を担う。アプリケーション・サービスにはドメイン・ロジックを含めるべきではありません(これは前のセクションで説明したように、ドメイン・サービスに属します)。
通常、アプリケーション・サービスは非常に薄い。アプリケーション・サービスは調整のためだけに使われ、他のロジックはすべてアプリケーション・レイヤーの下のレイヤーに押し込まれる。通常、セキュリティ上の懸念もこのレイヤーで扱う。

5 Applying Domain-Driven Design to a Monolithic Application
What a monolithic application is, as well as in what situation you may want to build one
How to build an entire domain-driven monolith from scratch
How to identify that your existing application might benefit from applying domain-driven design
What do we mean when we say monolithic application?
Setting the scene
Getting started with our CoffeeCo system
Implementing our product repository
⭐
このようにするのは、購入アグリゲートを Mongo の実装から切り離すためです。他のすべてのドメインモデルもデータベースモデルから切り離す必要があります
Adding an infrastructure service for payment handling
Paying with CoffeeBux
Adding store-specific discounts

6 Building a Microservice Using DDD
Learn what a microservice is, and how it differs from a monolithic application
Learn at a high level when you and your company may benefit from considering a microservice-based architecture
Build another service from scratch, using the ports and adaptor pattern, as well as the anti-corruption layer pattern
What do we mean by microservices?
What are the benefits of microservices?
What are the downsides of microservices?
Should my company adopt microservices?
Setting the scene (again)
Building a recommendation system
Next, we are going to define an interface for the partnerships system:
type Option struct {
HotelName string
Location string
PricePerNight money.Money
}
type AvailabilityGetter interface {
GetAvailability(ctx context.Context, tripStart time.Time, tripEnd time.Time, location string) ([]Option, error)
}
ここで、私たちがインターフェイスとパートナーシップの実装をまったく結びつけていないことに注目してほしい。私たちは、境界のあるコンテキストからドメイン言語を使い、合理的で賢明なインターフェースとは何かを定義した。これは長い目で見れば、新しいパートナーシップ・システムへの移行をより簡単にするために大いに役立つだろう。
Revisiting the anti-corruption layer
Exposing our service via an open host service

7 DDD for Distributed Systems
What do we mean by a distributed system?
What are CQRS and EDA?
What is event sourcing?
What is a message bus?
How can we best deal with failure?
What is a distributed system?
CAP
Consistency, Availability, Partition tolerance
一貫性:すべての読み取りが最新の情報を受け取るか、エラーになる。
可用性:すべてのリクエストはエラーでないレスポンスを受け取るが、最新の情報を受け取れない可能性がある。
パーティション耐性: ネットワーク上の問題(パケットの廃棄など)が発生しても、システムは稼動し続ける。ここで障害が発生した場合、システム設計者は次のどちらかを選択しなければならない
- オペレーションをキャンセルし、可用性を低下させるが、一貫性を確保する。
- 操作を続行することで、可用性は確保できるが、一貫性が失われるリスクがある。
CAP theorem and databases
Distributed system patterns
CQRS
EDA
Dealing with failure
Two-phase commit (2PC)
準備段階:各サブシステムに、私たちが完了させたい仕事量をこなせるかどうかを確認する。
完了フェーズ:各サブシステムに、先ほど約束した作業を行うように指示する。
The saga pattern
What is a message bus?
Kafka
RabbitMQ
NATS

8 TDD, BDD, and DDD
Discuss and give examples of TDD and BDD using Go
Talk about how TDD and BDD can be used alongside DDD to make your systems more resilient and maintainable
TDD
Run the test we just wrote – it should fail (and we should expect it to)
Write as little code as possible to pass the test
Refactoring