当前位置: 首页 > news >正文

设计模式的学习

OO:Object-Oriented

面向对象

---

《Head First设计模式》

这本书是用java写的,我是写C++的,用C++来写相关的代码

---

p2(第二页)

#ifndef DUCK_H
#define DUCK_H/*** @brief The Duck class    鸭子类*/
class Duck
{
public:Duck();/*** @brief quack 呱呱叫* 所有的鸭子都会呱呱叫* 所以在父类中实现这部分代码*/void quack();/*** @brief swim  游泳* 所有的鸭子都会游泳* 所以在父类中实现这部分代码*/void swim();/*** @brief display   展示鸭子的外观* 每种鸭子的外观特点不同,需要在子类中进行实现* 所以这里是虚函数*/virtual void display();
};#endif // DUCK_H
#ifndef MALLARDDUCK_H
#define MALLARDDUCK_H#include "duck.h"
/*** @brief The MallardDuck class 绿头鸭*/
class MallardDuck : public Duck
{
public:MallardDuck();virtual void display();
};#endif // MALLARDDUCK_H
#ifndef MALLARDDUCK_H
#define MALLARDDUCK_H#include "duck.h"
/*** @brief The MallardDuck class 绿头鸭*/
class MallardDuck : public Duck
{
public:MallardDuck();virtual void display();
};#endif // MALLARDDUCK_H

---

现在需要添加需求:一部分鸭子会飞。

如果直接在基类中添加fly(),那么意味着所有的鸭子都会飞。(所有的子类都拥有了fly() )

而橡皮鸭子是不会飞的。

---

当涉及“维护”时,为了复用目的而使用继承,并不是完美的。

---

如果子类把fly()方法覆盖掉呢?

可以,但如果再加入一种不会飞的鸭子,那么需要重新再覆盖fly()方法。

void fly()
{//覆盖,什么事都不做
}

每多一种鸭子,就需要覆盖一次fly()方法。

------

而有些鸭子不会飞,也不会叫。

---

希望找到一种建立软件的方法,让我们可以用一种对既有的代码影响最小的方式来修改软件。

这样我们就可以花较少时间重做代码,而让程序去做更酷的事。

---

继承不能很好地解决问题,因为鸭子的行为在子类中不断地改变,并且让所有的子类都有这些行为是不恰当的。

Flyable和Quackable接口一开始似乎还不错,但继承接口无法达到代码的复用。

当需要修改某个行为时,需要在定义此行为的类中修改它。

---

设计原则: 

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

---

努力让系统中的某部分改变不会影响其他部分。

---

设计原则:

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

---

简单的多态例子:

有一个抽象类Animal,两个具体的实现:Dog和Cat继承自Animal

针对实现编程:

Dog d = new Dog();
d.bark();

针对接口编程:

Animal * animal = new Dog();
animal.makeSound();

子类实例化的动作不再需要在代码中硬编码,而是在运行时才指定具体实现的对象,

进一步封装:

a = getAnimal();
a.makeSound();

我们不关心实际的子类型是什么,我们只关心它知道如何正确地调用makeSound()。

---

#ifndef FLYBEHAVIOR_H
#define FLYBEHAVIOR_H
#include <QDebug>
/*** @brief The FlyBehavior class 飞行行为*/
class FlyBehavior
{
public:FlyBehavior(){}virtual void fly(){}
};/*** @brief The FlyWithWings class    用翅膀飞行*/
class FlyWithWings : public FlyBehavior
{
public:FlyWithWings(){}virtual void fly(){qDebug()<<"用翅膀飞行";}
};/*** @brief The FlyNoWay class    不会飞行*/
class FlyNoWay : public FlyBehavior
{
public:FlyNoWay(){}virtual void fly(){qDebug()<<"不会飞行";}
};#endif // FLYBEHAVIOR_H
#ifndef FLYBEHAVIOR_H
#define FLYBEHAVIOR_H
#include <QDebug>
/*** @brief The FlyBehavior class 飞行行为*/
class FlyBehavior
{
public:FlyBehavior(){}virtual void fly(){}
};/*** @brief The FlyWithWings class    用翅膀飞行*/
class FlyWithWings : public FlyBehavior
{
public:FlyWithWings(){}virtual void fly(){qDebug()<<"用翅膀飞行";}
};/*** @brief The FlyNoWay class    不会飞行*/
class FlyNoWay : public FlyBehavior
{
public:FlyNoWay(){}virtual void fly(){qDebug()<<"不会飞行";}
};#endif // FLYBEHAVIOR_H

关键在于:

鸭子现在会将飞行和呱呱叫的动作“委托”别人处理,而不是使用定义在Duck类或子类内的呱呱叫和飞行方法。

#ifndef DUCK_H
#define DUCK_H#include "flybehavior.h"
#include "quackbehavior.h"
/*** @brief The Duck class    鸭子类*/
class Duck
{
public:Duck();FlyBehavior * flyBehavior;QuackBehavior * quackBehavior;void performQuack(){quackBehavior->quack();}void performFly(){flyBehavior->fly();}/*** @brief display   展示鸭子的外观* 每种鸭子的外观特点不同,需要在子类中进行实现* 所以这里是虚函数*/virtual void display(){}
};#endif // DUCK_H
#ifndef MALLARDDUCK_H
#define MALLARDDUCK_H#include "duck.h"
/*** @brief The MallardDuck class 绿头鸭*/
class MallardDuck : public Duck
{
public:MallardDuck();virtual void display(){}
};#endif // MALLARDDUCK_H
#include "mallardduck.h"MallardDuck::MallardDuck()
{flyBehavior = new FlyWithWings();quackBehavior = new MuteQuack();
}
    MallardDuck mallardDuck;mallardDuck.performFly();mallardDuck.performQuack();

---

通过基类的指针析构子类时,会出现内存泄漏吗?

如果不希望内存泄漏,析构函数必须使用虚函数。

---


http://www.mrgr.cn/news/44370.html

相关文章:

  • Trie树之最大异或对问题
  • C语言 | Leetcode C语言题解之第461题汉明距离
  • VMware ESXi 7.0U3q macOS Unlocker OEM BIOS 2.7 Dell HPE 联想定制版 9 月更新发布
  • 【Canvas与色彩】十二等分多彩隔断圆环
  • 单链表的分解
  • 【QT】QT入门
  • 前沿论文创新点集合
  • 输电线路悬垂线夹检测无人机航拍图像数据集,总共1600左右图片,悬垂线夹识别,标注为voc格式
  • 通用版本升级规范
  • 微软推出针对个人的 “AI伴侣” Copilot 会根据用户的行为模式、习惯自动进化
  • 二叉树的进阶
  • 五、存储引擎
  • 详细分析Spring Framework中 @ConditionalOnProperty的基本知识(附Demo)
  • SpringBoot:让开发更加简单
  • 数字电表读数检测图像数据集,数据集总共3300左右张图片,标注为voc格式
  • 问:详细介绍一下JVM的指针压缩技术?
  • Crypto虐狗记---”你“和小鱼(八)
  • 单链表合成(去重复值)
  • 【PostgreSQL】运维篇——性能优化的重要性与背景
  • 【题解】—— LeetCode一周小结40