《Head First设计模式》 策略模式 C++实现

    技术2024-07-10  81

    Head First设计模式 策略模式 C++实现

    书中简介:由各类鸭子去继承父类(Duck),然后再各自实现对应的fly()和quack()方法。类图如下: 这看起来还是不错的,用到了继承。可是当自定义的Duck类变得很多时,这种方法就显得太过笨拙了,因为这种方法没有最大程度地利用继承关系,从而提高代码复用。

    另一种方法,我们会想到利用接口来实现,看似不错,其实也没有提高效率,类图如下: 我们只是简单地把原本写在Duck类中的fly()和quack()方法抽离出来而已,这样的设计使得每个子类并没有摆脱需要overloading父类(接口)方法的束缚。

    我们转换思路,因为继承好像并不能减少代码量,我们想到另一种方法:组合(委托)。我们可以在Duck类中声明Duck类拥有FlyBehavior类型的flyBehavior指针和QuackBehavior类型的quackBehavior指针。这看起来很合理,因为只要是鸭子都会fly和quack,那么不妨在声明时就明确它。C++通过指针来实现委托(动态绑定),从而达到设计与实现行为分离的效果。类图如下: 这样设计有个好处,那就是Duck体系是不变的一方,即使有新类型的鸭子加入,都不会导致变化,我们只需要将新类型的Duck类丢到Duck框架里就好。因为Duck类已经把这两个成员变量委托给外界了,所以我们唯一需要改变的就是去实现每个FlyBehavior和QuackBehavior的动作。这样就形成了一静一动,更好了实现了解耦操作。

    实现代码:

    #include <iostream> using namespace std; // 飞行行为接口 class FlyBehavior { public: virtual void fly()=0; }; class FlyWithWings : public FlyBehavior { public: void fly() { cout << "Fly with wings" << endl; } }; class FlyNoWay : public FlyBehavior { public: void fly() { cout << "Fly no way" << endl; } }; // 呱呱叫行为接口 class QuackBehavior { public: virtual void quack()=0; }; class Quack : public QuackBehavior { public: void quack() { cout << "Quack" << endl; } }; class Squeak : public QuackBehavior { public: void quack() { cout << "squeak" << endl; } }; class MuteQuack : public QuackBehavior { public: void quack() { cout << "mutequack" << endl; } }; // 鸭子类 class Duck { private: FlyBehavior* flyBehavior; QuackBehavior* quackBehavior; public: Duck(FlyBehavior* fb, QuackBehavior* qb): flyBehavior(fb), quackBehavior(qb) {} virtual ~Duck() { delete flyBehavior; delete quackBehavior; } void perform_quack() { quackBehavior->quack(); } void perform_fly() { flyBehavior->fly(); } }; class GreenheadDuck : public Duck { public: GreenheadDuck(FlyBehavior* fb, QuackBehavior* qb): Duck(fb, qb) {} }; class RedheadDuck : public Duck { public: RedheadDuck(FlyBehavior* fb, QuackBehavior* qb): Duck(fb, qb) {} }; class RubberDuck : public Duck { public: RubberDuck(FlyBehavior* fb, QuackBehavior* qb): Duck(fb, qb) {} }; class WoodDuck : public Duck { public: WoodDuck(FlyBehavior* fb, QuackBehavior* qb): Duck(fb, qb) {} }; int main(int argc, char const* argv[]) { // 绿头鸭 Duck *green = new GreenheadDuck(new FlyWithWings(), new Quack()); // 红头鸭 Duck *red = new RedheadDuck(new FlyWithWings(), new Quack()); // 橡皮鸭 Duck *rubber = new RubberDuck(new FlyNoWay(), new Squeak()); // 木头鸭 Duck *wood = new WoodDuck(new FlyNoWay(), new MuteQuack()); green->perform_fly(); green->perform_quack(); cout << "----------------------------------------" << endl; red->perform_fly(); red->perform_quack(); cout << "----------------------------------------" << endl; rubber->perform_fly(); rubber->perform_quack(); cout << "----------------------------------------" << endl; wood->perform_fly(); wood->perform_quack(); cout << "----------------------------------------" << endl; return 0; }
    Processed: 0.019, SQL: 9