blob: c196e3f3f183dc4c40c101831d01209123ddb2bf [file] [log] [blame]
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<body>
<h1>Step 1 - Evans "Making a booking."</h1>
<p>
Location: Page 17, "Knowledge-Rich Design.
</p>
<p>
We start with a very simple domain design, consisting of a <i>Voyage</i> with <i>Cargo</i> items.
The booking system is responsible for matching as many <i>Cargo</i> items on to the <i>Voyage</i>
but not too many. Evans introduces a <i>capacity</i> property in the Voyage and a <i>size</i>
property to the Cargo.
</p>
<p>
Mr Evans continues to discuss that a <i>makeBooking( Cargo cargo, Voyage voyage )</i> method
(presumably in some service instance somewhere) becomes too complicated for the domain experts
and suggests breaking out the <b>policy</b> into a separate class.
</p>
<p>
Let's start with putting into the code that Mr Evans suggests, using so called POJO or JavaBeans
programming convention.
</p>
<p>
You will find the suggested code in this package. Take a look at it. You can also run the
testcase <b>step1</b> to see simple usage cases.
</p>
<p>
We have made this code more complex than the book is suggesting. First of all there is a separation
of interface from implementation. This is done to make the code more flexible for future change;
</p>
<ul>
<li>The <i>Voyage.addCargo()</i> <b>must</b> be hidden from the client code, so that it is forced to call
the <i>ShippingService.makeBooking()</i> and not bypassing it and call the <i>addCargo()</i> directly.
</li>
<li>DDD book doesn't mention the <i>ShippingService</i> in this section, but was introduced to make the
code executable. Making the ShippingService an interface is just following common practices, which
allows us to change the, or have multiple, implementations.
</li>
<li><i>Cargo</i> also has separated interface from the implementation for the same reason.</li>
<li><i>Sequence</i> is separated largely because in a real application, it is probably dependent on
the customer.
</li>
<li>Finally, the <i>OverbookingPolicy</i> is also separated since we want to be able to have many Policies
sooner or later.
</li>
<li>And with this separation, and hiding of the implementation from the client by putting all of the
implementation details in the <i>internal</i> package, we also need to add methods to create <i>Cargo</i>
and find <i>Voyage</i> instances.
</li>
</ul>
<p>
This could have been done utilizing Spring Framework, but we don't want to introduce a fairly large
dependency, and it wouldn't help us much in the domain aspect of this example.
</p>
<p>
Mr Evans then continues to discuss "Deep Models", where he correctly observes that the domain model
artifacts tend to change over time as we start to understand the domain better. The conclusion is that
the model will change a lot and the easier we make this process the faster we can move forward.
</p>
<p>
Now, what we have done so far is to just use plain Java to implement the discussion of Mr Evans' Cargo
example of domain-driven design. Before we move on to making the model more complex, and changing
the model as we understand it better, let's first refactor this into Zest™ and discuss the immediate
differences.
</p>
<p>
Steps;
</p>
<ol>
<li>Cargo has a <i>size</i> property. We change that to use the <i>Property</i> feature in Zest™.</li>
<li>Voyage likewise has the <i>capacity</i> and <i>bookedCargoSize</i> properties.</li>
<li>Zest™ doesn't need implementations of the Cargo and Voyage implementations.</li>
<li>Cargo and Voyage are entities, so we create CargoEntity and VoyageEntity interfaces.</li>
</ol>
</body>