Download presentation
Presentation is loading. Please wait.
1
Building a Rich Domain Model
Chris Richardson 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
2
Copyright (c) 2006 Chris Richardson. All rights reserved.
About Chris… Twenty years of software development experience Building object-oriented software since 1986 Using Java since 1996 J2EE since 1999 Author of POJOs in Action Run a consulting company that helps organizations use enterprise Java more effectively Chair of the eBIG Java SIG in Oakland ( 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
3
Copyright (c) 2006 Chris Richardson. All rights reserved.
Goals for this talk TODO Describe a domain model How it differs from a procedural design Some key design issues How to go about developing a domain model Domain models Object-oriented design Techniques for developing a domain model 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
4
** Agenda – Introduction to designing business logic
What is business logic? Using a layered architecture Business logic organization options Overview of a domain model Developing a domain model Identifying classes, attributes and relationships Identifying methods Implementing methods Test-driven development Mock objects Dependencies Demo Domain model smells Next steps 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
5
Copyright (c) 2006 Chris Richardson. All rights reserved.
The rise of OO I started developing software in the mid 1980s Object-oriented analysis and design became increasingly popular Perceived as a good way to tackle complex problems GoF wrote the design patterns book 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
6
Copyright (c) 2006 Chris Richardson. All rights reserved.
But along came EJB Most code written in a procedural style Fat session beans manipulating dumb data objects (DTOs) Ironic – EJB intended for building complex applications that benefit from OOAD 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
7
Reasons for procedural code
Seductively easy to write Encouraged by the EJB architecture, literature, and culture Session beans and message driven beans are procedural components EJB2 entity beans were pretty bad: No inheritance Limited relationships … 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
8
Problems with procedural code
Works well for simple business logic But doesn’t handle complexity well Complex, procedural business logic can be: Difficult to maintain and understand Difficult to test 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
9
Copyright (c) 2006 Chris Richardson. All rights reserved.
The reemergence of OO Enterprise Java frameworks that support OO development Hibernate JDO JPA/EJB3 (finally) Books that popularize OO Domain-driven design POJOs in Action … 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
10
** Agenda – Overview of a domain model
Introduction What is business logic? Using a layered architecture Business logic organization options Overview of a domain model Structure of a domain model Role of the domain model within the application Developing a domain model Identifying classes, attributes and relationships Identifying methods Implementing methods 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
11
Using the Domain Model Pattern
Business logic spread amongst a collection of classes Many classes correspond to real world concepts: Order, Customer, … Most classes are true objects having both State – fields Behavior – methods that act on the state 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
12
An example domain model
12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
13
Copyright (c) 2006 Chris Richardson. All rights reserved.
Code walkthrough Look at an example domain model 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
14
Copyright (c) 2006 Chris Richardson. All rights reserved.
Roles in a domain model Roles aka stereotypes Benefits: Guide design Help name objects Aid understanding Roles (from Domain-Driven Design): Entity Value Service Repository Factory 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
15
Copyright (c) 2006 Chris Richardson. All rights reserved.
Entity Objects with a distinct identity Typically correspond to real world concepts Often persistent Examples: Account, Customer, Order… 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
16
Copyright (c) 2006 Chris Richardson. All rights reserved.
Value object Objects that are defined by the values of their attributes Often immutable Two instances with identical values can be used interchangeably Often persistent Part of an entity Example: Address 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
17
Copyright (c) 2006 Chris Richardson. All rights reserved.
Repository Manages collections of objects Provides methods for: Adding an object to the collection Finding object or objects Deleting objects Encapsulates database access mechanism Consists of an interface and an implementation class Examples: AccountRepository, OrderRepository 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
18
Copyright (c) 2006 Chris Richardson. All rights reserved.
Factory Create objects Encapsulates complex object creation logic Different kinds of factories Factory classes Factory methods Example: TODO-?? 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
19
Copyright (c) 2006 Chris Richardson. All rights reserved.
Service Typically corresponds to one or more use cases Implements logic that cannot be put in a single entity Service method usually: Invokes one or more repositories/factories Invokes one or more entities Not persistent Consists of an interface and an implementation class Example: MoneyTransferService, MoneyTransferServiceImpl 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
20
A well designed domain model 1
An art – not a mechanical process Understandable by the business developers Reflects: reality design/implementation 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
21
A well designed domain model 2
Small classes/methods Services should be thin Good encapsulation, avoid JavaBeans Don’t define setters and getters automatically Well-designed classes encapsulate their state But UI frameworks make this difficult 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
22
A well designed domain model 3
See literature such as Bob Martin’s paper ( High cohesion each class should be focused and understandable Low coupling minimize dependencies Open/closed principle open for extension but closed to modification Dependency inversion principle details depend on abstractions … 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
23
Benefits of the Domain Model Pattern
Improved maintainability Improved testability Improved reuse 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
24
Drawbacks of the Domain Model pattern
Requires object-oriented design skills Requires domain model to be “mappable” to the source of the data E.g. nice database schema Ugly schemas and data stored in other applications is a challenge 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
25
Copyright (c) 2006 Chris Richardson. All rights reserved.
When to use it: The business logic is reasonably complex You have the skills to design one You can use an ORM framework 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
26
** Agenda – domain model design issues
Introduction What is business logic? Using a layered architecture Business logic organization options Overview of a domain model Structure of a domain model Role of the domain model within the application Domain model design issues Validation Dependency injection Developing a domain model Identifying classes, attributes and relationships Identifying methods Implementing methods 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
27
Copyright (c) 2006 Chris Richardson. All rights reserved.
TODO – need background Use case/domain 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
28
Copyright (c) 2006 Chris Richardson. All rights reserved.
Validation Syntactic validation Verify that input values are correctly formatted Handled by presentation tier, e.g. when it converts to a Java type Semantic validation Verify that input values obey business rules Simple validation can be done by presentation tier More complex validation must be done by the business tier 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
29
Example - Delivery info Validation
Syntactic: Street1 - required Street2 - optional City - required State – required, 2 letter code Zip – required, 5 digit Semantic: Delivery time is one hour in the future Delivery info served by a restaurant Bad address/time combination Bad address Bad time 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
30
Validation in the domain model
Performs semantic validation But what about syntactic validation: Can the business tier trust the presentation tier? Should the business tier revalidate, e.g. String value TODO – validation in the constructors of value objects 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
31
Copyright (c) 2006 Chris Richardson. All rights reserved.
Returning errors Business tier can’t just throw an exception Must return a collection of errors Fowler’s Notifier pattern But this needs to be passed around public interface Notification { public boolean isEmpty(); public void add(String error); public boolean hasErrors(); public String toString(); … } 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
32
Who does the validation 1?
Validation logic in object Benefits Simple Can access encapsulated state Drawbacks Adds complexity to class Less flexible, e.g. multiple contexts? public class DeliveryInfo { private Date deliveryTime; private Address deliveryAddress; public DeliveryInfo(Date deliveryTime, Address deliveryAddress) { this.deliveryTime = deliveryTime; this.deliveryAddress = deliveryAddress; } public void validateForDelivery(Notification notification, RestaurantRepository restaurantRepository) { validateDeliveryTime(notification); validateRestaurantAvailability(notification, restaurantRepository); private void validateDeliveryTime(Notification notification) { … private void validateRestaurantAvailability(Notification notification, 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
33
Who does the validation 2?
Separate class – Validator, Specification Benefits Simplifies class, minimizes coupling Supports multiple contexts Facilitates reuse of Validatee in different contexts Drawbacks Extra classes and/or interfaces Requires access to state of Validatee public interface DeliveryInfoValidator { void validate(DeliveryInfo deliveryInfo, Notification notification); } public class ValidateDeliveryInfoForOrder implements DeliveryInfoValidator { private RestaurantRepository restaurantRepository; public ValidateDeliveryInfoForOrder( RestaurantRepository restaurantRepository) { this.restaurantRepository = restaurantRepository; public void validate(DeliveryInfo deliveryInfo, Notification notification) { validateDeliveryTime(deliveryInfo, notification); validateRestaurantAvailability(deliveryInfo, notification, restaurantRepository); private void validateDeliveryTime(DeliveryInfo deliveryInfo, Notification notification) { … private void validateRestaurantAvailability(DeliveryInfo deliveryInfo, 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
34
Accessing a collaborator
Classes often collaborate with others This is a good thing – simplifies classes E.g. PlaceOrderService collaborates with PendingOrder and PendingOrderRepository A class needs to access its collaborators: Just happens naturally in the code, e.g. PendingOrder accessing the restaurant or its line items But sometimes it is tricky, e.g. accessing repositories PlaceOrderService needs the PendingOrderRepository PendingOrder needs the RestaurantRepository 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
35
Copyright (c) 2006 Chris Richardson. All rights reserved.
Obtaining a reference Service locator E.g. Registry Pattern But this requires a static/singleton Method parameter Avoids statics Clutters the code with extra parameters Dependency injection Pass in collaborator at construction time Constructor injection Setter injection Avoids problem with statics and extra params 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
36
Copyright (c) 2006 Chris Richardson. All rights reserved.
Dependency injection EXAMPLE??? TODO – Spring framework 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
37
Dependency injection into services
Easy to do for static components such as services and repositories => Instantiate and wire together using Spring’s dependency injection mechanism Use constructor injection whenever possible: Ensures that object is instantiated with the required dependencies 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
38
Copyright (c) 2006 Chris Richardson. All rights reserved.
TODO - Service example 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
39
Dependency injection into entities
This is trickier Entities are dynamically created by the application or the ORM framework Two DI options: New feature of Spring 2 – relies on AspectJ Write code + use Hibernate Interceptor to call into Spring 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
40
TODO – entity DI example
12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
41
Collaborators and testing
Collaborators make testing difficult: Top-down development is tricky Creating and initializing the collaborators makes a class’s tests more complicated Collaborators introduce undesirable coupling For example, PlaceOrderService calls: PendingOrder – non-trivial state-based behavior PendingOrderRepository – accesses the database Use a mock object to simulate the collaborator Simplifies tests Enables top-down development Enables an object to be tested in isolation 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
42
Mock object frameworks
Creating mocks Write your own mocks Use a mock object framework Mock object frameworks jMOCK EasyMock Easily create a mock that expects to have particular methods invoked 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
43
** Agenda – Developing a domain model
Introduction What is business logic? Using a layered architecture Business logic organization options Overview of a domain model Structure of a domain model Role of the domain model within the application Developing a domain model Identifying classes, attributes and relationships Identifying methods Implementing methods 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
44
Overview of developing a domain model
Analyze requirements to identify classes, relationships and attributes Analyze requirements and/or UI design to identify requests handled by the application Determine signatures of methods invoked by presentation tier Implement methods Repeat 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
45
Copyright (c) 2006 Chris Richardson. All rights reserved.
Avoid BDUF Real world applications have multiple use cases Analyze incrementally starting with the important ones Refactor domain model as you go Be agile! Avoid BDUF/analysis paralysis 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
46
Step #1: Identifying classes, attributes and relationships
How: Talk to the business people Analyze the requirements, e.g. look for nouns Apply domain knowledge Apply analysis patterns 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
47
Example – Place Order use case
The customer enters the delivery address and time. The system first verifies that the delivery time is in the future and that at least one restaurant serves the delivery information. It then updates the pending order with the delivery information, and displays a list of available restaurants. The customer selects a restaurant. The system updates the pending order with the restaurant and displays the menu for the selected restaurant. The customer enters quantities for each menu item. The system updates the pending order with the quantities and displays the updated pending order. The customer enters payment information (credit card information and billing address). The system updates the pending order with the payment information and displays the pending order with totals, tax, and charges. The customer confirms that she wants to place the order. The system authorizes the credit card, creates the order, and displays an order confirmation, which includes the order number. 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
48
Example – draft domain model
12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
49
Step #2 - Identify requests and the application’s response
Identify the requests that an application processes HTTP requests Internal timers etc Determine how the application responds Domain model: Verifies request Updates the database Performs calculations Provides data for the presentation tier to display 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
50
Identify requests - Analyze the use case
The customer enters the delivery address and time. The system first verifies that the delivery time is in the future and that at least one restaurant serves the delivery information. It then updates the pending order with the delivery information, and displays a list of available restaurants. The customer selects a restaurant. The system updates the pending order with the restaurant and displays the menu for the selected restaurant. The customer enters quantities for each menu item. The system updates the pending order with the quantities and displays the updated pending order. The customer enters payment information (credit card information and billing address). The system updates the pending order with the payment information and displays the pending order with totals, tax, and charges. The customer confirms that she wants to place the order. The system authorizes the credit card, creates the order, and displays an order confirmation, which includes the order number. 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
51
Identify requests - Analyze the UI
12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
52
Copyright (c) 2006 Chris Richardson. All rights reserved.
Example requests 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
53
Example responsibilities – enter delivery info
Verifying that the delivery time is in the future and that at least one restaurant serves the delivery information Updating the pending order with the delivery information Displaying a list of available restaurants. 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
54
Step #3 - Identifying methods
For each request define: Service method that handles the request Domain and repository methods that provide data to display Map each responsibility to one or more methods 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
55
Verifying and updating the PendingOrder
First two responsibilities: Verifying the delivery information Updating the PendingOrder This is business logic Therefore: Define PlaceOrderService interface Define updateDeliveryInfo() 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
56
Signature of updateDeliveryInfo()
Parameters Values entered by the user Session state Detached objects Return types Data to display Updated Session state DTOs and/or detached objects What about exceptions? Definite throw exceptions for true exceptions Use return codes for “regular” errors Or, return a Notifier public interface PlaceOrderService { PlaceOrderServiceResult updateDeliveryInfo(String pendingOrderId, Address deliveryAddress, Date deliveryTime); … } public class PlaceOrderServiceResult { private Notification errors; private PendingOrder pendingOrder; .. 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
57
Displaying available restaurants
“Displaying” is presentation logic But business logic must provide list of available restaurants public interface RestaurantRepository { List<Restaurant> findAvailableRestaurants( DeliveryInfo deliveryInfo); … } public Restaurant { String getName() {…} 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
58
*** Agenda – Implementing methods
12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
59
Step #4 – Implementing methods
Implement methods with significant behavior: Service methods Complicated entity methods Don’t implement: Repository methods since they are ORM framework-related 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
60
Assigning responsibilities with the GRASP patterns
Information expert Assign responsibility to who has the information, e.g. Account.credit() Creator – who creates? Container or Aggregator Uses E.g. Order creates line items See – TODO-REF for more information 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
61
Assigning responsibilities continued
Roles can be a guide: Repositories finding and save “root” objects Factories create objects Services primarily delegate to other classes Design patterns can help Strategy, Adapter,… Law of Demeter Avoid chaining: replace foo.x().y() with foo.xy() Minimizes coupling 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
62
Copyright (c) 2006 Chris Richardson. All rights reserved.
Formal modeling or TDD? Formal modeling approach Fire up a modeling tool Create some pretty diagrams … But can you be sure that it works? Better: test-driven development Write some tests Write the code to make them pass Refactor code to improve the design Repeat until done 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
63
Copyright (c) 2006 Chris Richardson. All rights reserved.
*** Agenda _ demo time 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
64
Copyright (c) 2006 Chris Richardson. All rights reserved.
Next steps Persistence Map persistent objects to DB Use JDO, Hibernate, or JPA Implement repositories Transactions Use Spring Transaction management or EJB 3 Security Use Acegi or EJB 3 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
65
Copyright (c) 2006 Chris Richardson. All rights reserved.
Summary TODO 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
66
Copyright (c) 2006 Chris Richardson. All rights reserved.
For more information Buy my book Visit my website Links to my book and articles Web site: 12/1/2018 Copyright (c) Chris Richardson. All rights reserved.
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.