首页 设计思想-面向对象
文章
取消

设计思想-面向对象

1. 面向对象编程和面向对象编程语言

1.1. 定义

面向对象编程:以类或对象作为组织代码的基本单元,并将封装、抽象、继承、多态四个特性,作为代码设计和实现的基石 。

面向对象编程语言:支持类或对象的语法机制,并有现成的语法机制,能方便地实现面向对象编程四大特性(封装、抽象、继承、多态)的编程语言。

1.2. 面向对象分析、设计和实现

软件工程面向对象
定需求、产品方案、研发落地、测试上线和后期运营围绕类、对象以及类与类之间如何交互
需求分析和系统设计面向对象分析和设计:程序拆解为类、类的属性和方法以及类之间的交互
软件开发面向对象实现:将分析和设计翻译成代码

1.3. 四大特性

1.3.1. 封装

what 也叫作信息隐藏或者数据访问保护。类通过暴露有限的访问接口,授权外部仅能通过类提供的方式(或者叫函数)来访问内部信息或者数据。

how 需要编程语言本身提供一定的语法机制来支持,即访问权限控制。

why 过度灵活也意味着不可控,属性可以随意被以各种奇葩的方式修改,而且修改逻辑可能散落在代码中的各个角落,势必影响代码的可读性、可维护性。 如果我们将属性封装起来,暴露少许的几个必要的方法给调用者使用,调用者就不需要了解太多背后的业务细节,用错的概率就减少很多。

1.3.2. 抽象

what 隐藏方法的具体实现,让调用者只需要关心方法提供了哪些功能,并不需要知道这些功能是如何实现的。

实际上,类的方法是通过编程语言中的“函数”这一语法机制来实现的。通过函数包裹具体的实现逻辑,这本身就是一种抽象。调用者在使用函数的时候,并不需要去研究函数内部的实现逻辑,只需要通过函数的命名、注释或者文档,了解其提供了什么功能,就可以直接使用了。

how 在面向对象编程中,我们常借助编程语言提供的接口类(比如Java中的interface关键字语法)或者抽象类(比如Java中的abstract关键字语法)这两种语法机制,来实现抽象这一特性。

why

  1. 抽象作为一种只关注功能点不关注实现的设计思路,正好帮我们的大脑过滤掉许多非必要的信息。
  2. 抽象作为一个非常宽泛的设计思想,在代码设计中,起到非常重要的指导作用。很多设计原则都体现了抽象这种设计思想,比如基于接口而非实现编程、开闭原则、代码解耦等。
  3. 我们在定义(或者叫命名)类的方法的时候,也要有抽象思维,不要在方法定义中,暴露太多的实现细节,以保证在某个时间点需要改变方法的实现逻辑的时候,不用去修改其定义。

抽象在多数据源、多存储源等场景中体现的非常充分,这类场景往往需要以基于接口而非实现编程的思想进行设计。

抽象为什么可以排除在面向对象编程特性之外呢?

该设计思想非常通用,不仅在面向对象编程中,也可指导架构设计等。该特性不需要编程语言提供特殊的语法机制来支持,仅需“函数”这基础的语法机制,就可实现抽象特性,即它没有很强的“特异性”,所以有时候并不被看作面向对象编程的特性之一。

1.3.3. 继承

what 用来表示类之间的 is-a 关系

how 编程语言需要提供特殊的语法机制来支持,比如Java使用extends关键字来实现继承,C++使用冒号(class B : public A),Python使用parentheses (),Ruby使用<。

why

  1. 代码复用
  2. is-a关系关联两个类更符合人类的思考方式,并且以设计的角度来看,具有结构美感。

为什么有些语言支持多重继承,有些语言不支持呢?

  1. 强耦合,子类和多个父类耦合在一起,可维护性差
  2. 多个父类中的出现同名方法(产生歧义),子类不知道继承哪个父类的方法,即著名的多重继承的 diamond problem,如下图,继承关系像钻石

diamond problem

过度使用继承带来的问题

  1. 过度使用继承,继承层次过深过复杂,就会导致代码可读性、可维护性变差。先要了解类的功能需要查看该类和它的所有父类(如果它的继承关系非常复杂,那就没法看)
  2. 子类和父类高度耦合,修改父类的代码,会直接影响到子类。

为达成代码复用:推荐利用组合关系而不是继承关系

1.3.4. 多态

what 子类可以替换父类,在实际的代码运行过程中,调用子类的方法实现。

how 编程语言需要提供下面的语法机制:

  1. 支持父类对象可以引用子类对象
  2. 支持继承、接口类或者 duck-typing。存在这种关系才能将子类传递给父类
  3. 支持子类可以重写(override)父类中的方法

why

  1. 提高代码的可扩展性和复用性,①即便子类的逻辑发生改变,调用者代码也不需要更改,因为使用的是父类,②新增一种策略,只需要继承或实现接口(符合开闭原则)
  2. 多态也是很多设计模式、设计原则、编程技巧的代码实现基础,比如策略模式、基于接口而非实现编程、依赖倒置原则、里式替换原则、利用多态去掉冗长的if-else语句等等。

what is duck-typing 只要两个类具有相同的方法,就可以实现多态,并不要求两个类之间有任何关系,这就是所谓的duck-typing,是一些动态语言所特有的语法机制。

本文由作者按照 CC BY 4.0 进行授权

设计模式之美导读和知识框图

面向对象编程与面向过程编程