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
private MessageService messageService; public void sendPromotions(GameCategory category) { for (Customer customer: customerRepo.findCustomersByInterest(category)) { messageService.sendMessage(creat...
More information