Skip to content

Commit fd32940

Browse files
committed
Synchronized services documentation with the current state of the application.
A few installation/usage documentation fixes, from user input.
1 parent e1e089b commit fd32940

File tree

3 files changed

+48
-17
lines changed

3 files changed

+48
-17
lines changed

dddsample/src/site/apt/characterization.apt

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,15 @@
2929

3030
{Aggregates}
3131

32-
In real life most things are connected, directly or indirectly. Mimicking this approach when building large software systems tend to bring unnecessary complexity and poor performance. DDD provides tactics to help you sort these things out, aggregates being one of the most important ones. Aggregates help with decoupling of large structures by setting rules for relations between entities. Aggregates can also have properties, methods, and invariants that doesn't fit within one single class. Java and other OO-languages typically miss specific language constructs to handle aggregates and in the sample application responsibilities that belong to an aggregate is most often implemented in the aggregate root. <<<{{{xref/se/citerus/dddsample/domain/model/cargo/package-summary.html}cargo}}>>>: cargo is the central aggregate in the sample application. <<<Cargo>>> is the aggregate root and the aggregate also contains the <Value Objects> <<<DeliveryHistory>>>, <<<Itinereray>>>, <<<Leg>>> and a few more classes. <<<{{{xref/se/citerus/dddsample/domain/model/handling/package-summary.html}handling}}>>>: handling is another important aggregate. It contains the HandlingEvents that are registered throughout a cargo's progress from <<<RECEIVED>>> to <<<CLAIMED>>>. The <<<HandlingEvent>>>s have a relation to the <<<Cargo>>> for which the event belongs, this is allowed since <<<HandlingEvent>>> is an aggregate root and so is <<<Cargo>>>. The main reason for not making <<<HandlingEvent>>> part of the cargo aggregate is performance. <<<HandlingEvent>>>s are received from external parties and systems, e.g. warehouse management systems, port handling systems, that call our <<<{{{xref/se/citerus/dddsample/domain/service/HandlingEventService.html}HandlingEventService}}>>> webservice. The number of events can be very high and it is important that our webservice can dispatch the remote calls quickly. To be able to support this use case we need to handle the remote webservice calls asynchronously, i.e. we do not want to load the big cargo structure for each received <<<HandlingEvent>>>. Since all relationships in an aggregate must be handled synchronously we put the <<<HandlingEvent>>> in an aggregate of its own and we are able processes the events quickly and at the same time eliminate dead-locking situations in the system. <Editors note: We are aware that this example may need a little more work to drive the full benefits of aggregates home. This is one of the problems with a small sample app, real-world complexity is hard to simulate.>
32+
In real life most things are connected, directly or indirectly. Mimicking this approach when building large software systems tend to bring unnecessary complexity and poor performance. DDD provides tactics to help you sort these things out, aggregates being one of the most important ones. Aggregates help with decoupling of large structures by setting rules for relations between entities. Aggregates can also have properties, methods, and invariants that doesn't fit within one single class. Java and other OO-languages typically miss specific language constructs to handle aggregates and in the sample application responsibilities that belong to an aggregate is most often implemented in the aggregate root.
33+
34+
<<<{{{xref/se/citerus/dddsample/domain/model/cargo/package-summary.html}cargo}}>>>: cargo is the central aggregate in the sample application. <<<Cargo>>> is the aggregate root and the aggregate also contains the <Value Objects> <<<DeliveryHistory>>>, <<<Itinereray>>>, <<<Leg>>> and a few more classes.
35+
36+
<<<{{{xref/se/citerus/dddsample/domain/model/handling/package-summary.html}handling}}>>>: handling is another important aggregate. It contains the HandlingEvents that are registered throughout a cargo's progress from <<<RECEIVED>>> to <<<CLAIMED>>>. The <<<HandlingEvent>>>s have a relation to the <<<Cargo>>> for which the event belongs, this is allowed since <<<HandlingEvent>>> is an aggregate root and so is <<<Cargo>>>.
37+
38+
The main reason for not making <<<HandlingEvent>>> part of the cargo aggregate is performance. <<<HandlingEvent>>>s are received from external parties and systems, e.g. warehouse management systems, port handling systems, that call our <<<{{{xref/se/citerus/dddsample/domain/service/HandlingEventService.html}HandlingEventService}}>>> webservice. The number of events can be very high and it is important that our webservice can dispatch the remote calls quickly. To be able to support this use case we need to handle the remote webservice calls asynchronously, i.e. we do not want to load the big cargo structure for each received <<<HandlingEvent>>>. Since all relationships in an aggregate must be handled synchronously we put the <<<HandlingEvent>>> in an aggregate of its own and we are able processes the events quickly and at the same time eliminate dead-locking situations in the system.
39+
40+
<Editors note: We are aware that this example may need a little more work to drive the full benefits of aggregates home. This is one of the problems with a small sample app, real-world complexity is hard to simulate.>
3341

3442
[images/aggregates.gif]
3543

@@ -47,10 +55,31 @@
4755

4856
*Domain services
4957

50-
Domain services are a natural part of the domain and provide services such as message forwarding etc. In the sample application the <<<{{{xref/se/citerus/dddsample/domain/service/RoutingService.html}RoutingService}}>>> provides access to the routing system and is used to find possible routes for a give specification.
58+
Domain services are expressed in terms of the ubiquitous language and the domain types, i.e.
59+
the method arguments and the return values are proper domain classes. Sometimes, only the service
60+
interface (<what> the service does) is part of the domain layer, but the implementation (<how> the service does it)
61+
is part of the application layer. This is analogous to how repository interfaces are part of the domain layer, but the
62+
Hibernate implementations are not.
5163

52-
*Application services
64+
A good example of that is the <<<{{{xref/se/citerus/dddsample/domain/service/RoutingService.html}RoutingService}}>>>,
65+
which provides access to the routing system and is used to find possible routes for a give specification.
66+
The {{{xref/se/citerus/dddsample/application/routing/ExternalRoutingService.html}implementation}} communicates with
67+
another team's context and translates to and from an external API and data model.
68+
69+
On the other hand, if the service is possible to implement strictly using the domain layer,
70+
both the interface and the implementation are part of the domain layer. That is the case for the
71+
<<<{{{xref/se/citerus/dddsample/domain/service/impl/BookingServiceImpl.html}BookingService}}>>>, for example.
5372

54-
The application services in the sample application are responsible for driving workflow and coordinating transaction management (by use of the declarative transaction management support in Spring). They also provide a high-level abstraction for clients to use when interacting with the domain. These services are typically designed to support specific use cases or stories. The <<<{{{xref/se/citerus/dddsample/domain/service/TrackingService.html}TrackingService}}>>> is used by the public web application for tracking cargo and the <<<{{{xref/se/citerus/dddsample/domain/service/BookingService.html}BookingService}}>>> is used by the internal administration application for booking new cargo.
73+
*Application services
5574

56-
The services are all defined in types of the domain, i.e. the method arguments and the return values are proper domain classes. In some situation, e.g. when dealing with graphs of lazy-loaded domain objects or when passing services' return values over network boundaries, the services are wrapped in facades. The facades handle ORM session management issues and/or convert the domain objects to more portable {{{http://martinfowler.com/eaaCatalog/dataTransferObject.html}Data Transfer Objects}}) that can be tailored to specific use cases. See <<<{{{xref/se/citerus/dddsample/application/remoting/BookingServiceFacadeImpl.html}BookingServiceFacadeImpl}}>>> for an example.
75+
The application services in the sample application are responsible for driving workflow and coordinating
76+
transaction management (by use of the declarative transaction management support in Spring).
77+
They also provide a high-level abstraction for clients to use when interacting with the domain.
78+
These services are typically designed to support specific use cases or fulfill technical requirements (web services, etc).
79+
80+
In some situations, e.g. when dealing with graphs of lazy-loaded
81+
domain objects or when passing services' return values over network boundaries, the services are wrapped in facades.
82+
The facades handle ORM session management issues and/or convert the domain objects to more portable
83+
{{{http://martinfowler.com/eaaCatalog/dataTransferObject.html}Data Transfer Objects}}) that can be tailored
84+
to specific use cases.
85+
See <<<{{{xref/se/citerus/dddsample/application/remoting/BookingServiceFacadeImpl.html}BookingServiceFacadeImpl}}>>> for an example.

dddsample/src/site/apt/download.apt

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,15 @@ mvn clean package
4141
mvn jetty:run
4242
-------------
4343

44-
<<NOTE>>: If you have an IDE with Maven support (see below), you don't need standalone Maven, and both of the two commands above
45-
can be run from inside the IDE.
44+
The public tracking interface is available at {{http://localhost:8080/dddsample}} (try tracking cargos XYZ and JKL, for example)
45+
and the booking and routing administration interface can be found at {{http://localhost:8080/dddsample/admin/list.html}}.
46+
The administration interface is used for booking and routing cargo.
4647

47-
<<NOTE>>: running Jetty does not work in IntelliJ with the embedded Maven runner. Workaround: either run Maven from command line,
48-
or swich to external Maven runner in IntelliJ.
48+
An RMI registry will be started on port <<<1099>>>, in addition to the Jetty container on port <<<8080>>>, so those ports
49+
need to be available or you have to reconfigure the application.
50+
51+
<<NOTE>>: running some Maven targets (<<<jetty:run>>> for example) currently do not work in IntelliJ with the embedded Maven runner.
52+
Workaround: either run Maven from command line, or swich to external Maven runner in IntelliJ.
4953

5054
<<NOTE>>: the application currently can't be run offline, due to an unresolved problem with XSD validation.
5155
Workaround: run application online.
@@ -81,9 +85,7 @@ java -jar IncidentLoggingApplication.jar
8185
environment. Developers who are interested in how DDD is applied in the application should download the source
8286
archive instead.
8387

84-
<<NOTE>>: the application currently can't be run offline, due to an unresolved problem with XSD validation.
85-
Workaround: run application with a working network connection.
86-
88+
The same caveats for running the application that are listed in the source package section above apply to this package as well.
8789

8890
IDE Setup
8991

dddsample/src/site/apt/roadmap.apt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,19 @@ Roadmap
66

77
This application is a work of progress, and these are some ideas for continued development:
88

9+
* Remodel Cargo-HandlingEvent aggregates to make boundaries
10+
and asynchronous updates more explicit
11+
12+
* Make handling event registration completely asynchronous
13+
914
* Next expected event, for tracking
1015

1116
* Timezones for locations and handling events
1217

1318
* Departure/arrival time for carrier movements, ETA for itineraries
1419

15-
* Make handling event registration asynchronous
16-
1720
* Improve web service interface
1821

19-
* Remodel Cargo-HandlingEvent aggregates to make boundaries
20-
and asynchronous updates more explicit
21-
2222
* Diversify user interfaces
2323

2424
* More ways to register handing events (FTP CSV file upload etc)

0 commit comments

Comments
 (0)