Design Pattern - Behavioral
Iterator (object level)
- Intent
- Access every element in a data structure sequentially
- Hide the underlying implementation
- Motivation
- Reuse algorithms independent of the underlying structure
- Benefits
- Simplify the aggregate interfaces
- Limitations
- Some implementation might not be robust
// Iterator
class CIterator {
public:
virtual void First() = 0;
virtual void Next() = 0;
virtual bool HasNext() = 0;
virtual CItem &Get() = 0;
}
class CContainer {
public:
virtual CIterator *CreateIterator() = 0;
}
class CConcreteContainer : public CContainer {
public:
CIterator *CreateIterator() {
return new CConcreteIterator(this);
}
}
public class Container implements Iterable<Item> {
private static class Iterator implements java.util.Iterator<Item> {
private int current;
private final int end;
public Iterator(final int start, final int stop) {
this.current = start;
this.stop = stop;
}
public Item Get() {
return this.current;
}
public void Next() {
this.current++;
}
public boolean hasNext() {
return this.current <= this.end;
}
}
}
State (object level)
- Intent
- Object behavior is dependent upon an internal state
- Object appear to change class
- Motivation
- Network connection has multiple states
- Programs has multiple modes
- Benefits
- Localizes state-specific behavior
- Partitions behavior for each state
- Make state transit explicit
- Limitations
- Minimal performance hit
// Context
class CContext {
protected:
int DState;
CState *DComplexState;
public:
CContext() {
DComplexState = CConcreteStateX::Instance();
}
void Request() {
switch(DState) {
case 0: //something
break;
case 1: //something else
break
// ...
default: // ...
break;
}
}
void ComplexRequest() {
DComplexState->Handle(this);
}
void SwitchState(CState *s) {
DComplexState = s;
}
}
// State
class CState {
public:
virtual void Handle(CContext *c) = 0;
}
class CConcreteStateX : public CState {
protected:
CConcreteStateX() {};
static CState *DUnique;
public:
void Handle(CContext *c){
// perform operation for this specific state according to the context
c->SwitchState(CConcreteStateY::Instance()); // move to next state
}
static CState *Instance() {
if (nullptr == DUnique) {
DUnique = new CConcreteStateX();
}
return DUnique;
}
}
Observer (object level)
- Intent
- Motivation
- Problem
- Alternative solution
- Benefits
- Limitations
Visitor (object level)
- Intent
- Motivation
- Problem
- Alternative solution
- Benefits
- Limitations
Command (object level)
Used for callback functions, from C++ 11 it’s possible to bind a callable obj (operator()
overridden) to something
- Intent
- encapsulate a request as an object
- allows for undoable operations
- Motivation
- Problem
- develop a file editing and record macros for later reply (be also able to undo actions)
- Alternative solution
- store command as values and use large switch statement (too big to maintain)
- Benefits
- decouples the invoking obj from action obj
- manipulated and extended
- assemble commands into composite command
- easy to add new commands
- Limitations
Chain of Responsibility (object level)
- Intent
- decouple sender of req form receiver, allow for more than one obj to handle the req
- chain the receiving obj and pass the req along
- Motivation
- Problem
- develop a help system that is context sensitive. Such help linked depends upon where clicked on
- Alternative solution
- Benefits
- reduce coupling (both receiver and server)
- flexibly add responsibility to object
- Limitations
- receipt is not guaranteed
- could have mishandled requests
Memento (object level)
- Intent
- capture and externalize object’s internal
- Motivation
- Problem
- Alternative solution
- Benefits
- Limitations
Notes
- PIMPL (Pointer to Implementation): could be an alternative to memento