彻底弄懂类设计原则之 - 开闭原则

待兔 等级 578 0 0
标签:

类设计原则之 - 开闭原则

OCP , Open Closed Principle , 中文翻译为 开闭原则

当第一次看到 OCP 时,我就蒙了,什么开,什么闭啊,完全摸不到头脑

然后就去网上找各种博客,各种解释,最多的一种就是:

对扩展开放,对修改关闭

当时我就更蒙了,去问了很多“高手”,他的回答让我更加迷茫:

不修改代码就可以增加新功能

这是多么神奇的事啊,不修改代码就能增加新功能

但问题是:怎么做到的呢? 不修改代码就能增加新的功能,难道像人工智能一样,会自动学习?又或者有什么高超的技巧?

越是好奇,越是想要弄明白 ,这么“神奇”的原则当然要继续探索了,但是怎么也没有找到 “不修改代码就能增加新功能” 的秘籍

对于这个原则开始有了怀疑,经过继续探索与各种查资料,才发现原来那些 “高手” 以及各种博客上的解释,是少了一个主语

而这才是 OCP (开闭原则) 的关键

大师们省略的主语是一个 消费者 , 另一个就是 生产者 了,也可以叫做提供者

例如 : A 类调用了 B 类的方法,A类就是消费者, B类就是提供者

重新表述 开闭原则

所以完整的 开闭原则 应该这样来表述: 对使用者修改关闭,对提供者扩展开放

更通俗的意思就是:提供者增加新的功能时,使用者不需要修改代码

但是读者可能又有了疑问: 提供者增加了新的功能,使用者不修改代码就真的能用上吗?

比如:一个 Car 类,有 加速 , 刹车 功能, 现在增加了一个 倒车 功能

如果其它模块要使用这个 Car 类,不修改代码就可以用上倒车 功能吗?

很显然这是不可能的, 我都新加了一个函数,你都不调用 ,你怎么用上我的新功能?

答案就在于:新增加的功能 并不是增加一个全新的功能,但是在原来的功能中有了替代

比如继续以轿车为例子:假设现在有了 卡车 , 跑车 ,家用车 三款车

现在要增加一种 卡丁车 , 只要 卡丁车 实现了 加速刹车 ,那么使用者就不需要修改代码,就可以玩 卡丁车了

但如果你增加了一种 漂移 功能,那么使用者就必须修改代码才能使用 漂移功能了。

对应到代码上来说,开闭原则(OCP) 应用原则如下:

  • 接口不变:包括函数名,函数参数,返回函数等, 可以使用 OCP

  • 接口改变:已有函数修改名称,参数,返回值,或者增加新的函数,OCP都不再适用

虽然 OCP 是针对类设计提出来的原则 ,但是其思想其实适用很广,系统和子系统,子系统和子系统,模块和模块之间都可以应用OCP

而且不同的地方应用其实都 遵循同一个原则:通过接口交互 ! 比如

  • 类与类之间应用 OCP :使用 interface 进行交互
  • 模块和模块,系统和系统之间 : 使用规定好的协议,不管是私有的还是公开的,例如 HTTP , RTCP

小结

OCP ,也即 开闭原则 : 对使用者修改关闭,对提供者扩展开放

开闭原则应用很广

  • 类与类之间用 interface进行交互
  • 模块与模块,系统与系统之间,使用规定好的协议
收藏
评论区

相关推荐

Python入门之类(class)
Python3 面向对象 Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的。本章节我们将详细介绍Python的面向对象编程。 如果你以前没有接触过面向对象的编程语言,那你可能需要先了解一些面向对象语言的一些基本特征,在头脑里头形成一个基本的面向对象的概念,这样有助于你更容易的学习Python的面向对
Python入门之类(class)
Python3 面向对象 Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的。本章节我们将详细介绍Python的面向对象编程。 如果你以前没有接触过面向对象的编程语言,那你可能需要先了解一些面向对象语言的一些基本特征,在头脑里头形成一个基本的面向对象的概念,这样有助于你更容易的学习Python的面向对
CAS之基本类型与引用类型
CAS之基本类型与引用类型 ============= 1.1 long -------- static final Unsafe unsafe ; static Long offset; private volatile long state= 1; static { try {
Java 类之间的关系
总述 == 类和类之间的关系,耦合度从高到低: * is 。继承、实现 * has 。组合、聚合、关联 * use 。依赖。 要求是:**高内聚、低耦合。** 继承 == Person 和 Man之间是继承关系。 ![](https://oscimg.oschina.net/oscnet/7b9f06e3a37b7bc9c5c2fe14
Java——类之间的关系
### 3.7 类之间的关系 #### 3.7.1 泛化关系  类和类之间的继承关系及接口与接口之间的继承关系。 ![](https://oscimg.oschina.net/oscnet/a5fa467c0401d4d7c7525fa4ab75fa4c672.png)  ![](https://oscimg.oschina.net/oscnet/9
Java基础之类
一、类的一般形式 -------- ### 1、类的概述 类就是事物的集合和抽象。它所代表的是这类事物所共有的一些行为和属性。 ### 2、类的一般形式 中国有13亿人,就有13亿个对象 人类只有一个 class 类名{ 类型 变量名; 类型 变量名; ... 类型 方法名
Java常用工具类之IO流工具类
package com.wazn.learn.util; import java.io.Closeable; import java.io.IOException; /** * IO流工具类 * * @author yangzhenyu *
java常用API之System类
System中代表程序所在系统,提供了对应的一些系统属性信息,和系统操作。System类不能手动创建对象,因为构造方法被private修饰,阻止外界创建对象。System类中的都是static方法,类名访问即可。 常用方法: ![](https://images2018.cnblogs.com/blog/1451598/201808/1451598-20
06_java之类概述
### 01引用数据类型\_类 * A: 数据类型 * a: java中的数据类型分为:基本类型和引用类型 * B: 引用类型的分类 * a: Java为我们提供好的类,比如说:Scanner,Random等。 * b: 我们自己创建的类,按照类的定义标准,可以在类中包含多个方法与属性,来供我
JUnit5学习之三:Assertions类
### 欢迎访问我的GitHub [https://github.com/zq2599/blog\_demos](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fgithub.com%2Fzq2599%2Fblog_demos) 内容:所有原创文章分类汇总及配套源码,涉及Java、Doc
JUnit5学习之二:Assumptions类
### 欢迎访问我的GitHub [https://github.com/zq2599/blog\_demos](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fgithub.com%2Fzq2599%2Fblog_demos) 内容:所有原创文章分类汇总及配套源码,涉及Java、Doc
Lua之Lua变量类型
在上一节中说到了 [Lua的安装与变量](https://www.oschina.net/action/GoToLink?url=http%3A%2F%2Fwww.ttlsa.com%2Flua%2Flua-install-and-lua-variable-ttlsa%2F),这节说说Lua变量的类型。Lua在使用中不需要预先定义变量的类型。Lua中基本的类
Mongodb之数据类型
一.MongoDB的数据类型 -------------- Object  ID :Documents 自生成的 \_id String: 字符串,必须是utf-8 Boolean:布尔值,true 或者false (Python中 True False 首字母大写) Integer:整数 (Int32 Int64 你们就知道有个Int就行了,一般我
Neo4J之标签类型
Neo4J的标签可以理解一个类,在创建一个节点时可以设置一个或多个标签: **1\. 标签名为中文(可以)** ![](https://img2018.cnblogs.com/blog/1309692/201809/1309692-20180905104037922-144441266.png) ![](https://oscimg.oschina.n
Python 入门 之 类成员
Python 入门 之 类成员 =============== 1、类的私有成员: --------- ### 私有: 只能自己拥有 #### 以 \_\_ 开头就是私有内容 对于每一个类的成员而言都有两种形式: - 公有成员,在任何地方都能访问 - 私有成员,只有在类的内部才能使用 私有成员和公有