Looks like no one added any tags here yet for you.
Abstract Factory
Provide an interface for creating families of related objects without specifying their concrete classes.
interface GUIFactory {
Button createButton();
Checkbox createCheckbox();
}
class WinFactory implements GUIFactory {
public Button createButton() { return new WinButton(); }
public Checkbox createCheckbox() { return new WinCheckbox(); }
}
class MacFactory implements GUIFactory {
public Button createButton() { return new MacButton(); }
public Checkbox createCheckbox() { return new MacCheckbox(); }
}
// Client code:
GUIFactory factory = System.getProperty("os.name").contains("Win")
? new WinFactory() : new MacFactory();
Button btn = factory.createButton();
Checkbox cb = factory.createCheckbox();
btn.render();
cb.render();
Builder
Separate the construction of a complex object from its representation.
class House {
private String walls;
private String roof;
private String floor;
// setters/getters
}
interface HouseBuilder {
HouseBuilder buildWalls(String type);
HouseBuilder buildRoof(String type);
HouseBuilder buildFloor(String type);
House getResult();
}
class ConcreteHouseBuilder implements HouseBuilder {
private House house = new House();
public HouseBuilder buildWalls(String type) { house.setWalls(type); return this; }
public HouseBuilder buildRoof(String type) { house.setRoof(type); return this; }
public HouseBuilder buildFloor(String type) { house.setFloor(type); return this; }
public House getResult() { return house; }
}
// Director
class HouseDirector {
public House construct(HouseBuilder builder) {
return builder.buildWalls("Brick").buildRoof("Tile").buildFloor("Wood").getResult();
}
}
// Client code:
HouseDirector director = new HouseDirector();
House house = director.construct(new ConcreteHouseBuilder());
Factory Method
Define an interface for creating an object, let subclasses decide which class to instantiate.
abstract class Dialog {
// Factory method
abstract Button createButton();
public void render() {
Button okButton = createButton();
okButton.render();
}
}
class WindowsDialog extends Dialog {
Button createButton() { return new WinButton(); }
}
class WebDialog extends Dialog {
Button createButton() { return new HTMLButton(); }
}
// Client code:
Dialog dialog = new WindowsDialog();
dialog.render();
Prototyoe
Create new objects by cloning existing instances (prototypes).
interface Shape extends Cloneable {
Shape clone();
}
class Circle implements Shape {
int radius;
Circle(int r) { this.radius = r; }
public Shape clone() {
return new Circle(this.radius);
}
}
// Client code:
Circle original = new Circle(10);
Circle copy = (Circle)original.clone();
Singleton
Ensure a class has only one instance and a global point of access.
class Logger {
private static Logger instance;
private Logger() {}
public static synchronized Logger getInstance() {
if (instance == null) {
instance = new Logger();
}
return instance;
}
public void log(String message) { System.out.println(message); }
}
// Client code:
Logger.getInstance().log("This is a singleton logger.");
Adapter
Converts one interface to another expected by the client.
interface MediaPlayer { void play(String file); }
class AdvancedMediaPlayer { void playMp4(String file) { /* ... */ } }
class MediaAdapter implements MediaPlayer {
private AdvancedMediaPlayer advanced = new AdvancedMediaPlayer();
public void play(String file) {
// adapt the call
advanced.playMp4(file);
}
}
// Client code:
MediaPlayer player = new MediaAdapter();
player.play("movie.mp4");
Bridge
Separate an abstraction from its implementation, so both can vary independently.
interface Device {
void powerOn();
void powerOff();
void setVolume(int percent);
}
class TV implements Device {
// Implementation details...
}
class Radio implements Device {
// Implementation details...
}
abstract class RemoteControl {
protected Device device;
RemoteControl(Device d) { this.device = d; }
abstract void togglePower();
abstract void volumeUp();
}
class BasicRemote extends RemoteControl {
BasicRemote(Device d) { super(d); }
void togglePower() { /* calls device.powerOn()/powerOff() */ }
void volumeUp() { /* calls device.setVolume() */ }
}
// Client code:
Device tv = new TV();
RemoteControl remote = new BasicRemote(tv);
remote.togglePower();
Composite
Treat individual objects and compositions of objects uniformly.
interface Graphic {
void draw();
}
class Dot implements Graphic {
public void draw() { System.out.println("Draw a dot."); }
}
class CompoundGraphic implements Graphic {
private List<Graphic> children = new ArrayList<>();
public void add(Graphic g) { children.add(g); }
public void draw() {
for (Graphic g : children) g.draw();
}
}
// Client code:
CompoundGraphic group = new CompoundGraphic();
group.add(new Dot());
group.add(new Dot());
group.draw(); // Draw all children
Decorator
Add responsibilities to objects dynamically without altering their class.
interface Notifier {
void send(String message);
}
class EmailNotifier implements Notifier {
public void send(String message) { System.out.println("Email: " + message); }
}
class SMSDecorator implements Notifier {
private Notifier wrappee;
SMSDecorator(Notifier notifier) { this.wrappee = notifier; }
public void send(String message) {
wrappee.send(message);
System.out.println("SMS: " + message);
}
}
// Client code:
Notifier notifier = new SMSDecorator(new EmailNotifier());
notifier.send("Hello!");
Facade
Provide a simplified interface to a complex subsystem.
class ComplexSystem {
void start() {}
void loadData() {}
void processData() {}
void stop() {}
}
class Facade {
private ComplexSystem system = new ComplexSystem();
public void doWork() {
system.start();
system.loadData();
system.processData();
system.stop();
}
}
// Client code:
Facade facade = new Facade();
facade.doWork(); // Simplified call
Flyweight
Use sharing to support a large number of fine-grained objects efficiently.
// Flyweight: shared state for a character glyph
class Glyph {
private char character;
Glyph(char c) { this.character = c; }
public void draw(int position) { System.out.println(character + " at " + position); }
}
class GlyphFactory {
private Map<Character, Glyph> cache = new HashMap<>();
public Glyph getGlyph(char c) {
return cache.computeIfAbsent(c, Glyph::new);
}
}
// Client code:
GlyphFactory factory = new GlyphFactory();
String text = "Hello";
for (int i = 0; i < text.length(); i++) {
Glyph g = factory.getGlyph(text.charAt(i));
g.draw(i);
}
Proxy
Provide a placeholder that controls acacess to another object.
interface Image {
void display();
}
class RealImage implements Image {
private String filename;
RealImage(String f) { this.filename = f; loadFromDisk(); }
private void loadFromDisk() { /* ... */ }
public void display() { System.out.println("Displaying " + filename); }
}
class ImageProxy implements Image {
private String filename;
private RealImage realImage;
ImageProxy(String f) { this.filename = f; }
public void display() {
if (realImage == null) {
realImage = new RealImage(filename);
}
realImage.display();
}
}
// Client code:
Image image = new ImageProxy("photo.jpg");
image.display(); // Loads on first display only
Chain of Responsibility
Pass requests along a chain of handlers until one handles it.
abstract class Handler {
protected Handler next;
public Handler linkWith(Handler next) { this.next = next; return this; }
public void handle(String request) {
if (!doHandle(request) && next != null) {
next.handle(request);
}
}
protected abstract boolean doHandle(String request);
}
class AuthHandler extends Handler {
protected boolean doHandle(String request) {
if (request.equals("authenticated")) {
System.out.println("AuthHandler handled request");
return true;
}
return false;
}
}
class LoggingHandler extends Handler {
protected boolean doHandle(String request) {
System.out.println("LoggingHandler logs: " + request);
return false;
}
}
// Client code:
Handler chain = new AuthHandler().linkWith(new LoggingHandler());
chain.handle("authenticated"); // AuthHandler handles
chain.handle("something else"); // Auth fails, LoggingHandler logs it
Command
Encapsulate a request as an object, enabling undo/redo and paramterization.
interface Command {
void execute();
}
class Light {
void on() { System.out.println("Light on"); }
void off() { System.out.println("Light off"); }
}
class LightOnCommand implements Command {
private Light light;
LightOnCommand(Light l) { this.light = l; }
public void execute() { light.on(); }
}
// Invoker
class RemoteControl {
private Command command;
void setCommand(Command c) { this.command = c; }
void pressButton() { command.execute(); }
}
// Client code:
Light light = new Light();
Command onCommand = new LightOnCommand(light);
RemoteControl remote = new RemoteControl();
remote.setCommand(onCommand);
remote.pressButton();
Interpreter
Define a grammar and interpret statements in that language.
interface Expression {
boolean interpret(String context);
}
class TerminalExpression implements Expression {
private String data;
TerminalExpression(String d) { this.data = d; }
public boolean interpret(String context) {
return context.contains(data);
}
}
// Combined expressions
class AndExpression implements Expression {
private Expression expr1, expr2;
AndExpression(Expression e1, Expression e2) { expr1 = e1; expr2 = e2; }
public boolean interpret(String context) {
return expr1.interpret(context) && expr2.interpret(context);
}
}
// Client code:
Expression isJava = new TerminalExpression("Java");
Expression isPattern = new TerminalExpression("Pattern");
Expression isJavaPattern = new AndExpression(isJava, isPattern);
System.out.println(isJavaPattern.interpret("Java Design Pattern")); // true
Iterator
Access elements of a collection sequentially without exposing internal details.
class CustomCollection implements Iterable<String> {
private List<String> items = Arrays.asList("A", "B", "C");
public Iterator<String> iterator() {
return items.iterator();
}
}
// Client code:
CustomCollection collection = new CustomCollection();
for (String s : collection) {
System.out.println(s);
}
Mediator
Encapsulate how objects interact, promoting loose coupling.
class Mediator {
private Button button;
private TextBox textBox;
void setComponents(Button b, TextBox t) {
this.button = b;
this.textBox = t;
}
public void buttonClicked() {
textBox.showMessage("Button was clicked!");
}
}
class Button {
Mediator mediator;
Button(Mediator m) { mediator = m; }
void click() { mediator.buttonClicked(); }
}
class TextBox {
void showMessage(String msg) { System.out.println("TextBox: " + msg); }
}
// Client code:
Mediator mediator = new Mediator();
Button button = new Button(mediator);
TextBox textBox = new TextBox();
mediator.setComponents(button, textBox);
button.click(); // Mediator coordinates interaction
Memento
Capture the object’s internal state to restore it later without violating encapsulation.
class Editor {
private String text;
public void setText(String t) { this.text = t; }
public String getText() { return text; }
public Memento save() { return new Memento(text); }
public void restore(Memento m) { this.text = m.getState(); }
static class Memento {
private final String state;
Memento(String s) { state = s; }
private String getState() { return state; }
}
}
// Client code:
Editor editor = new Editor();
editor.setText("Version 1");
Editor.Memento m = editor.save();
editor.setText("Version 2");
editor.restore(m); // back to "Version 1"
Observer
Define a one-to-many dependency between objects so that when one changes state, all are notified.
interface Observer {
void update(String data);
}
class Subject {
private List<Observer> observers = new ArrayList<>();
private String state;
void attach(Observer o) { observers.add(o); }
void setState(String s) {
state = s;
notifyAllObservers();
}
private void notifyAllObservers() {
for (Observer o : observers) o.update(state);
}
}
class ConcreteObserver implements Observer {
public void update(String data) { System.out.println("Observer got: " + data); }
}
// Client code:
Subject subject = new Subject();
subject.attach(new ConcreteObserver());
subject.setState("New State"); // Observers notified
State
Allow an object to change its behavior when its internal state changes.
interface State {
void handle(Context c);
}
class Context {
private State state;
Context(State s) { this.state = s; }
void setState(State s) { this.state = s; }
void request() { state.handle(this); }
}
class ConcreteStateA implements State {
public void handle(Context c) {
System.out.println("State A handling, switching to B");
c.setState(new ConcreteStateB());
}
}
class ConcreteStateB implements State {
public void handle(Context c) {
System.out.println("State B handling, switching to A");
c.setState(new ConcreteStateA());
}
}
// Client code:
Context context = new Context(new ConcreteStateA());
context.request(); // State A -> B
context.request(); // State B -> A
Strategy
Define a family of algorithms, encapsulate them, and make them interchaneable.
interface Strategy {
int doOperation(int a, int b);
}
class Addition implements Strategy {
public int doOperation(int a, int b) { return a + b; }
}
class ContextStrategy {
private Strategy strategy;
ContextStrategy(Strategy s) { this.strategy = s; }
public int execute(int a, int b) { return strategy.doOperation(a, b); }
}
// Client code:
ContextStrategy contextStrategy = new ContextStrategy(new Addition());
System.out.println(contextStrategy.execute(2, 3)); // 5
Template Method
Define an algorithm’s skeleton and let subclasses override certain steps.
abstract class Game {
final void play() {
start();
playTurn();
end();
}
abstract void start();
abstract void playTurn();
abstract void end();
}
class Chess extends Game {
void start() { System.out.println("Chess starts"); }
void playTurn() { System.out.println("Chess turn played"); }
void end() { System.out.println("Chess ends"); }
}
// Client code:
Game game = new Chess();
game.play();
Visitor
Separate operations from the objects on which they operate, allowing you to add new operations without modifying the objects.
interface Element {
void accept(Visitor v);
}
class ConcreteElementA implements Element {
public void accept(Visitor v) { v.visit(this); }
String operationA() { return "A"; }
}
class ConcreteElementB implements Element {
public void accept(Visitor v) { v.visit(this); }
String operationB() { return "B"; }
}
interface Visitor {
void visit(ConcreteElementA a);
void visit(ConcreteElementB b);
}
class ConcreteVisitor implements Visitor {
public void visit(ConcreteElementA a) { System.out.println("Visitor on A: " + a.operationA()); }
public void visit(ConcreteElementB b) { System.out.println("Visitor on B: " + b.operationB()); }
}
// Client code:
List<Element> elements = Arrays.asList(new ConcreteElementA(), new ConcreteElementB());
Visitor visitor = new ConcreteVisitor();
for (Element e : elements) {
e.accept(visitor);
}