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

wikitmp_abstract_factory.png

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

wikitmp_builder.png

1.2.2 Sequence diagram

wikitmp_builder_sequence.png

1.2.3 Implementation

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

2 Structure

2.1 Singleton

class Singleton {
public:
  static Singleton* Instance() {
    if (m_instance == 0) {
      m_instance = new Singleton;
    }
    return m_instance;
  }
protected:
  Singleton();
private:
  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.

wikitmp_visitor-1.png

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.

wikitmp_visitor-2.png

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) {
            super(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

Validate