OO design principles and patterns

pagsousa 1,988 views 43 slides Apr 10, 2014
Slide 1
Slide 1 of 43
Slide 1
1
Slide 2
2
Slide 3
3
Slide 4
4
Slide 5
5
Slide 6
6
Slide 7
7
Slide 8
8
Slide 9
9
Slide 10
10
Slide 11
11
Slide 12
12
Slide 13
13
Slide 14
14
Slide 15
15
Slide 16
16
Slide 17
17
Slide 18
18
Slide 19
19
Slide 20
20
Slide 21
21
Slide 22
22
Slide 23
23
Slide 24
24
Slide 25
25
Slide 26
26
Slide 27
27
Slide 28
28
Slide 29
29
Slide 30
30
Slide 31
31
Slide 32
32
Slide 33
33
Slide 34
34
Slide 35
35
Slide 36
36
Slide 37
37
Slide 38
38
Slide 39
39
Slide 40
40
Slide 41
41
Slide 42
42
Slide 43
43

About This Presentation

Principles and patterns of object oriented design. answering the most common questions faced when designing a system, e.g., how to model the domain? how to prepare the code for modification? how to handle an object's life cycle?


Slide Content

Object Oriented Design
is mainly about
behaviour, not
structure.
2

What to ask when designing
0Which class should a responsibility be assigned to?
0How to organize the system’s responsibilities?
0How to model the domain?
0How to handle an object’s lifecycle?
0How to prepare the code for modification?


3

Which class should a
responsibility be assigned to?
4

0Information Expert [GRASP]
0A responsibility dealing with X should be
assigned to the object holding X

0Single Responsibility Principle [SOLID]
0Each class should have one and only one
responsibility

0Interface Segregation [SOLID]
0Favour small specific interfaces so clients don’t
depend on interfaces they don’t use
5

Corollary of Information Expert
Getters and setters are Evil
(don’t ask for data, delegate as much as possible)

6

Procedural thinking
7

Object thinking
8

How to organize the system’s
responsibilities?
9

Layers pattern
0You are designing a system whose dominant
characteristic is a mix of low- and high-level issues,
where high-level operations rely on the lower-level
ones.

0Therefore
0Structure your system into an appropriate number of
layers and place them on top of each other, each
providing a specific level of abstraction.
10
GoF

Common architecture
Source: domain driven design , Eric Evans 11

0Low coupling [GRASP]
0Keep coupling of elements to a minimum.
Avoid circular dependencies.

0High Cohesion [GRASP]
0Keep related elements close together

0Indirection [GRASP]
0Avoid tight coupling by creating an
indirection layer

13

Façade
0Work is actually performed by a series of subsystem
but this level of complexity must be hidden from the
client

0Therefore
0Create a facade object offering a simpler, high level
interface which delegates work in the actual subsystems
14
GoF

Controller
0You need to coordinate application activity - the
interactions of a use case with the UI or external
systems

0Therefore
0Assign the responsibility of use case coordination to a
dedicated use case controller which exposes a business
API (application layer) and performs no business logic
but delegates to the right domain objects instead
15
GRASP

How to model the domain?
16

Look at your domain model’s
ubiquitous language
17

Entity
0Some objects in the domain have a thread of
continuity which we need to track by its identity.

0Therefore
0Model objects in the real world as entities, assigning
each object one or more identities. Equality of
references is done comparing the identity of the object.

18
DDD

Entity: example
Class Account{
public Account(AccountNumber accn) {…}

public boolean equals(Object other) {
if (other==this) return true;
if (!(other instanceof Account)) return false;
return (this.getID() == (Account)other.getID());
}

public void withdraw(Money amount) {
if (hasEnoughBalance(amount)
|| overdraftAllowed(amount)) {
// business logic for withdrawing
// and updating balances
}
}
}
19

Value Object
0Not everything needs an identity; some things matter
for the value of its attributes.

0Therefore
0Create immutable objects whose equality is
determined by the equality of its attributes.
20
DDD

Value object: example
Class Balance{
public Balance(Money amount, Calendar asOf) {…}

// getters (but no setters)
public Money amount() {…}
public Calendar asOf() {…}

// creates a new Balance object
// keeping this and the other object unchanged
public Balance add(Money some) {…}
public Balance add(Money some, Calendar effectiveOn) {…}
public Balance subtract(Money some) {…}
...

public boolean equals(Object other) {…}
}
21

Service
0Some business operations are not naturally placed
in a certain domain object

0Therefore
0Create a service object that handles only that operation
and coordinates the necessary domain objects.
23
DDD

Service: example
class TransferService {
public void transfer(Money amount,
Account from, Account to) {
if (isAllowedToTransfer(from, amount, to) {
from.withdraw(amount);
to.deposit(amount);
}
}

private boolean isAllowedToTransfer(Account from,
Money amount,
Account to) {
// rules specific to account transfers
// (e.g., maximum allowed amount to transfer for
// international account)
}
}
24

An Example
25
N-to-M
relationships
are hard

A pragmatic design
26
•Remove
unnecessary
associations

•Force traversal
direction of
bidirectional
associations

•Reduce
cardinality by
qualification of
the association

we are still left
with a tangle of
interconnected
objects...

Aggregate
0Some objects are closely related together and we need
to control the scope of data changes so that invariants
are enforced

0Therefore
0Keep related objects with frequent changes bundled in
an aggregate
0control access to the “inner” objects thru one single
“root” object
27
DDD

A more pragmatic design
28
Legend:
•Account
aggregate
•Customer
aggregate







Address is a value
object so it can be
freely shared among
several aggregates

How to handle an object’s
lifecycle?
29

Object’s lifecycle
1.An object is created
2.The object is used
3.It must be persisted for later use
4.Later, the object is reconstructed from persistence
5.It is used (provably changed)
6.It is stored back again for later use
7.…
30

Separate use from
construction
31

Factories
0Creating a (large) object might be a complex task
and/or the client must be decoupled from the actual
type of the created object.

0Therefore
0Place construction logic in a dedicated factory which
encapsulates object creation for all clients.
32
DDD

0Creator [GRASP]
0Assign class A creation responsibility to the class which
either (1) contains A’s instances; or (2) holds the data
for initializing an A’s instance

0Factory Method [GoF]
0A class method that simplifies the creation of different
implementations of the same interface

0Simple Factory [GoF]
0A class made up of only factory methods

0Abstract Factory [GoF]
0Handles the creation of related or dependent product
families
33

Repository
0Client code needs to obtain a reference to an object in
order to use it (sometimes, the desired object needs to
be reconstructed from persistence). After using it the
client wants the object to be persisted again.

0Therefore
0Encapsulate the logic needed for obtaining object
references in a Repository. The repository handles all
the persistence logic and abstracts the client code from
such details.
34
DDD

35
Repository example

Repositories and layers
36

How to prepare the code for
modification?
37

Protected Variation
0You need to design objects, components or systems so
that variations in those elements don’t impact other
elements

0Therefore
0Identify points of predicted variation and create a stable
interface around them.
38
GRASP

0Open/Close Principle [SOLID]
0A class should be open for extension and
adaption and closed for modification

0Dependency Inversion Principle [SOLID]
0Clients should depend on abstractions, not
concretions. I.e., program to an interface not
a realization.

39

0Polymorphism [GRASP]
0When behaviour varies depending on type

0Template Method [GoF]
0Define the skeleton of an algorithm in an
operation, deferring some steps to subclasses.

0Liskov Substitution Principle [SOLID]
0Any method expecting A should work
properly with any object derived from A


40

Liskov Substitution Principle’s Corollary
Derived classes should adhere strictly to the semantics
of the contract

see also, Design by Contract:
Pre-conditions
Post-conditions
Invariants

41

Strategy
0Sometimes there is a business policy (expressed in
the domain) that must be enforced but it actually may
have different variations of concrete policies

0Therefore
0Define a common interface for the policy and provide
different implementations decoupling the client from
the actual policy and allowing for permutation and
independent evolution.
42
GoF

Topic Principles and patterns
Which class should a responsibility be
assigned to?
Information Expert
Single Responsibility Principle
Interface Segregation Principle
How to organize the system’s
responsibilities?
Layers
Façade
Controller
How to model the domain? Entity
Value Object
Service
Aggregate
How to handle an object’s lifecycle? Factories
Repositories
How to prepare the code for
modification?
Protected Variation
Open/Close Principle
Dependency Inversion Principle
Liskov Substitution Principle
Template Method
Strategy
44

References
0Domain Driven Design. Eric Evans
0Why getters and setters are Evil. Allan Holub.
http://www.javaworld.com/article/2073723/core-
java/why-getter-and-setter-methods-are-evil.html
0Design Principles and Design Patterns. Robert Martin.
http://www.objectmentor.com/resources/articles/Princip
les_and_Patterns.pdf
0Design Patterns-Elements of Reusable Object-oriented
Software, Gamma et al. (Gang of Four)
0Applying UML and Patterns; Craig Larman; (2nd ed.); 2002.

45