Head first设计模式 第1章阅读笔记

父类

class Duck{
    void quack();
    void swim();
    void fly();
    void display();
};

子类

  • 覆盖父类的display()函数,实现自己的display(),每种鸭子都有自己的外观特征
  • 继承父类的quack()、swim()、fly()
class MallardDuck : public Duck {
    void display() {
        // 外观是绿头
    }
};
class RedheadDuck : public Duck {
    void display() {
        // 外观是红头
    }
};

问题

  1. 并不是所有的鸭子都会飞,橡皮鸭子就不会飞, 诱饵鸭不会飞
  2. 并不是所有的鸭子都会叫,诱饵鸭就不会叫

所以子类直接继承父类的fly()和swim()是不合适的。

解决方案

  1. 在和父类不同时,子类覆盖掉父类的fly()和swim(),实现自己的fly()和swim()
    • 该方案存在的问题
      • 代码在多个子类中重复,可能多个子类的fly()相同,但是与父类的不同,不得不在每个子类中都实现一个相同的fly()
      • 运行时的行为不容易改变,如果一只鸭子刚开始是咕咕叫,后来变成过呱呱叫,该怎么办?
      • 很难知道所有鸭子的全部行为,父类可能不囊括鸭子的所有有行为
      • 改变会牵一发动全身,造成其他鸭子不想要的改变
class RubberDuck : public Duck{
    void fly() {
        // 覆盖掉父类的fly(), 变成什么时都不做
    }
};
class DecoyDuck : public Duck {
    void fly() {
        // 覆盖,变成什么事都不做
    }
    void quack() {
        // 覆盖,变成什么事都不做
    }   
};
  1. 把fly()从超类中取出来放进一个"Flyable接口"中。同样的方法,把quack()从超类中取出来放进一个"Quackable接口"。
    • 这么一来,只有会飞的鸭子才实现"Flyable接口"。只有会叫的鸭子才实现"Quackable()"
    • 代码难以复用,每种鸭子都得实现自己的fly()或wim。当有很多鸭子的实现方式一样时,会出现很多相同的代码。只是从一个噩梦跳到另一个噩梦中。
  2. 分开变化和不会变化的部分。
    • 准备两组类(完全远离Duck类),一个是"fly"相关的,一个是"quack"相关的,每一组都实现各自的动作。
    • 接口"Flyable", 具体实现由子类完成。(“Quackable类似”)
    • 在Duck类中,加入两个实例变量,分别为"Flyable()“和"Quackable()”
    • 分析优势
      • 鸭子类中只使用了接口,没有实现,代码得到了复用
      • 还可以在运行时改变状态,赋值一个新的子类对象给Flyable接口或Quackable接口即可。
      • 当需要添加新的飞行方式或叫的方式时,只需要继承接口,在子类中实现即可。Duck类不需要做任何改动。
设计原则1

找出应用中可能需要的变化之处,把它独立出来,不要和那些需要变化的代码混在一起

设计原则2

针对接口编程,而不是针对实现编程

原则3

多用组合,少拥继承

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值