Design Pattern

Table of Contents

1 Creation

1.1 Abstract Factory

  • Implemented by Factory Method.
  • Focus on a family of products.
  • ConcreteFactory is often singleton


The implementation:

class AbstractFactory {
  virtual CreateA() {}
  virtual CreateB() {}
class ConcreteFactory1 {
  virtual CreateA() {new A1;}
  virtual CreateB() {new B2;}
class ConcreteFactory2 {
  virtual CreateA() {new A2;}
  virtual CreateB() {new B1;}
// client code
ConcreteFactory1 factory;
AbstractA *a = factory.CreateA();
AbstractB *b = factory.CreateB();

1.2 Builder

1.2.1 Class Diagram


1.2.2 Sequence diagram


1.2.3 Implementation

Director::Create() {
// client knows which concreteBuilder to use,
// so it knows which the product is
ConcreteBuilder builder;
director = Director(builder);

2 Structure

2.1 Singleton

class Singleton {
  static Singleton* Instance() {
    if (m_instance == 0) {
      m_instance = new Singleton;
    return m_instance;
  static Singleton* m_instance;

Singleton *Singleton::m_instance = 0;

3 Behavior Pattern

3.1 Visitor pattern

Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing theclasses of the elements on which it operates.

3.1.1 The problem and the naive solution

We have a list of classes in a class hierarchy, e.g. AST nodes. We want to define many operations, each operates different on different nodes.


This is not good. Application code is mixed with the AST node implementation.

3.1.2 The pattern

We define a hierarchy of visitors, and defines different behavior inside the visitors for different nodes they operate on. This is called double-dispatch: The virtual functions lookup is decided not only by the object the function is defined on, but also the arguments it accepts.


3.1.3 Example

public interface AST {
    public static abstract class ASTNode {
        public abstract Object accept(Visitor visitor);
    public static abstract class Exp extends ASTNode {

    public static class NumExp extends Exp {
        double _val;
        public Object accept(Visitor visitor) {
            return visitor.visit(this);
    public static class AddExp extends CompoundArithExp {
        public AddExp(List<Exp> args) {
        public Object accept(Visitor visitor) {
            return visitor.visit(this);
public class Evaluator implements Visitor<Value> {
    public Value visit(NumExp e) {
        return new NumVal(e.v());
    public Value visit(AddExp e) {
        List<Exp> operands = e.all();
        double result = 0;
        for (Exp exp : operands) {
            NumVal intermediate = (NumVal) exp.accept(this); // Dynamic
            // type-checking
            result += intermediate.v(); // Semantics of AddExp in terms of the
            // target language.
        return new NumVal(result);

Author: Hebi Li

Created: 2017-06-14 Wed 22:43