第二章-场景模式

第二章-场景模式,第1张

第二章-场景模式 1. 设计原型 - a Duck

说明:

  1. 我们假设所有的Duck叫声都一样,quack~~,游泳的姿态也相同~~

  2. 每种Duck的外型特征彼此不同 ~~

  3. 图示中斜体文字表示, 函数被virtual xxx = 0 关键字所声明,为抽象接口。对应的代码如下,以后不再追加代码。

    #include 
    
    using namespace std;
    
    class Duck
    {
        public:
        
    	virtual void quack(void)
    	{
    		cout << "all Ducks quack" << endl;
    	}
    	virtual void swim(void)
    	{
    		cout << "all Ducks swim" << endl;
    	}
    	virtual void display(void) = 0;
    };
    
    class MallardDuck : public Duck
    {
        public:
        
        void display (void)
        {
            cout << "A MallardDuck display" << endl;
        }
    };
    
    class RedheadDuck  : public Duck
    {
        public:
        void display (void)
        {
            cout << "A RedheadDuck display" << endl;
        }
    };
    
    int main()
    {
        MallardDuck  aMallardDuck;
        RedheadDuck  aRedheadDuck;
        
        aRedheadDuck.quack();
        aMallardDuck.quack();
        
        aRedheadDuck.display();
        aMallardDuck.display();
        return 0;
    }
    
    ————————————————————————打印输出———————————————
    all Ducks quack
    all Ducks quack
    A RedheadDuck display
    A MallardDuck display
    
2. 设计原型的改进-飞行能力

**需求:**我们需要为Duck 添加飞行功能的支持

方案: 基类Duck中添加fly接口,这样所有子类都具备了fly的能力

virtual void Ducks::fly(void)
{
	cout << "all Ducks fly" << endl;
}

**问题:**考虑橡胶制成的小鸭子,它应该具有飞行能力吗?
橡胶Duck不具备飞行能力,所以这个设计有问题

3. 小节2 提出的问题的修改提案

方案1:
virtual void Ducks::fly(void); 可以在RubberDuck中override 此函数,什么也不做即可

问题:
方案1类似,RedheadDuck,MallardDuck 叫声和游泳姿态各不相同,因此有必要overrid Duck中的quack 和 swim函数

方案1的改进方案2

void RubberDuck::fly()
{
	cout << "RubberDuck does not fly" << endl;
}
...
void RedhatDuck::swim()
{
	cout << "swim like a RedhatDuck" << endl;
}
void RedhatDuck::quack()
{
	cout << "quack like a RedhatDuck" << endl;
}
...
void MallardDuck::swim()
{
	cout << "swim like a MallardDuck" << endl;
}
void MallardDuck::swim()
{
	cout << "quack like a MallardDuck" << endl;
}

改进方案2的问题

如果我们有100种Duck呢? 如果以后需要添加类似likefly的功能函数,,但为了避免bug, 在子类中需要重写100次如下的函数。
尽管likefly函数毫无用处。

void RubberDuck::likefly()
{
	cout << "RubberDuck does not fly" << endl;
}

不如,考虑重构?

4. 设计原型的重构

说明:

  • Duck 是一个抽象概念,具有飞行行为,游泳行为,叫声行为。 对于Duck来说,行为不再表现为函数,而是对象 FlyBehavior …
    优点:

  • 代码复用性强。RedHeadDuck 和 MallardDuck 可以复用一个FlywithWings 类

    代码:

    #include 
    
    using namespace std;
    
    class SwimBehavior
    {
        public:
        virtual void swim(void) = 0;
    };
    
    class QuackBehavior
    {
        public:
       virtual void quack(void) = 0;
    };
    
    class FlyBehavior
    {
      public:
      virtual void fly(void) = 0;  
    };
    
    class SwimCircle : public SwimBehavior
    {
        public:
        void swim (void)
        {
            cout << "swim in a circle" << endl;
        }
    };
    
    class SwimLine : public SwimBehavior
    {
        public:
        void swim(void)
        {
            cout << "swim in a line" << endl;
        }
    };
    
    class MuteQuack: public QuackBehavior
    {
        public:
        void quack(void)
        {
            cout << "quack in mute way" << endl; 
        }
    };
    
    class Squeak: public QuackBehavior
    {
        public:
        void quack(void)
        {
            cout << "quack in Squeak way" << endl; 
        }
    };
    
    class FlyNoWay : public FlyBehavior
    {
        public:
        void fly(void)
        {
            cout << "fly do nothing" << endl;
        }
    };
    
    class FlywithWings : public FlyBehavior
    {
        public:
        void fly(void)
        {
            cout << "fly with wings" << endl;
        }
    };
    
    
    class Duck
    {
      public:
      void performFly()
      {
          m_flaybehavior->fly();
      }
      
      void performSwim()
      {
          m_quackbehavior->quack();
      }
      
      void performQuack()
      {
          m_swimbehavior->swim();
      }
      
      protected:
      FlyBehavior *m_flaybehavior;
      QuackBehavior *m_quackbehavior;
      SwimBehavior *m_swimbehavior;
    };
    
    class RedHeadDuck: public Duck
    {
        public:
        RedHeadDuck (void)
        {
            m_flaybehavior = new FlywithWings();
            m_swimbehavior = new SwimCircle();
            m_quackbehavior = new Squeak();
        }
    };
    
    class MallardDuck: public Duck
    {
        public:
        MallardDuck (void)
        {
            m_flaybehavior = new FlywithWings();
            m_swimbehavior = new SwimCircle();
            m_quackbehavior = new MuteQuack(); 
        }
    };
    
    int main()
    {
    
        MallardDuck mallarDuck;
        RedHeadDuck redHeadDuck;
        
        mallarDuck.performQuack();
        mallarDuck.performSwim();
        mallarDuck.performFly();
        cout << "--------cut line-------" << endl;
    
        redHeadDuck.performQuack();
        redHeadDuck.performSwim();
        redHeadDuck.performFly();
        
        return 0;
    }
    
    
5. 小节4重构的一个应用

需求: 乘火箭而飞的鸭子

设计:

代码:

class FlyOnRocket: public FlyBehavior
{
    public:
    void fly()
    {
        cout << "I am flying on Rockets" << endl;
    }
};

class SuperDuck: public Duck
{
  public:
    SuperDuck (void)
    {
        m_flaybehavior = new FlyOnRocket();
        m_swimbehavior = new SwimCircle();
        m_quackbehavior = new MuteQuack(); 
    }
};

int main()
{

    SuperDuck superduck;
    superduck.performFly();
    return 0;
}
6. 小节4的设计思路为场景模式

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5651206.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存