摘自<Design Paterns_Elements of Reusable Object-Oriented Software>
上一系列偏重于入门,从本篇开启进阶系列,着重于设计模式的适用情景。
回顾入门系列 设计模式入门(一) 策略模式
1 Intent
Define a family of algorithms, encapsulate each one, and make them interchangeable.
Strategy lets the algorithm vary independently from clients that use it.
2 Applicability
1) many related classes differ only in their behavior
= strategies provide a way to configure a class with one of many behaviors
2) you need different variants of an algorithm
= strategies can be used when these variants are implemented as a class hierarchy of algorithms
3) an algorithm uses data that clients should not know about
= use strategies to avoid exposing complex, algorithm-specific data structures
4) a class defines many behaviors, and these appear as multiple conditional statements in its operations
= move related conditional branches into their own strategy class
3 Sample
many algorithms exist for breaking a stream of text into lines, and hard-wiring such algorithms into the class that require them is not desirable.
C++ 实例:
1) class Composition
/* Composition class maintains a collection of Component instances */ class Composition { public: Composition(Compositor*); void Repair(); private: Compositor* _compositor; Component* _components; // the list of components int _componentCount; // the number of components int _lineWidth; // the Composition‘s line width int* _lineBreaks; // the position of linebreaks in components int _lineCount; // the number of lines }; void Composition::Repair () { Coord* natural; Coord* stretchability; Coord* shrinkability; int componentCount; int* breaks; // prepare the arrays with the desired component sizes // ... // determine where the breaks are: int breakCount; breakCount = _compositor->Compose( natural, stretchability, shrinkability, componentCount, _lineWidth, breaks ); // lay out components according to breaks // ... }
2) class Compositor and its subclasses
/* Compositor is an abstract class(also interface) */ class Compositor{ public: virtual int Compose( Coord natural[], Coord stretch[],Coord shrink[], int componentCount, int lineWidth, int breaks[] ) = 0; protected: Compositor(); }; /* Three subclasses */ class SimpleCompositor : public Compositor { public: SimpleCompositor(); virtual int Compose( Coord natural[], Coord stretch[], Coord shrink[], int componentCount, int lineWidth, int breaks[] ); // ... }; class TeXCompositor : public Compositor { public: TeXCompositor(); virtual int Compose( Coord natural[], Coord stretch[], Coord shrink[], int componentCount, int lineWidth, int breaks[] ); // ... }; class ArrayCompositor : public Compositor{ public: ArrayCompositor(int interval); virtual int Compose( Coord natural[], Coord stretch[], Coord shrink[], int componentCount, int lineWidth, int breaks[] ); // ... };
3) instantiation
Composition* quick = new Composition(new SimpleCompositor); Composition* slick = new Composition(new TeXCompositor); Composition* iconic = new Composition(new ArrayCompositor(100));