Design Pattern 軟體工程與哲學

Design Pattern 設計模式學習筆記 (四)

Command Pattern
As you request an object to do some task, the object itself has no idea about the task before you tell it. The pattern makes the task (or command) into a class. The points about the pattern are:
# class ConcreteCommand inherits from class Command, and must implements
the Execute method.
# class ConcreteCommand has a reference of the receiving object. When the Execute method is called, the receiver acts as the ConcreteCommand designs.
# the creation and execution of a command can be at different time.
# the functionality of undo can be considered in the pattern.

Interpreter Pattern
Its general usage is to parse a string. When a sentence comes, a pattern parses it, and see if the sentence matches the pattern.

In some level I think it is OK to think this pattern as the Composite Pattern. There are some things to note:
# the abstract and concrete classes should have the method Interpret.
# a general return data type for the Interpret method is bool. It returns true if the sentence matches the expression.
# theoretically, if you have lots of expression in your database, you will also need to create this number of expressions.

Iterator Pattern

Just think of the STL iterators, but the functionalities of a customized iterator can vary. I don’t temporally address too much on this pattern.

Mediator Pattern
As the name, Mediator is to mediate the couplings between different objects. Especially when a object changes, the Mediator changes other objects. So basically, all the Concrete Colleagues should have the access to the Mediator, and the Mediator should have the access to all the Concrete Colleagues.

Memento Pattern
Doesn’t have inheritance hierarchies. Instead, it emphasizes on the interaction of objects.
1. the client asks the Originator to create a Memento, which can belong to the client.
2. when the client needs the Originator to go back to a certain time, it calls Originator::setMemento, where the input is the Memento created before.

Observer Pattern
Participating classes: Subject and multiple Observers.

As needed, the subject notifies all the observer to update. Compared to Mediator pattern, if regarding the mediator as observer, then the number of observers is only one. However, it can also take the mediator as subject. In this case, the observers become the role of Concrete Colleagues. But personally, in the view of semantics, regarding observer as a mediator is better. 

Take OGRE SampleContext for example, SampleContext inherits from OIS::KeyListener and OIS::MouseListener, and implements the key and mouse event handling in it. In this case, SampleContext is an observer. In other words, it can be said to be an Observer Pattern that you register some observer classes to a subject class at the beginning, and the subject automatically updates the observers when necessary.

State Pattern
Simply delegates some state-dependent work to the State class. So your module may have a State reference, which can be State1, State2, etc. There are two points needed to note:
# the State reference in your module can and should change.
# use State pattern to avoid a large if-else or switch-case chain.

Strategy Pattern
Personally I think it’s just delegation. In a system, you might want to delegate a job to StrategyA, but in other cases, you might want delegate a job to StrategyB. Sometimes the pattern is used to switch the algorithms in your module.

Template Method
Template Method is a function in your class that defines the steps of certain work. However, the class doesn’t “implement” the step functions (leave them empty), and the implementation is done by sub-classes. However, the implementation can also be delegated using the Strategy Pattern, so I think the emphasis of Template Method Pattern is to fix the steps in a template method.

Visitor Pattern
I would say the pattern is also a kind of delegation. In this pattern you have a group of elements and visitors. Each element must implement the accept function, whose input is a visitor. Besides, each visitor must implement the visitElementX function (e.g., visitElementA, visitElementB, etc) depending on how many elements you have.

In an element’s accept function, the element has no idea of what to do, and just calls the visitor’s visitElementX function. Note that the input of the visitElementX function is such element, so the code is something like: visitor->visitElementA(this);

Let’s see an example. There is a game that different people walk on a map, and events might arise when a person is at certain place. In this case, “place” is the element, and “person” is the visitor.

[1] “Design Patterns”, Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides.