Upload
truongminh
View
218
Download
0
Embed Size (px)
Citation preview
© GameDuell GmbH | DOAG 2015
Cargo Tracker
Domain-Driven Design auf Basis von JEE
Dirk Ehms, GameDuell GmbH
© GameDuell GmbH | DOAG 2015
Domain-Driven Design
• Set of principles and patterns
• Not a technology or methodology
• Software and domain experts collaboration
• Term invented by Eric Evans
2
© GameDuell GmbH | DOAG 2015
Domain-Driven Design Reference Definitions and Pattern Summaries
6
http://tinyurl.com/k82tpbr
https://domainlanguage.com/ddd/patterns/DDD_Reference_2011-01-31.pdf
© GameDuell GmbH | DOAG 2015
Building Blocks of DDD: Model-Driven Design
Value Objects
Repositories
Services
Model-Driven Design
Layered Architecture
Factories
Entities Aggregates
Access with
Encapsulate with
Act as root of
Maintain integrity with
Domain Events
Express model with Push state change with
© GameDuell GmbH | DOAG 2015
Building Blocks of DDD: Layered Architecture
Value Objects
Repositories
Services
Model-Driven Design
Factories
Entities Aggregates
Access with
Encapsulate with
Act as root of
Maintain integrity with
Domain Events
Express model with Push state change with
Layered Architecture
© GameDuell GmbH | DOAG 2015
Building Blocks of DDD: Entities
Value Objects
Repositories
Services
Model-Driven Design
Layered Architecture
Factories
Entities Aggregates
Access with
Encapsulate with
Act as root of
Maintain integrity with
Domain Events
Express model with Push state change with
© GameDuell GmbH | DOAG 2015
Entities
• Have identity, state and behavior
• Not defined by their attributes
• Examples: Customer, Account
12
@Entity public class Cargo implements Serializable { private TrackingId trackingId; public void specifyNewRoute(RouteSpecification routeSpecification) {...} public void assignToRoute(Itinerary itinerary) {...} public void deriveDeliveryProgress(HandlingHistory handlingHistory) {...} ... }
© GameDuell GmbH | DOAG 2015
Building Blocks of DDD: Value Objects
Value Objects
Repositories
Services
Model-Driven Design
Layered Architecture
Factories
Entities Aggregates
Access with
Encapsulate with
Act as root of
Maintain integrity with
Domain Events
Express model with Push state change with
© GameDuell GmbH | DOAG 2015
Value Objects
• Defined by their attributes
• No conceptual identity
• Immutable
• Entity contains Value Objects
• Examples: Address, Money
15
@Embeddable public class Itinerary implements Serializable { /** * Test if the given handling event is expected when executing this * itinerary. */ public boolean isExpected(HandlingEvent event) {...} ... }
© GameDuell GmbH | DOAG 2015
Value Objects (cont.)
16
@Embeddable public class Itinerary implements Serializable { @OrderBy("loadTime") @PrivateOwned @Size(min = 1) private List<Leg> legs = Collections.emptyList(); ... }
@Entity public class Leg implements Serializable { @Id @GeneratedValue private Long id; ... }
© GameDuell GmbH | DOAG 2015
Building Blocks of DDD: Aggregates
Value Objects
Repositories
Services
Model-Driven Design
Layered Architecture
Factories
Entities Aggregates
Access with
Encapsulate with
Act as root of
Maintain integrity with
Domain Events
Express model with Push state change with
© GameDuell GmbH | DOAG 2015
Aggregates
• Cluster of Entities and Value Objects
• Consistency boundary
• One Entity acts as Aggregate Root
• Root controls access
• Root is target for external references
18
© GameDuell GmbH | DOAG 2015
Aggregates (cont.)
@Entity
public class Cargo implements Serializable {
@Id
@GeneratedValue
private Long id;
@Embedded
private TrackingId trackingId;
@ManyToOne
@JoinColumn(name = "origin_id")
private Location origin;
@Embedded
private RouteSpecification routeSpecification;
@Embedded
private Itinerary itinerary;
@Embedded
private Delivery delivery;
public void specifyNewRoute(RouteSpecification routeSpecification) {...}
public void assignToRoute(Itinerary itinerary) {...}
public void deriveDeliveryProgress(HandlingHistory handlingHistory) {...}
...
}
© GameDuell GmbH | DOAG 2015
Alternative Approaches
• ID references between aggregates
• Custom Types
• ORM file instead of annotations
21
<?xml version="1.0" encoding="UTF-8"?> <entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_2_0.xsd" version="2.0"> <entity class="...domain.model.cargo.Cargo" access="FIELD"> ... </entity> <embeddable class="...domain.model.cargo.Itinerary" access="FIELD"> ... </embeddable> </entity-mappings>
© GameDuell GmbH | DOAG 2015
Building Blocks of DDD: Repositories
Value Objects
Repositories
Services
Model-Driven Design
Layered Architecture
Factories
Entities Aggregates
Access with
Encapsulate with
Act as root of
Maintain integrity with
Domain Events
Express model with Push state change with
© GameDuell GmbH | DOAG 2015
Repositories
• Encapsulates persistence and retrieval
• Interface definition: Domain layer
• Implementation: Infrastructure layer
23
@ApplicationScoped public class JpaCargoRepository implements CargoRepository, Serializable { @PersistenceContext private EntityManager entityManager; @Override public Cargo find(TrackingId trackingId) {...} @Override public void store(Cargo cargo) {...} @Override public TrackingId nextTrackingId() {...} ... }
© GameDuell GmbH | DOAG 2015
Alternative: Hexagonale Architecture
User Interface Layer Infrastructure Layer
Domain Layer
Internal UI port
External integration
port
In -Memory Database
Relational Database
External systems
NoSQL Database
User Interface
Test adapter
Test adapter
RESTful webservices
Internal persistence
port
External service
port
© GameDuell GmbH | DOAG 2015
Building Blocks of DDD: Factories
Value Objects
Repositories
Services
Model-Driven Design
Layered Architecture
Factories
Entities Aggregates
Access with
Encapsulate with
Act as root of
Maintain integrity with
Domain Events
Express model with Push state change with
© GameDuell GmbH | DOAG 2015
Factories
• Create complex domain objects
• Relevant Patterns: Factory, Builder
• Invariants
26
@ApplicationScoped public class HandlingEventFactory implements Serializable { @Inject private CargoRepository cargoRepository; @Inject private VoyageRepository voyageRepository; @Inject private LocationRepository locationRepository; public HandlingEvent createHandlingEvent(...) {...} ... }
© GameDuell GmbH | DOAG 2015
Building Blocks of DDD: Services
Value Objects
Repositories
Services
Model-Driven Design
Factories
Entities Aggregates
Access with
Encapsulate with
Act as root of
Maintain integrity with
Domain Events
Express model with Push state change with
Layered Architecture
© GameDuell GmbH | DOAG 2015
Services
• Represent an operation
• Stateless
• Example: transfer(Account1, Account2, Money)
• Domain Service
• Business Logic
• Application Service:
• Non functional requirements, coordinator
• Infrastructure Service
• E.g. sending emails
28
© GameDuell GmbH | DOAG 2015
Application Service
29
@Stateless public class DefaultBookingService implements BookingService { @Inject private CargoRepository cargoRepository; @Inject private LocationRepository locationRepository; @Inject private RoutingService routingService; @Override public TrackingId bookNewCargo(UnLocode originUnLocode, UnLocode destinationUnLocode, Date arrivalDeadline) {...} @Override public List<Itinerary> requestPossibleRoutesForCargo(TrackingId trackingId) {...} @Override public void assignCargoToRoute(Itinerary itinerary, TrackingId trackingId) {...} @Override public void changeDestination(TrackingId trackingId, UnLocode unLocode) {...} }
© GameDuell GmbH | DOAG 2015
Building Blocks of DDD: Domain Events
Value Objects
Repositories
Services
Model-Driven Design
Factories
Entities Aggregates
Access with
Encapsulate with
Act as root of
Maintain integrity with
Domain Events
Express model with Push state change with
Layered Architecture
© GameDuell GmbH | DOAG 2015
Domain Events
• Represents a state change
• Plain data
• Immutable
31
/** * A HandlingEvent is used to register the event when, * for instance, a cargo is unloaded from a carrier at * a some location at a given time. */ @Entity public class HandlingEvent implements Serializable {...}
© GameDuell GmbH | DOAG 2015
Technology Mapping
32
Layer Building Block APIs Annotations
User Interface JAX-RS JAX-WS JSF Websocket JEE-Batch
@Path @WebService @Named @ServerEndpoint META-INF/batch-jobs/*.xml
Application Layer Application Service EJB @Stateless
Domain Layer
Entity, Aggregate Value Object Domain Service Domain Event
JPA JPA CDI CDI, JMS
@Entity @Embeddable, @Entity @ApplicationScoped @Inject Event<...>
Infrastructure Layer
Repository (Impl.) Infrastructure Service
JPA, CDI JAX-RS-Client, JAX-WS-Client, JMS, JavaMail
@PersistenceContext
© GameDuell GmbH | DOAG 2015
DDD Implementation Effort
33 Source: [Fowler, PoEAA]
Complexity of Domain Logic
Data or Transaction centric
Domain Model
Effo
rt t
o E
nh
ance
© GameDuell GmbH | DOAG 2015
Resources, Useful Links
• Cargo Tracker
http://cargotracker.java.net
• Getting Started with Domain-Driven Design
http://refcardz.dzone.com/refcardz/getting-started-domain-driven
• Domain-Driven Design Quickly
http://www.infoq.com/minibooks/domain-driven-design-quickly
• Domain-Driven Design Reference
https://domainlanguage.com/ddd/patterns/DDD_Reference_2011-01-31.pdf
34