Design Patterns with Java Examples

Design Patterns with Java Examples.

Interface Driven Patterns

Strategy Pattern / Bridge Pattern

This pattern is one of the incarnation of Dependency Injection.

class StrategyContext {
    private Strategy strategy;
    public StrategyContext(Strategy strategy) {
        this.strategy = strategy;
    }

    public boolean run(String[] args) {
        return this.strategy.run(args)
    }
}

Strategy can be either interface or abstract class. This pattern helps to hide the implementation details from the method callers, and it's just a simple illustration of interface-oriented programming.

Note StrategyContext doesn't implement Strategy interface.

Proxy Pattern

class StrategyProxy implements Strategy {
    private Strategy strategy;
    public StrategyProxy() {
        this.strategy = new ConcreteStrategy();
    }

    @Override
    public boolean run(String[] args) {
        return this.strategy.run(args);
    }
}

This pattern is quite similar to the Strategy Pattern except that here the strategy details are hidden from the proxy dependents, however in Strategy Pattern the concrete strategy is injected through the constructor.

Note both StrategyProxy and ConcreteStrategy have implement the Strategy interface.

Decorator Pattern

This pattern helps to add more functionalities without changing the original target instance.

Adaptor Pattern

The implementation of Adaptor Pattern is the same as that of Proxy Pattern while with different goal.

Note only BeggerAdaptor has implemented the Worker interface.

Factory Patterns

Singleton Pattern

There are multiple implementation methods for Singleton Pattern in Java as listed here - Java Singleton Design Pattern Best Practices with Examples. My favorite one is Bill Pugh Singleton Implementation, because it's concise and thread-safe.

Simple Factory Pattern

OperationAdd and OperationMinus classes implement Operation interface.

Note that from my perspective of view Factory Pattern and Abstract Factory Pattern don't provide much value to simplify the program or make the logic clearer, so that I would prefer not to introduce them here.

Flyweight Pattern

This pattern is to reduce the cost of resource on recreating instances, one common example is Java String.

In Java the strings with the same value are actually refering to the same underlying object. Although the resource used by creating a string is not substantial, because the number of operations is large, it still impact tremendously on the program overall.

Note that in Simple Factory Pattern a new object is always returned, however in FlyWeight Pattern, only when there is no such instance will a new object be created and returned.

Builder Pattern

Here we set the options for the builder and finally it will create the instance based on the requirement.

Prototype Pattern

It's just to implement the Cloneable interface in java. Note that if you want to create a immutable class, you should follow How to create Immutable class in Java? and use deep copy instead of shallow copy.

Changing Context

Chain of Responsibility Pattern

And there is another more common pattern which is widely used in servlet,

In this way the handlers don't have to the successor of itself.

States Pattern

Please check this awesome article about Deterministic Finite Automation (DFA) from Leetcode or LeetCode——8.字符串转整数(atoi).

In this way the business logic for different states is implemented in the related State, and the correlation between different business units is reduced.

other implementations:

Example for the 3 implementation of State Pattern - Example.

Interpreter Pattern

Here the concrete Expression classes will interpret the context accordingly. This pattern can be used in syntax tree (I don't quite understand this, anyone can give an illustration?).

Visitor Pattern

Visitor Pattern

This pattern encapsulates the elements inside an Entirety object and allows the Visitor instances to visit it's internal elements.

Others

Template Pattern

The target for this pattern is DRY - Don't Repeat Yourself.

Facade Pattern

This pattern is to reduce the complexity of the interface that an external dependent needs to know.

Observer Pattern

Memo Pattern

This pattern is quite common in frontend application when preparing the data to be submitted to the backend.

Composite Pattern

Composite Pattern combines objects into a tree structure to represent the "part-whole" hierarchy.

Actually it's a preorder tree traversal which can be implemented as

Iterator Pattern

In Java there are Iterator<T> interface and Iterable<T> interface. The Iterable<T> requires an implementation of Iterator<T> iterator(); to return an Iterator<T> object. The Iterator<T> requires the implementation of boolean hasNext(); and T next(); methods.

Mediator Pattern

Here the implementation is one to one, obviously the business case might be many-to-many, and then the logic wrapped inside the mediator would be more complicated.

Principles

SRP

Single Responsibility Principle.

Open-Close Principle

  • Open to extension

  • Closed to modification

Dependency Inversion Principle

Interface-oriented programming.

LoD Principle

The Law of Demeter (LoD) or principle of least knowledge is a design guideline for developing software, particularly object-oriented programs.

Last updated

Was this helpful?