“把模式装进你的脑子里面,然后在你的设计和已有的应用中,寻找何处可以使用它们。”
a.策略模式:
假设有个Duck类,类中需要fly和quack接口,一个表示鸭子会飞,一个表示鸭子的叫声。如果需要产生一个橡皮鸭子,就需要从鸭子类继承产生,但是fly也会被继承下来。实际上橡皮鸭子被限制为不会飞(当然,也可以在橡皮鸭中,将fly接口重新实现。但是,实例仍然调用的是叫fly的接口,却使得橡皮鸭不能飞。有点矛盾!)。而且,当需要产生很多不同种的鸭子类型的时候,可能重新构造fly接口的工作很多,这导致了不必要的重复。
这样就导致了策略模式的产生:
定义:
策略模式作为一种软件设计模式,指对象有某个行为,但是在不同的场景中,这个行为有不同的实现算法。例如,播放器类中的播放行为,可以设置为不同的场景,如剧场,流行等等。
C++实现:(由于本人对C++比对JAVA熟悉一点,代码摘自维基百科。后面附自己想到的一个例子。)
#include <iostream> #include <string> #include <assert.h> using namespace std; //create abstract class class StrategyInterface { public: virtual void excute() = 0; /* data */ }; class ConcreteStrategyA : public StrategyInterface { public: virtual void excute() { cout << "This is ConcreteStrategyA." << endl; } /* data */ }; class ConcreteStrategyB : public StrategyInterface { public: virtual void excute() { cout << "This is ConcreteStrategyB." << endl; } /* data */ }; class ConcreteStrategyC : public StrategyInterface { public: virtual void excute() { cout << "This is ConcreteStrategyC." << endl; } /* data */ }; class Context { public: Context( StrategyInterface *strategy ):strategy( strategy ){} void SetStrategy( StrategyInterface *pStrategy ) { strategy = pStrategy; } void excute() { strategy->excute(); } private: StrategyInterface *strategy; /* data */ }; int main() { ConcreteStrategyA concreteStrategyA; ConcreteStrategyB concreteStrategyB; ConcreteStrategyC concreteStrategyC; Context contextA( &concreteStrategyA ); Context contextB( &concreteStrategyB ); Context contextC( &concreteStrategyC ); contextA.excute(); contextB.excute(); contextC.excute(); contextA.SetStrategy( &concreteStrategyB ); contextA.excute(); contextB.SetStrategy( &concreteStrategyC ); contextB.excute(); return 0; }
这个模式其实就是将行为抽象出来。我自己又根据这个策略,想到一个例子,例如播放MP3的时候,可以选择音乐的场景,究竟是流行,剧场,jazz还是其他。
class ScenarioInterface { public: virtual void play() = 0; /* data */ }; class Theatre : public ScenarioInterface { public: virtual void play() { cout << "Play music in the Theatre scenario." << endl; } /* data */ }; class Pop : public ScenarioInterface { public: virtual void play() { cout << "Play music in the pop scenario." << endl; } /* data */ }; class Classic: public ScenarioInterface { public: virtual void play() { cout << "Play music in the classic scenario." << endl; } /* data */ }; class Jazz : public ScenarioInterface { public: virtual void play() { cout << "Play music in the Jazz scenario." << endl; } /* data */ }; class Mp3 { public: Mp3( const string &name, ScenarioInterface *pSecn ) : songName( name ), scenario( pSecn ) { } ~Mp3() { } //modify the scenario void SetScenario( ScenarioInterface *pScen ) { scenario = pScen; } void PlayMusic() { cout << "The name of the song is :" << songName << "."<< endl; scenario->play(); } private: string songName; ScenarioInterface *scenario; /* data */ }; int main() { Pop pop; Theatre theatre; Classic classic; Jazz jazz; Mp3 mp3A( "I belive.", &pop ); mp3A.PlayMusic(); Mp3 mp3B( "In the end.", &theatre ); mp3B.PlayMusic(); Mp3 mp3C( "Numb.", &theatre ); mp3C.PlayMusic(); mp3C.SetScenario( &jazz ); mp3C.PlayMusic(); return 0; }