设计模式探秘-1-面向对象

面向对象简介

功能分解

功能分解是一种处理复杂问题的自然方法。将问题分解为多个功能步骤,再将步骤细分,然后解决更小的问题,将一个复杂问题变为解决多个简单的小问题。
功能分解的问题

  1. 主程序需要负责控制子程序的前后顺序,还要确保整个程序正确工作,主程序承担了太多功能
  2. 应对变化的能力弱,功能的变化需要对整个函数或模块进行修改。

模块化

可以在功能分解中模块化问题,将功能划分为一个个模块,模块间再相互调用,在功能需要变化时只需要修改对应的模块即可。模块化可是代码易于理解和维护。
模块化的问题是容易低内聚和紧耦合

内聚性描述一个功能内部组成部分之间的紧密程度
耦合性描述各个模块间的紧密程度
软件开发的目标应该是创建模块内部完整(高内聚),与其它模块间的联系小巧、直接、可见、灵活(松耦合)。

如果修改一个函数或函数使用的某个数据对其它函数产生严重破坏。因为功能分解将主要的精力放在具体的函数中,对一个函数或函数数据的修改会影响其它函数和数据。

面向对象

想象一个问题,一个厨子根据工人的反馈决定下顿饭做什么饭。
方法一:

  1. 厨子把可以做的菜列出来。
  2. 厨子得到工人名单和住址。
  3. 厨子前往工人住处。
  4. 厨子询问工人想吃什么菜,并记录下来。
  5. 厨子返回。
  6. 厨子汇总,找到票数最高的几个菜下顿饭做。

方法二:

  1. 厨子把可以做的菜列出来,张贴起来。
  2. 通知工人自行在菜单上选择要吃的菜,并记录。
  3. 厨子查看菜单,找到票数最高的几个菜下顿饭做。

方法二明显优于方法一,方法一需要关注大量细节、责任繁重,而方法二则简单的多,让工人明白,完成自身的任务。方法二将责任从厨子转移到每一个工人身上,实现责任的转移
新需求,要求厨子区分女性工人和男性工人,如果是方法一统计时需要增加一个步骤,区分女性工人和男性工人。而方法二则只需要给出两份菜单即可,女性一份,男性一份。

软件开发过程中的不同视角

  1. 概念 软件负责什么? “呈现所研究领域的各种概念,得出概念时应该很少或不考虑实现软件“
  2. 规约 怎么使用软件? 考虑软件的接口,而不是如何实现
  3. 实现 软件怎样履行自己的责任? 考虑代码本身,根据规约实现代码

面向对象编程以对象为中心,一切重点集中在对象身上。编写代码围绕对象而非函数进行组织。
对象有自己的属性和方法,属性告诉对象自身状态,方法告诉对象如何完成某些功能。

按照Martin Fowler的视角框架观察对象。

  1. 概念层次,对象是一组责任
  2. 规约层次,对象是可被其它对象或者对象自己调用的方法
  3. 实现层次,对象是代码和数据,以及对象之间的计算交互

对象具有供其它对象调用的公共接口。
围绕类组织对象,类是对对象行为的定义,包含对象的数据元素、对象能够操作的方法、访问数据元素和方法的方式。对象可以拥有不同的数据,但拥有相同的功能。
对象是类的实例。

抽象类

抽象类定义其它相关类的一般属性。例如抽象类学生,定义了学生的一般属性。
代表了某种类型的相关行为的类成为具体类,因为它代表一个概念既定、不变的实现。例如,本科生和研究生就是具体类,而学生则是抽象类。
抽象类和具体类是一种is-a(是一种)的关系,称之为继承。例如本科生继承学生类,研究生继承学生类。
抽象类可以定义派生类必须实现的公共方法。派生类使用抽象类的默认行为还是自己重新定义由派生类自身决定。
如果抽象类只提供规约而不提供实现,则是接口。

类的访问控制

对象对自己负责,有很多东西是自己私有的,不能暴露给其它对象,所以需要访问控制。

  1. 公开 public 任何对象可见
  2. 保护 protected 自身和派生类对象可见
  3. 私有 private 自身可见

类的封装

类的属性控制,达到隐藏数据的目的,实现数据的封装,但类的封装不只是数据封装,而是各种隐藏。

多态

多态,抽象引用概念性的要求对象做什么,对于不同的派生对象有不同的实现方式。

特殊的对象方法

  1. 构造方法 负责初始化或创建一个对象
  2. 析构方法 负责清除一个对象

概念回顾

  1. 功能分解 结构化程序员总是使用功能分解进行程序设计。功能分解是将一个问题逐渐分解为更小功能的方法,每个函数都分解到可管理为止
  2. 需求变更 需求变更是开发过程中与生俱来的。与其向用户或者自己抱怨获得理想而且完整的需求看来是不可能完成的任务”,不如使用更有效的开发方法,应对需求变更
  3. 对象 对象是由其责任定义的。对象能够自己负责自己,从而简化了使用对象的控制程序的任务
  4. 构造函数和析构函数 对象具有在创建和销毁自己时自动调用的特殊方法。这些特殊方法是:

    1. 构造函数:初始化或创建对象
    2. 析构函数:在对象删除时清除对象
    3. 所有面向对象语言都使用构造函数和析构函数辅助对对象的管理
  5. 抽象类 定义了概念上相似的一组类的方法和公共属性。抽象类不能实例化

  6. 属性 与对象关联的数据(也称为数据成员,data member)
  7. 类 对象的蓝图——为其类型的对象定义方法和数据
  8. 构造函数 在创建对象时调用的特殊方法
  9. 派生类 从基类特化的类,包含基类所有的属性和方法,但还可能包含其他属性或不同的方法实现
  10. 析构函数 在销毁对象时调用的特殊方法
  11. 封装 任何形式的隐藏。对象封装其数据,抽象类封装其派生的具体类
  12. 功能分解 一种分析方法,将问题逐步分解成小的功能
  13. 继承 一种特化类的方式,用于将派生类与其基类联系起来
  14. 实例 类的特定对象
  15. 实例化 创建类的一个实例的过程
  16. 成员 类的数据或方法
  17. 方法 与对象关联的例程
  18. 对象 具有责任的实体。一个特殊的、自成一体的容器,包含数据和操作数据的方法。对象的数据对于外部对象是受保护的
  19. 多态 相关的对象根据其具体类型实现方法的能力
  20. 超类 其他的类从中派生的类,包含所有派生类都要使用的主要数据和方法的定义(方法可能改写)

参考书籍

  • 设计模式解析(第二版)