Cargo Tracker

Transcription

Cargo Tracker
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
© GameDuell GmbH | DOAG 2015
2
Java Pet Store / J2EE Core Pattern
© GameDuell GmbH | DOAG 2015
3
Cargo Tracker
© GameDuell GmbH | DOAG 2015
4
Cargo Tracker Screenshot
© GameDuell GmbH | DOAG 2015
5
Domain-Driven Design Reference
Definitions and Pattern Summaries
http://tinyurl.com/k82tpbr
https://domainlanguage.com/ddd/patterns/DDD_Reference_2011-01-31.pdf
© GameDuell GmbH | DOAG 2015
6
Building Blocks of DDD: Model-Driven Design
Services
Domain Events
Repositories
Express model with
Push state change with
Access with
Act as root of
Model-Driven
Design
Entities
Aggregates
Maintain
integrity with
Encapsulate with
Value Objects
Factories
Layered
Architecture
© GameDuell GmbH | DOAG 2015
Cargo Tracker Domain Model
© GameDuell GmbH | DOAG 2015
8
Building Blocks of DDD: Layered Architecture
Services
Domain Events
Repositories
Express model with
Push state change with
Access with
Act as root of
Model-Driven
Design
Entities
Aggregates
Maintain
integrity with
Encapsulate with
Value Objects
Factories
Layered
Architecture
© GameDuell GmbH | DOAG 2015
Layered Architecture
Source: [Evans, DDD]
© GameDuell GmbH | DOAG 2015
10
Building Blocks of DDD: Entities
Services
Domain Events
Repositories
Express model with
Push state change with
Access with
Act as root of
Model-Driven
Design
Entities
Aggregates
Maintain
integrity with
Encapsulate with
Value Objects
Factories
Layered
Architecture
© GameDuell GmbH | DOAG 2015
Entities
• Have identity, state and behavior
• Not defined by their attributes
• Examples: Customer, Account
@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
12
Domain Model: Entities
© GameDuell GmbH | DOAG 2015
13
Building Blocks of DDD: Value Objects
Services
Domain Events
Repositories
Express model with
Push state change with
Access with
Act as root of
Model-Driven
Design
Entities
Aggregates
Maintain
integrity with
Encapsulate with
Value Objects
Factories
Layered
Architecture
© GameDuell GmbH | DOAG 2015
Value Objects
•
•
•
•
•
Defined by their attributes
No conceptual identity
Immutable
Entity contains Value Objects
Examples: Address, Money
@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
15
Value Objects (cont.)
@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
16
Building Blocks of DDD: Aggregates
Services
Domain Events
Repositories
Express model with
Push state change with
Access with
Act as root of
Model-Driven
Design
Entities
Aggregates
Maintain
integrity with
Encapsulate with
Value Objects
Factories
Layered
Architecture
© 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
© GameDuell GmbH | DOAG 2015
18
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
Domain Model: Aggregates
© GameDuell GmbH | DOAG 2015
20
Alternative Approaches
• ID references between aggregates
• Custom Types
• ORM file instead of annotations
<?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
21
Building Blocks of DDD: Repositories
Services
Domain Events
Repositories
Express model with
Push state change with
Access with
Act as root of
Model-Driven
Design
Entities
Aggregates
Maintain
integrity with
Encapsulate with
Value Objects
Factories
Layered
Architecture
© GameDuell GmbH | DOAG 2015
Repositories
• Encapsulates persistence and retrieval
• Interface definition: Domain layer
• Implementation: Infrastructure layer
@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
23
Alternative: Hexagonale Architecture
User Interface Layer
User
Interface
Infrastructure Layer
Internal
persistence
port
Internal
UI port
In -Memory
Database
Relational
Database
Test
adapter
NoSQL
Database
Domain Layer
Test
adapter
RESTful
webservices
External
integration
port
External
service
port
External
systems
© GameDuell GmbH | DOAG 2015
Building Blocks of DDD: Factories
Services
Domain Events
Repositories
Express model with
Push state change with
Access with
Act as root of
Model-Driven
Design
Entities
Aggregates
Maintain
integrity with
Encapsulate with
Value Objects
Factories
Layered
Architecture
© GameDuell GmbH | DOAG 2015
Factories
• Create complex domain objects
• Relevant Patterns: Factory, Builder
• Invariants
@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
26
Building Blocks of DDD: Services
Services
Domain Events
Repositories
Express model with
Push state change with
Access with
Act as root of
Model-Driven
Design
Entities
Aggregates
Maintain
integrity with
Encapsulate with
Value Objects
Factories
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
© GameDuell GmbH | DOAG 2015
28
Application Service
@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
29
Building Blocks of DDD: Domain Events
Services
Domain Events
Repositories
Express model with
Push state change with
Access with
Act as root of
Model-Driven
Design
Entities
Aggregates
Maintain
integrity with
Encapsulate with
Value Objects
Factories
Layered
Architecture
© GameDuell GmbH | DOAG 2015
Domain Events
• Represents a state change
• Plain data
• Immutable
/**
* 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
31
Technology Mapping
Layer
Building Block
User Interface
APIs
Annotations
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
32
Effort to Enhance
DDD Implementation Effort
Domain Model
Data or Transaction centric
Complexity of Domain Logic
Source: [Fowler, PoEAA]
© GameDuell GmbH | DOAG 2015
33
Resources, Useful Links
• Cargo Tracker
http://cargotracker.java.net
• Getting Started with Domain-Driven Design
http://refcardz.dzone.com/refcardz/getting-starteddomain-driven
• Domain-Driven Design Quickly
http://www.infoq.com/minibooks/domain-driven-designquickly
• Domain-Driven Design Reference
https://domainlanguage.com/ddd/patterns/DDD_Refere
nce_2011-01-31.pdf
© GameDuell GmbH | DOAG 2015
34
Books
© GameDuell GmbH | DOAG 2015
35
Thank You!
Any Questions?
© GameDuell GmbH | DOAG 2015

Similar documents

Zwiebeln statt Schichten - BED-Con

Zwiebeln statt Schichten - BED-Con private MessageService messageService; public void sendPromotions(GameCategory category) { for (Customer customer: customerRepo.findCustomersByInterest(category)) { messageService.sendMessage(creat...

More information