Layered Architectures and Domain

advertisement
Table of Contents
•
•
•
•
•
General Layered Architecture
Sample Application
Domain-Driven Design (DDD) Building Blocks
Spring Layered Architecture
Inversion of Control
General Layered Architecture
• Layer
– a discrete, orthogonal area of concern within an
application
• Top layer (front end, presentation)
– UI – end user interaction
– Web – navigation logic
• Middle layer
– Service – coarse-grained system functionality (use
cases), transaction (unit of work) , stateless
– Domain – entities, value objects, business logic – the
true implementation of the use cases
• Bottom layer (back end, infrastructure)
– Persistence – store & retrieve instances of the object
model
– Integration – communication between systems
Sample Application – Pet Store (see
jpetstore example)
• Use Cases
– Fill shopping
cart
– Sign in
– Register
customer
– Register order (checkout);
– Process order
• Business Rules
– Large orders must be approved
DDD Building Blocks
• Entity, Value Object, Aggregate
• Repository, Service
• Refine Associations, Validation
Entity
• An object defined primarily by its identity is
called an ENTITY.
• When an object is distinguished by its identity,
rather than its attributes,
– Keep the class definition simple and focused on life
cycle continuity (status) and identity (id).
– Be alert to requirements that call for matching objects
by attributes (finders).
– The model must define what it means to be the same
thing (equality).
Value Object
• An object that represents a descriptive aspect of
the domain with no conceptual identity is called a
VALUE OBJECT.
• When you care only about the attributes of an
element of the model, classify it as a VALUE
OBJECT.
– Treat the VALUE OBJECT as immutable. (it cannot be
changed except by full replacement)
– Don't give it any identity and avoid the design
complexities necessary to maintain ENTITIES.
Store - Entities and Value Objects
Aggregate
Context/Problem
• Consistency of changes in a model with complex associations
• Invariants that apply to closely related groups of objects, not just discrete
objects
• Locking schemes cause multiple users to interfere with each other and
make a system unusable.
Solution
• Cluster the ENTITIES and VALUE OBJECTS into AGGREGATES and define
boundaries around each.
• Choose one ENTITY to be the root of each AGGREGATE, and control all
access to the objects inside the boundary through the root.
• Allow external objects to hold references to the root only.
• Transient references to internal members can be passed out for use
within a single operation only.
Store - Aggregates
Store - Validation
• Define object validation
as part of the domain
• Use the Strategy design
pattern to be able to
change the validation
algorithms without
changing the model
• Validation algorithms
are defined for each
aggregate root
Repository
• A REPOSITORY represents all objects of a certain type as a
conceptual set (usually emulated).
• For each type of object that needs global access, create a
repository
– Provide methods to add and remove objects, which will
encapsulate the actual insertion or removal of data in the data
store.
– Provide methods that select objects based on some criteria and
return fully instantiated objects or collections of objects whose
attribute values meet the criteria, thereby encapsulating the
actual storage and query technology.
• Provide REPOSITORIES only for AGGREGATE roots that
actually need direct access.
Store - Repositories
Service
• A SERVICE is an operation offered as an interface that stands alone
in the model, without encapsulating state, as ENTITIES and VALUE
OBJECTS do.
• SERVICES are a common pattern in technical frameworks, but they
can also apply in the domain layer.
• A good SERVICE has three characteristics.
– The operation relates to a domain concept that is not a natural part of
an ENTITY or VALUE OBJECT.
– The interface is defined in terms of other elements of the domain
model.
– The operation is stateless.
• When a significant process or transformation in the domain is not a
natural responsibility of an ENTITY or VALUE OBJECT, add an
operation to the model as a standalone interface declared as a
SERVICE.
Store – Product Catalog Service
Presentation Layer:
• Get categories
• Get products by
category
• Get items by product
• Other CRUD
operations, e.g.
remove category
which also includes
removing products
and items
• etc
Store – Ordering Service
Presentation Layer:
• Get user by username
• Create order
• Approve order
• Reject order
• Process order
• Get open orders
• Get orders by
customer
• Get orders for
approval
• Enforce business rules
DDD Layered Architecture
Inversion of Control (IoC)
Suppose we have a component that uses another component that
implements a given interface. How the component could obtain a plugin
implementation?
Dependency Lookup. Use
Abstraction
a factory bean to lookup
Dependent
for the collaborator, such as:
object
I i = factoryBean.getBean(“i”);
i.f();
...
This code
is usually put in C.
This design follows
the dependency
inversion principle.
Collaborator object
IoC (cont.)
Dependency Injection. Use
an assembler object that injects
(populates) a field in the
dependent object.
Based on a config,
finds an appropriate
implementation,
creates a collaborator, and
injects that object in
the dependent object.
IoC (cont.)
Constructor Injection. The Assembler
uses the constructor to inject or set
the implementation.
Assembler proceeds
as follows:
I i = new IImpl();
C c = new C(i);
IoC (cont.)
Setter Injection. The Assembler
uses a setter method to inject or set
the implementation.
Assembler proceeds
as follows:
I i = new IImpl();
C c = new C();
c.setI(i)
IoC (cont.)
•
<?xml version="1.0" encoding="UTF-8"?>
•
•
<beans xmlns=“...">
<bean id=“cBean"
class=“C">
<property name=“i"
ref=“iBean" />
</bean>
<bean id=“iBean"
class=“IImpl">
</bean>
</beans>
•
public class C {
private I i;
public void setI(I i) {
this.i = i;
}
public void fun() {i.f();}
}
FileSystemXmlApplicationContext factory =
new FileSystemXmlApplicationContext("classpath:conf/spring-config.xml");
C c = (C) factory.getBean(“cBean");
c.fun();
Download