• Keine Ergebnisse gefunden

Design Patterns

N/A
N/A
Protected

Academic year: 2022

Aktie "Design Patterns"

Copied!
44
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

Oliver Haase

Design Patterns

Observer

(2)

Description

Object based behavioral pattern

Purpose: Define a one-to-many dependency between objects so that when one object changes state, all its

dependents are notified and updated automatically.

Also Known As: Publish-Subscribe

(3)

Model

View 1

View 2

View 3 Observer Subject,

Observable

notify

get update

Motivating Example

keep consistency between decoupled objects

often used in the context of the MVC architectural pattern, more general, related to event

listeners

helps build a layered architecture

(4)

update() Observer

concreteSubject.get() attach(Observer)

detach(Observer) notify()

Subject

update()

ConcreteObserver observers

get() set(s) state

ConcreteSubject concreteSubject

state = s notify()

return state

for each o in observers o.update()

General Structure

knows its observers

provides interface for attaching and detaching observers

defines call-back operation to get notified

uses concrete subject’s get operations to pull

updated state

(5)

Applicability

Use the Observer pattern when

the abstraction has two aspects where one depends on the other. Encapsulating these aspects in separate objects will increase the chance to reuse them independently.

the subject doesn't know in advance how many observer objects it will have.

the subject should be able to notify its observer objects without knowing them.

(6)

Interactions

ConcreteSubject notifies its observers whenever a change to its internal state happens.

After a ConcreteObserver gets notified, it may query the subject state by using the get() method.

ConcreteObserver uses this information to change its own internal state.

(7)

Pros & Cons

Pros:

Decoupling of subject and observer, each can be extended and reused individually.

Dynamic addition and removal of observers at runtime.

Subject broadcasts notification automatically to all interested objects, no matter how many or which kind of observers are registered.

Cons:

May result in many notifications the observers are not interested in

Potentially difficult for the observers to figure out the specific state change of the subject.

(8)

Push vs. Pull Model

In its purest form, notification does not carry updated state information → Pull Model

Variant: notification contains updated state → Push Model

Pull Model Push Model

signature of notify operation

number of operation calls

unnecessarily exchanged state

information

independent of subject’s state

fields subject to modification if subject’s state fields are changed

higher lower

fewer more

(9)

Observer in Java

Call of notifyObservers without prior call of setChanged

has no effect!

update(Observable, Object)

<<interface>>

Observer + addObserver(Observer)

+ deleteObserver(Observer) + notifyObservers()

# setChanged()

Observable

update(Observable, Object) MyObserver

observers

getState() setState(s) state

MyObservable

state = s

setChanged() notifyObservers()

(10)

Observer in Java

Observable is a class.

What if our observable subject already has a super-class?

What aspects of inheritance are needed?

→ implementation inheritance, and

→ interface inheritance

SmartAdapter!

Can class Observable be delegated to?

→ No, because setChanged is protected.

Adapter & Delegation (see Implementation Reuse patterns)

(11)

Observer in Java: SmartAdapter

update(Observable, Object)

<<interface>>

Observer + addObserver(Observer)

+ deleteObserver(Observer) + notifyObservers()

# setChanged()

Observable

update(Observable, Object) MyObserver

observers

getState() setState(s) state

delegate

MyObservable MySuper

state = s

delegate.setChanged() delegate.notify()

+ setChanged() + getState() + setState(s) delegate

SmartObservableAdapter

delegate.setState(s)

return delegate.getState() super.setChanged()

(12)

Observer and Concurrency

Naive implementation of attach(), detach(), and notify()

public final class NaiveSubject {

private final Vector<Observer> observers;

...

public final void attach(Observer o) { observers.addElement(o);

}

public final void detach(Observer o) { observers.removeElement(o);

}

public final void notifyObservers() { for(Observer o : observers) {

o.update();

}

(13)

Observer and Concurrency

Vector is thread-safe, but NaiveSubject is not.

NaiveSubject will throw

ConcurrentModificationException if a thread adds or removes an observer while another notifies the observers.

Possible solutions:

Java Monitor Pattern (risky because of alien method call)

Use CopyOnWriteArrayList

Copy vector before iteration (this is how JDK Observable

does it)

(14)

Observer and Concurrency

Do not attach observer to subject inside observer’s constructor!

→ Otherwise the observer’s this reference escapes before the subject is fully constructed.

Reminder: In general, do not register a listener at an event source within listener’s constructor!

(15)

Relationship with other Patterns

MVC architectural pattern almost always uses Observer pattern.

(16)

Mediator

(17)

Motivation

Complex systems often require that the participating objects know each other.

This might end up in a nontransparent situation which is hard to understand.

The Mediator now supervises this communication.

It knows all the objects taking part and the objects are only aware of the mediator.

(18)

Description

Object based behavioral pattern

Purpose: Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by

keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.

Also Known As: Broker

(19)

Mediator Colleague

ConcreteMediator ConcreteColleague1 ConcreteColleague2 mediator

General Structure

Each colleague-class knows its broker-class

Each colleague-object works with its broker and not with the other colleague-objects

implements the general behavior by coordinating the colleague-objects

knows and manages its colleague-objects

defines an interface for the interaction with

colleague-objects

(20)

Applicability

Use the Mediator pattern when

there are many objects that have to work with each other, but the dependencies are unstructured and hard to

understand.

reusability of object is hard, because it has dependencies to many other objects.

a behavior that's distributed between several classes should be customizable without a lot of subclassing

(21)

Pros & Cons

Pro:

Limits subclassing

Decoupled colleague-objects

n:n-relations converted to 1:n-relations

Abstracts how the colleague-objects work with each other

Centralized control

Con:

Broker class might turn into a hard to maintain monolith

(22)

Relationship with other Patterns

Facade: Subsystem-classes don‘t know about the facade;

colleague-classes know their broker.

Colleague objects can notify the broker using the Observer pattern.

If the Mediator alters message then it is an Adapter pattern.

(23)

Memento

(24)

Description

Object based behavioral pattern

Purpose: Capture the internal state of an object without violating encapsulation and thus providing a mean for

restoring the object into initial state when needed.

Also Known As: Token

(25)

Description

Used for: Undo functionality

A Memento is an object which saves a snapshot of an originator’s internal state.

Only the originator has access to the state of the memento object.

(26)

return new Memento(state) CareTaker

getState()

setState(state) state

Memento

createMemento()

setMemento(Memento m) state

Originator memento

state = m.getState()

General Structure

Creates a memento object

capturing the originator’s internal state.

Use the memento object to restore its previous state.

The memento is opaque to the caretaker, and the caretaker

must not operate on it.

Saves the state information

Full access only from the originator

(27)

Interactions

:Caretaker :Originator aMemento:Memento

createMemento() new Memento() setState()

setMemento(aMemento)

getState()

(28)

Applicability

Use the Memento pattern if

an object's state must be captured so that it can be restored later on, and if

explicitly passing the state of the object would violate encapsulation.

(29)

Consequences

Preserves encapsulation.

CareTaker simplifies originator code.

Using the memento pattern can be expensive.

In some languages it is hard to ensure that only the

Originator can access the Memento’s state.

How can we ensure this in Java?

Make Memento an inner class of Originator

(30)

Ensure encapsulation in Java

public final class Originator { private int state;

public Memento createMemento() { return new Memento(state);

}

public void setMemento(Memento memento) { state = memento.getState();

}

public static final class Memento { private final int state;

private Memento(int state) { this.state = state;

}

private int getState() { return state;

private method of static inner class can be called by outer class

(31)

Relationship with other Patterns

Command objects can use mementos to maintain state for undoable operations.

Iterator can use memento objects to save state of iteration.

(32)

Strategy

(33)

Description

Object based behavioral pattern

Purpose: Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the

algorithm vary independent of clients that use it.

Also Known As: Policy

(34)

Motivating Example

@Immutable

public final class OriginalAIOpponent { private final Level skill;

public OriginalAIOpponent(Level skill) { this.skill = skill;

}

public void repelMove(int posX, int posY) { switch (skill) {

case LOUSY:

// do something break;

case ...

} }

public void printCoolSlogan() { switch (skill) {

case LOUSY:

// print something public enum Level {

LOUSY, STRONG;

}

(35)

Motivating Example

Options if we need to add a new skill level?

add case to Opponent class (easy to forget an occurrence)

create subclass of Opponent

outsource different behavior

(36)

Motivating Example

Define strategy interfaces:

public interface RepelStrategy {

void repelMove(int posX, int posY);

}

public interface SloganStrategy { void printCoolSlogan();

}

Sample implementation:

public class LousySloganStrategy implements SloganStrategy { @Override public void printCoolSlogan() {

System.out.println("Please don't hurt me!");

} }

(37)

Motivating Example

public class AIOpponent {

private final RepelStrategy repelStrategy;

private final SloganStrategy sloganStrategy;

public AIOpponent(RepelStrategy repelStrategy, SloganStrategy sloganStrategy) {

this.repelStrategy = repelStrategy;

this.sloganStrategy = sloganStrategy;

}

public void repelMove(int posX, int posY) { repelStrategy.repelMove(posX, posY);

}

public void printCoolSlogan() {

sloganStrategy.printCoolSlogan();

} }

AIOpponent o = new AIOpponent(

new LousyRepelStrategy(), new LousySloganStrategy());

(38)

Sample Structure

printCoolSlogan()

<<interface>>

SloganStrategy

sloganStrategy.printCoolSlogan()

printCoolSlogan()

LousySloganStrategy ContextInterface()

AIOpponent

printCoolSlogan()

StrongSloganStrategy sloganStrategy

(39)

AlgorithmInterface() Strategy

strategy.AlgorithmInterface()

AlgorithmInterface() ConcreteStrategyA ContextInterface()

Context

AlgorithmInterface() ConcreteStrategyB strategy

General Structure

gets configured with ConcreteStrategy object

may define interface that lets Strategy access its data

implements the algorithm using the Strategy interface

interface common to all supported algorithms

(40)

Applicability

Use the Strategy pattern when

many related classes differ only in their behavior. Strategies provide a way to configure a class with one of many

behaviors.

need of different variants of algorithms.

an algorithm uses data that clients shouldn’t know about

A class defines many behaviors (use of multiple conditional statements).

Remark: be aware of switch-case-statements, they have a smell

(41)

Interactions

A context forwards requests from its clients to its strategy.

Data handover:

A context may hand over all data required by the algorithm to the strategy method.

The context can pass itself as an argument to Strategy method.

(42)

Pros & Cons

Pro:

Re-usability of algorithms

An alternative to sub-classing of the context class

Choice of different implementations

Elimination of conditional statements

clean separation of different algorithms easier to test

Con:

Clients must be aware of different strategies

Communication overhead

Increased number of objects

(43)

Real World Examples

ThreadPoolExecutor gets RejectedExecutionHandler

object to decide strategy for tasks that cannot be executed (AbortPolicy, CallerRunsPolicy, DiscardOldestPolicy,

DiscardPolicy)

Java Comparator interface

Java AWT and Swing, e.g. paintBorder() method of

JComponent

(44)

Relationship with other Patterns

Flyweight can be used to implement strategy objects.

Referenzen

ÄHNLICHE DOKUMENTE

Aufgrund eines PSUR Follow-Up Assessments (PSU FU ) durch den Ausschuss für Risikobewertung im Bereich Pharmakovigilanz (PRAC), dessen Ergebnis durch das CMDh bestätigt wurde,

Der Zustand kann allerdings ¨ uber ein Netzwerk auch auf einen anderen Rech- ner ¨ubertragen werden, um dort ein gleiches Objekt zu instanziieren.

Clearly, there is a need to identify an enterprise management pattern which accommodates the requirements and objectives of business stakeholders, and which also ensures that the

Hinweis: Die Methode equals(Struct other) der Klasse Struct wird nur von den JUnit-Testfällen verwendet und prüft nicht die korrekte

5133 6G XX 600 x 420 mm, 20 kg für 3-Loch Armatur geeignet, mittleres Hahnloch durchgestochen, ohne Überlauf, Bei Modellen ohne Überlauffunktion muss ein nicht verschließbares

Katelyn Crossland 12 Logan-Rogersville Brianna Linehan 12 Logan-Rogersville. Lauren Tyler 11

The purpose of such categorization is the same as for the electrons: loose muons are input to the MVA that separates prompt leptons from non-prompt lepton; fakeable muons are used

Date of defence: 25.06.2020 Venue of defence: FHS UK, U Kříže 8, Praha 5- Jinonice Course of defence: Předseda komise představil uchazeči komisi.. Uchazeč