Behavioral design patterns are concerned with communication between objects, how objects interact and distribute responsibility.
graph TD
A[Behavioral Patterns] --> B[Chain of Responsibility]
A --> C[Command]
A --> D[Iterator]
A --> E[Mediator]
A --> F[Memento]
A --> G[Observer]
A --> H[State]
A --> I[Strategy]
A --> J[Template Method]
A --> K[Visitor]
B --> L[Passes request along chain]
C --> M[Encapsulates request as object]
D --> N[Accesses elements sequentially]
E --> O[Reduces direct object coupling]
F --> P[Captures object state]
G --> Q[Notifies dependents of changes]
H --> R[Alters object behavior]
I --> S[Encapsulates algorithms]
J --> T[Defines algorithm skeleton]
K --> U[Adds operations to class]
public abstract class Handler {
protected Handler successor;
public void setSuccessor(Handler successor) {
this.successor = successor;
}
public abstract void handleRequest(Request request);
}
public class ConcreteHandler extends Handler {
@Override
public void handleRequest(Request request) {
if (canHandle(request)) {
// Handle the request
} else if (successor != null) {
successor.handleRequest(request);
}
}
}
public interface Command {
void execute();
void undo();
}
public class ConcreteCommand implements Command {
private Receiver receiver;
public ConcreteCommand(Receiver receiver) {
this.receiver = receiver;
}
@Override
public void execute() {
receiver.action();
}
@Override
public void undo() {
receiver.undoAction();
}
}
public class Invoker {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void executeCommand() {
command.execute();
}
}
public interface Iterator<T> {
boolean hasNext();
T next();
}
public class ConcreteCollection<T> {
private List<T> items = new ArrayList<>();
public Iterator<T> getIterator() {
return new ConcreteIterator();
}
private class ConcreteIterator implements Iterator<T> {
private int index = 0;
@Override
public boolean hasNext() {
return index < items.size();
}
@Override
public T next() {
if (hasNext()) {
return items.get(index++);
}
throw new NoSuchElementException();
}
}
}
public interface Mediator {
void sendMessage(String message, Colleague colleague);
}
public abstract class Colleague {
protected Mediator mediator;
public Colleague(Mediator mediator) {
this.mediator = mediator;
}
public abstract void receive(String message);
}
public class ConcreteMediator implements Mediator {
private List<Colleague> colleagues = new ArrayList<>();
public void addColleague(Colleague colleague) {
colleagues.add(colleague);
}
@Override
public void sendMessage(String message, Colleague originator) {
for(Colleague colleague : colleagues) {
if (colleague != originator) {
colleague.receive(message);
}
}
}
}
public class Memento {
private final String state;
public Memento(String state) {
this.state = state;
}
public String getState() {
return state;
}
}
public class Originator {
private String state;
public void setState(String state) {
this.state = state;
}
public Memento saveStateToMemento() {
return new Memento(state);
}
public void restoreStateFromMemento(Memento memento) {
state = memento.getState();
}
}
public class Caretaker {
private List<Memento> mementoList = new ArrayList<>();
public void add(Memento state) {
mementoList.add(state);
}
public Memento get(int index) {
return mementoList.get(index);
}
}
public interface Observer {
void update(String message);
}
public class Subject {
private List<Observer> observers = new ArrayList<>();
private String state;
public void attach(Observer observer) {
observers.add(observer);
}
public void setState(String state) {
this.state = state;
notifyObservers();
}
private void notifyObservers() {
for(Observer observer : observers) {
observer.update(state);
}
}
}
public interface State {
void handle(Context context);
}
public class Context {
private State state;
public void setState(State state) {
this.state = state;
}
public void request() {
state.handle(this);
}
}
public class ConcreteStateA implements State {
@Override
public void handle(Context context) {
// Handle the state
context.setState(new ConcreteStateB());
}
}
public interface Strategy {
int execute(int a, int b);
}
public class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public int executeStrategy(int a, int b) {
return strategy.execute(a, b);
}
}
public class AddStrategy implements Strategy {
@Override
public int execute(int a, int b) {
return a + b;
}
}
public abstract class AbstractClass {
public final void templateMethod() {
step1();
step2();
hook();
}
protected abstract void step1();
protected abstract void step2();
protected void hook() {} // Optional hook
}
public class ConcreteClass extends AbstractClass {
@Override
protected void step1() {
// Implementation
}
@Override
protected void step2() {
// Implementation
}
}
public interface Visitor {
void visit(ConcreteElementA element);
void visit(ConcreteElementB element);
}
public interface Element {
void accept(Visitor visitor);
}
public class ConcreteElementA implements Element {
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
public class ConcreteVisitor implements Visitor {
@Override
public void visit(ConcreteElementA element) {
// Do something with element A
}
@Override
public void visit(ConcreteElementB element) {
// Do something with element B
}
}