diff --git a/chapter_01_domain_model.asciidoc b/chapter_01_domain_model.asciidoc index 49279ab8..80576d58 100644 --- a/chapter_01_domain_model.asciidoc +++ b/chapter_01_domain_model.asciidoc @@ -91,7 +91,7 @@ But there's a lot more to DDD and to the processes, tools, and techniques for developing a domain model. We hope to give you a taste of it, though, and cannot encourage you enough to go on and read a proper DDD book: -* The original "blue book,"_Domain-Driven Design_ by Eric Evans (Addison-Wesley Professional) +* The original "blue book," _Domain-Driven Design_ by Eric Evans (Addison-Wesley Professional) * The "red book," _Implementing Domain-Driven Design_ by Vaughn Vernon (Addison-Wesley Professional) @@ -253,6 +253,7 @@ system, and the names of the classes and variables that we use are taken from th business jargon. We could show this code to our nontechnical coworkers, and they would agree that this correctly describes the behavior of the system. +[role="pagebreak-before"] And here is a domain model that meets our requirements: [[domain_model_1]] @@ -909,6 +910,38 @@ def test_raises_out_of_stock_exception_if_cannot_allocate(): ---- ==== + +[role="nobreakinside"] +.Domain Modeling Recap +***************************************************************** +Domain modeling:: + This is the part of your code that is closest to the business, + the most likely to change, and the place where you deliver the + most value to the business. Make it easy to understand and modify. + +Distinguish entities from value objects:: + A value object is defined by its attributes.((("value objects", "entities versus")))((("entities", "value objects versus"))) It's usually best + implemented as an immutable type. If you change an attribute on + a Value Object, it represents a different object. In contrast, + an entity has attributes that may vary over time and it will still be the + same entity. It's important to define what _does_ uniquely identify + an entity (usually some sort of name or reference field). + +Not everything has to be an object:: + Python is a multiparadigm language, so let the "verbs" in your + code be functions. For every `FooManager`, `BarBuilder`, or `BazFactory`, + there's often a more expressive and readable `manage_foo()`, `build_bar()`, + or `get_baz()` waiting to happen.((("functions"))) + +This is the time to apply your best OO design principles:: + Revisit the ((("object-oriented design principles")))SOLID principles and all the other good heuristics like "has a versus is-a," + "prefer composition over inheritance," and so on. + +You'll((("domain modeling", startref="ix_dommod"))) also want to think about consistency boundaries and aggregates:: + But that's a topic for <>. + +***************************************************************** + We won't bore you too much with the implementation, but the main thing to note is that we take care in naming our exceptions in the ubiquitous language, just as we do our entities, value objects, and services: @@ -942,33 +975,3 @@ image::images/apwp_0104.png[] That'll probably do for now! We have a domain service that we can use for our first use case.((("domain modeling", "functions for domain services", startref="ix_dommodfnc"))) But first we'll need a database... -[role="nobreakinside"] -.Domain Modeling Recap -***************************************************************** -Domain modeling:: - This is the part of your code that is closest to the business, - the most likely to change, and the place where you deliver the - most value to the business. Make it easy to understand and modify. - -Distinguish entities from value objects:: - A value object is defined by its attributes.((("value objects", "entities versus")))((("entities", "value objects versus"))) It's usually best - implemented as an immutable type. If you change an attribute on - a Value Object, it represents a different object. In contrast, - an entity has attributes that may vary over time and it will still be the - same entity. It's important to define what _does_ uniquely identify - an entity (usually some sort of name or reference field). - -Not everything has to be an object:: - Python is a multiparadigm language, so let the "verbs" in your - code be functions. For every `FooManager`, `BarBuilder`, or `BazFactory`, - there's often a more expressive and readable `manage_foo()`, `build_bar()`, - or `get_baz()` waiting to happen.((("functions"))) - -This is the time to apply your best OO design principles:: - Revisit the ((("object-oriented design principles")))SOLID principles and all the other good heuristics like "has a versus is-a," - "prefer composition over inheritance," and so on. - -You'll((("domain modeling", startref="ix_dommod"))) also want to think about consistency boundaries and aggregates:: - But that's a topic for <>. - -*****************************************************************