`
honeyao
  • 浏览: 75322 次
  • 性别: Icon_minigender_1
  • 来自: ShenZhen
社区版块
存档分类
最新评论

老生常谈:面向对象编程五大原则

    博客分类:
  • Java
阅读更多

单一职责原则SRP:Single Responsibility Principle
开放封闭原则OCP:Open-Close Principle
Liskov替换原则LSP:Liskov Substitution Principle
依赖倒置原则DIP:Dependency Invertion Principle
接口隔离原则ISP:Interface Separate Principle

  在面向对象设计中,如何通过很小的设计改变就可以应对设计需求的变化,这是令设计者极为关注的问题。为此不少OO先驱提出了很多有关面向对象的设计原则用于指导OO的设计和开发。下面是几条与类设计相关的设计原则。

1. 开闭原则(the Open Closed Principle OCP)
  一个模块在扩展性方面应该是开放的而在更改性方面应该是封闭的。因此在进行面向对象设计时要尽量考虑接口封装机制、抽象机制和多态技术。该原则同样适合于非面向对象设计的方法,是软件工程设计方法的重要原则之一。我们以收音机的例子为例,讲述面向对象的开闭原则。我们收听节目时需要打开收音机电源,对准电台频率和进行音量调节。但是对于不同的收音机,实现这三个步骤的细节往往有所不同。比如自动收缩电台的收音机和按钮式收缩在操作细节上并不相同。因此,我们不太可能针对每种不同类型的收音机通过一个收音机类来实现(通过重载)这些不同的操作方式。但是我们可以定义一个收音机接口,提供开机、关机、增加频率、降低频率、增加音量、降低音量六个抽象方法。不同的收音机继承并实现这六个抽象方法。这样新增收音机类型不会影响其它原有的收音机类型,收音机类型扩展极为方便。此外,已存在的收音机类型在修改其操作方法时也不会影响到其它类型的收音机。 
 
2. 替换原则 (the Liskov Substitution Principle LSP)
  子类应当可以替换父类并出现在父类能够出现的任何地方。这个原则是Liskov于1987年提出的设计原则。它同样可以从Bertrand Meyer 的DBC (Design by Contract) 的概念推出。
  我们以学生为例,夜校生为学生的子类,因此在任何学生可以出现的地方,夜校生均可出现。这个例子有些牵强,一个能够反映这个原则的例子时圆和椭圆,圆是椭圆的一个特殊子类。因此任何出现椭圆的地方,圆均可以出现。但反过来就可能行不通。 
  运用替换原则时,我们尽量把类B设计为抽象类或者接口,让C类继承类B(接口B)并实现操作A和操作B,运行时,类C实例替换B,这样我们即可进行新类的扩展(继承类B或接口B),同时无须对类A进行修改。

3. 依赖原则 (the Dependency Inversion Principle DIP)
  在进行业务设计时,与特定业务有关的依赖关系应该尽量依赖接口和抽象类,而不是依赖于具体类。具体类只负责相关业务的实现,修改具体类不影响与特定业务有关的依赖关系。
  在结构化设计中,我们可以看到底层的模块是对高层抽象模块的实现(高层抽象模块通过调用底层模块),这说明,抽象的模块要依赖具体实现相关的模块,底层模块的具体实现发生变动时将会严重影响高层抽象的模块,显然这是结构化方法的一个"硬伤"。
  面向对象方法的依赖关系刚好相反,具体实现类依赖于抽象类和接口。
  为此,我们在进行业务设计时,应尽量在接口或抽象类中定义业务方法的原型,并通过具体的实现类(子类)来实现该业务方法,业务方法内容的修改将不会影响到运行时业务方法的调用。 

4. 接口分离原则(the Interface Segregation Principle ISP)
    采用多个与特定客户类有关的接口比采用一个通用的涵盖多个业务方法的接口要好。
  ISP原则是另外一个支持诸如COM等组件化的使能技术。缺少ISP,组件、类的可用性和移植性将大打折扣。
  这个原则的本质相当简单。如果你拥有一个针对多个客户的类,为每一个客户创建特定业务接口,然后使该客户类继承多个特定业务接口将比直接加载客户所需所有方法有效。

以上四个原则是面向对象中常常用到的原则。此外,除上述四原则外,还有一些常用的经验诸如类结构层次以三到四层为宜、类的职责明确化(一个类对应一个具体职责)等可供我们在进行面向对象设计参考。但就上面的几个原则看来,我们看到这些类在几何分布上呈现树型拓扑的关系,这是一种良好、开放式的线性关系、具有较低的设计复杂度。一般说来,在软件设计中我们应当尽量避免出现带有闭包、循环的设计关系,它们反映的是较大的耦合度和设计复杂化。

分享到:
评论

相关推荐

    老生常谈javascript的面向对象思想

    面向对象编程(OOP)是通过创建对象来模拟现实世界的一种编程范式。在JavaScript中,对象可以通过不同的方法创建和定义。面向对象有三大基本特性:封装、继承和多态。 封装是面向对象编程的核心思想之一,它指的是...

    老生常谈JavaScript面向对象基础与this指向问题

    JavaScript中的面向对象编程是语言的核心特性之一,它允许开发者创建具有特定属性和行为的类(构造函数)并实例化为对象。本文将深入探讨面向对象的基础概念,包括面向过程与面向对象的区别,以及JavaScript中特有的...

    老生常谈PHP面向对象之标识映射

    在当前的编程领域中,面向对象编程(Object-Oriented Programming,简称OOP)是一种十分重要的编程范式。而PHP作为一种流行的脚本语言,在互联网后端开发中拥有广泛的应用。标识映射(Identity Mapping)是一种数据...

    老生常谈PHP面向对象之注册表模式

    注册表模式(Registry Pattern)是面向对象编程中的一种设计模式,它常用于管理应用范围内的全局变量或配置项,是一种以对象形式存储共享信息的方式,使得这些信息在整个程序生命周期内都可以被访问和修改。...

    老生常谈PHP面向对象之命令模式(必看篇)

    在PHP面向对象编程中,命令模式尤其有用,因为它可以帮助我们解耦请求者(客户端)与接收者(执行操作的对象)。下面我们将详细探讨这种模式在PHP中的应用。 1. **命令类**: 命令类是命令模式的核心,它定义了...

    老生常谈PHP面向对象之解释器模式

    最近在看 “深入PHP面向对象模式与实践” ,学习书中的内容后瞬间觉得自己有点高大上了,哈 ! 其实还是个菜B。相信也会有新手朋友在看这本(我自己也是新手),对书中我个人认为比较难的内容的学习心得就想拿出来分享...

    老生常谈Bootstrap媒体对象

    :ballot_box_with_check: 媒体对像的对象:常使用“media-object”表示,就是媒体对象中的对象,常常是图片 :ballot_box_with_check: 媒体对象的主体:常使用“media-body”表示,就是媒体对像中的主体内容,可以是...

    燕骏团队单片机C语言编程规范v3.0

    关于命名,最老生常谈的就是命名一定要有意义!!别看谭浩强!别看谭浩强!别看谭浩强! 变量、函数、宏等等都需要命名,清晰的命名是优秀代码的特点之一。命名的要点之一是名称应能清晰的描述这个对象,以至于一个...

    降低实施ERP风险的八大原则

    ERP项目是一个企业管理系统工程,而不是一般意义上的企业管理...有关ERP的实施是一个老生常谈的话题了,此文将根据笔者多年的实施经验总结如下几点:中小企业在实施ERP时应注意如何实现ERP的快速实施并降低风险等问题。

    老生常谈Java网络编程TCP通信(必看篇)

    "Java 网络编程 TCP 通信" Java 网络编程是指使用 Java 语言进行网络编程,实现在计算机网络中进行数据交换和通讯的操作。 TCP(Transmission Control Protocol,传输控制协议)是基于连接的协议,也就是说,在正式...

    电子技术的老生常谈——接地.pdf

    正如标题所言,《电子技术的老生常谈——接地》一文中提到的那样,尽管接地的基本概念在每一次培训和交流中都会被提及,但往往缺乏一个通用而全面的方法论指导。本文旨在深入探讨接地的各种类型、目的以及具体的实施...

    老生常谈的24种Java设计模式

    创建型模式:主要关注对象的创建过程,包括如何实例化对象、隐藏对象的创建细节等。常见的创建型模式有工厂方法模式、抽象工厂模式等。 结构型模式:主要用于处理类或对象的组合,如适配器模式、桥接模式等。 行为型...

    老生常谈Javascript中的原型和this指针

    理解这两个概念对于掌握JavaScript的面向对象编程特性至关重要。接下来,我们将详细探讨原型和this指针的相关知识点。 首先,我们来看一下JavaScript中的原型。原型在JavaScript中扮演了非常重要的角色,它是...

Global site tag (gtag.js) - Google Analytics