Loading... 或许是命中注定,我一个热爱硬件的电路狗,怎么就去了软件公司码代码。毕竟不是科班出身,很多东西都没有学过,还是需要恶补的,比如设计模式。设计模式最经典的应该是四人帮的那本《设计模式-可复用面向对象基础》,里面从理论的高度讲述了23个设计模式,然而我实在编码太少,无法理解该书的精妙,还是要找一本通俗易懂的书学习一个。于是,我找到了《Head First设计模式》,形象、生动,配以简单的案例,起码让我对设计模式没有了恐惧感,增强了好奇心。然而好记性不如烂笔头,加上例程都是JAVA的,而我没有学过JAVA,于是决定用C++重新实现了各章的内容,算是复习了吧。 废话写了一堆,还是进入正题。这本书所讲的第一个设计模式是策略模式(Strategy)。所谓策略模式,就是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换,让算法独立于使用它的客户而独立变化。具体来说,就是针对不同类型的对象,需要用不同的策略去处理(**找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起,把会变化的部分取出并封装起来,好让其他部分不会受到影响**),为了确保策略与客户端互不影响,就设计一个单独的策略类,并以此为基类,产生各种策略(**针对接口编程,而不是针对实现编程**)。而在客户端使用策略时,不采用继承的思路(**多用组合,少用继承**),而是将策略通过组合的方式整合到客户端中,以实现策略和客户端的相互独立。下图就是书中鸭子例子的UML类图。 ![](http://blog.lxalxy.com/usr/uploads/2021/03/718665135.jpg) 利用C++实现的Duck例子如下,偷了个懒,都放在了主文件内。 ```cpp hljs #include "stdafx.h" #include<iostream> using namespace std; //*******************飞行行为抽象类*********************// class FlyBehavior { public: FlyBehavior() {}; virtual ~FlyBehavior() { cout << "~FlyBehavior()" << endl; } virtual void Fly() = 0; }; //*******************鸣叫行为抽象类*********************// class QuackBehavior { public: QuackBehavior() {}; virtual ~QuackBehavior() { cout << "~QuackBehavior()" << endl; } virtual void Quack() = 0; }; //*******************飞行行为实现*********************// class FlyWithWings : public FlyBehavior { public: FlyWithWings() {}; virtual ~FlyWithWings() { cout << "~FlyWithWings()" << endl; } void Fly(); }; void FlyWithWings::Fly() { cout << "Fly with Wings!" << endl; } class FlyNoWay : public FlyBehavior { public: FlyNoWay() {}; virtual ~FlyNoWay() { cout << "~FlyNoWay()" << endl; } void Fly(); }; void FlyNoWay::Fly() { cout << "I can't fly!" << endl; } //*******************鸣叫行为实现*********************// class QuackQuack : public QuackBehavior { public: QuackQuack() {}; virtual ~QuackQuack() { cout << "~QuackQuack()" << endl; } void Quack(); }; void QuackQuack::Quack() { cout << "Quack! Quack!" << endl; } class MuteQuack : public QuackBehavior { public: MuteQuack() {}; virtual ~MuteQuack() { cout << "~MuteQuack()" << endl; } void Quack(); }; void MuteQuack::Quack() { cout << "I can't Quack!" << endl; } class Squeak : public QuackBehavior { public: Squeak() {}; virtual ~Squeak() { cout << "~Squeak()" << endl; } void Quack(); }; void Squeak::Quack() { cout << "Squeak! Squeak!" << endl; } //*******************Duck基类*********************// class Duck { public: Duck() {}; virtual ~Duck(); virtual void display() = 0; void performQuack(); void performFly(); void setFlyBehavior(FlyBehavior * flyBehavior); void setQuackBehavior(QuackBehavior * quackBehavior); protected: FlyBehavior * m_flyBehavior; QuackBehavior * m_quackBehavior; }; Duck::~Duck() { if (m_flyBehavior != NULL) { delete m_flyBehavior; } if (m_quackBehavior != NULL) { delete m_quackBehavior; } cout << "~Duck()" << endl; } void Duck::performQuack() { m_quackBehavior->Quack(); } void Duck::performFly() { m_flyBehavior->Fly(); } void Duck::setFlyBehavior(FlyBehavior * flyBehavior) { cout << "I'm changing the fly behavior!" << endl; m_flyBehavior = flyBehavior; } void Duck::setQuackBehavior(QuackBehavior * quackBehavior) { cout << "I'm changing the quack behavior!" << endl; m_quackBehavior = quackBehavior; } //*******************各Duck子类*********************// class MallardDuck : public Duck { public: MallardDuck(); virtual ~MallardDuck() { cout << "~MallardDuck()" << endl; } void display(); }; MallardDuck::MallardDuck() { m_flyBehavior = new FlyNoWay; m_quackBehavior = new QuackQuack; } void MallardDuck::display() { cout << "I'm a MallardDuck!" << endl; } class RubberDuck : public Duck { public: RubberDuck(); virtual ~RubberDuck() { cout << "~RubberDuck()" << endl; } void display(); }; RubberDuck::RubberDuck() { m_flyBehavior = new FlyNoWay; m_quackBehavior = new Squeak; } void RubberDuck::display() { cout << "I'm a RubberDuck!" << endl; } class DecoyDuck : public Duck { public: DecoyDuck(); virtual ~DecoyDuck() { cout << "~DecoyDuck()" << endl; } void display(); }; DecoyDuck::DecoyDuck() { m_flyBehavior = new FlyNoWay; m_quackBehavior = new MuteQuack; } void DecoyDuck::display() { cout << "I'm a DecoyDuck!" << endl; } class RedheadDuck : public Duck { public: RedheadDuck(); virtual ~RedheadDuck() { cout << "~RedheadDuck()" << endl; } void display(); }; RedheadDuck::RedheadDuck() { m_flyBehavior = new FlyWithWings; m_quackBehavior = new QuackQuack; } void RedheadDuck::display() { cout << "I'm a RedheadDuck!" << endl; } int main() { Duck * testMallard = new MallardDuck(); testMallard->display(); testMallard->performFly(); testMallard->performQuack(); testMallard->setQuackBehavior(new MuteQuack()); testMallard->performQuack(); cout << "-------------------------" << endl; Duck * testRedhead = new RedheadDuck(); testRedhead->display(); testRedhead->performFly(); testRedhead->performQuack(); testRedhead->setFlyBehavior(new FlyNoWay()); testRedhead->performFly(); cout << "-------------------------" << endl; delete testMallard; cout << "-------------------------" << endl; delete testRedhead; return 0; } ``` 可以看到,通过策略模式,可以方便的动态改变Duck的行为,不过策略模式也存在着自身的缺点,那就是客户需要知道所有的策略类(策略类数量可能很多),并且理解策略类的含义。 © 允许规范转载 赞 如果觉得我的文章对你有用,请随意赞赏