开闭原则(Open Closed Principle)是Java世界里最基础的设计原则,它指导我们如何建立一个稳定的、灵活的系统。

定义:

一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。

Softeware entities like classes,modules and functions should be open for extension but closed for modifications.

开闭原则的含义是说一个软件实体应该通过扩展来实现变化,而不是通过修改已有代码来实现变化。

软件实体包括以下几个部分:

项目或软件产品中按照一定的逻辑规则划分的模块

抽象和类

方法

开闭原则是为软件实体的未来事物而制定的对现行开发设计进行约束的一个原则。

注意:开闭原则对扩展开放,对修改关闭,并不意味着不做任何修改,低层模块的变更,必然要有高层模块进行耦合,否则就是一个孤立无意义的代码片段了。

变化的类型:

逻辑变化

子模块变化

可见试图变化

一个项目的基本路径应该是这样的:项目开发、重构、测试、投产、运维,其中的重构可以对原有的设计和代码进行修改,运维尽量减少对原有代码修改,保持历史代码的纯洁性,提高系统的稳定性。

开闭原则的重要性:

1.开闭原则对测试的影响

开闭原则可是保持原有的测试代码仍然能够正常运行,我们只需要对扩展的代码进行测试就可以了。

2.开闭原则可以提高复用性

在面向对象的设计中,所有的逻辑都是从原子逻辑组合而来的,而不是在一个类中独立实现一个业务逻辑。只有这样代码才可以复用,粒度越小,被复用的可能性就越大。

3.开闭原则可以提高可维护性

面向对象开发的要求。

如何使用开闭原则:

1.抽象约束

第一,通过接口或者抽象类约束扩展,对扩展进行边界限定,不允许出现在接口或抽象类中不存在的public方法;

第二,参数类型、引用对象尽量使用接口或者抽象类,而不是实现类;

第三,抽象层尽量保持稳定,一旦确定即不允许修改。

2.元数据(metadata)控制模块行为

元数据就是用来描述环境和数据的数据,通俗地说就是配置参数,参数可以从文件中获得,也可以从数据库中获得。

Spring容器就是一个典型的元数据控制模块行为的例子,其中达到极致的就是控制反转(Inversion of Control)

3.制定项目章程

在一个团队中,建立项目章程是非常重要的,因为章程中指定了所有人员都必须遵守的约定,对项目来说,约定优于配置。

4.封装变化

对变化的封装包含两层含义:

第一,将相同的变化封装到一个接口或者抽象类中;

第二,将不同的变化封装到不同的接口或抽象类中,不应该有两个不同的变化出现在同一个接口或抽象类中。

例子

下面来个例子,先是不好的例子:

class GraphicEditor {

public void drawShape(Shape s) {

if (s.m_type==1)

drawRectangle(s);

else if (s.m_type==2)

drawCircle(s);

}

public void drawCircle(Circle r) {....}

public void drawRectangle(Rectangle r) {....}

}

class Shape {

int m_type;

}

class Rectangle extends Shape {

Rectangle() {

super.m_type=1;

}

}

class Circle extends Shape {

Circle() {

super.m_type=2;

}

}

当我们要扩展一个形状时,需要先了解GraphicEditor类,然后在drawShape中添加新的类型,然后再添加函数。下面是改进后的代码:

class GraphicEditor {

public void drawShape(Shape s) {

s.draw();

}

}

class Shape {

abstract void draw();

}

class Rectangle extends Shape {

public void draw() {

// draw the rectangle

}

}

不需要了解绘制逻辑,把具体实现放到了子类。

总结:

1. 遵守开闭原则可以提高软件扩展性和维护性。

2. 大部分的设计模式和设计原则都是在实现开闭原则。

java开闭原则 例子_解析Java编程中设计模式的开闭原则的运用相关推荐

  1. java 字符串是对象吗_解析Java中的String对象的数据类型

    解析Java中的String对象的数据类型 2007-06-06 eNet&Ciweek 1. 首先String不属于8种基本数据类型,String是一个对象. 因为对象的默认值是null,所 ...

  2. java 获取spring对象数组_解析Java中如何获取Spring中配置的bean

    解析Java中如何获取Spring中配置的bean Java中如何获取Spring中配置的bean?下面是由百分网小编为大家整理的解析Java中如何获取Spring中配置的bean,喜欢的可以收藏一下 ...

  3. java多态的简单例子_要JAVA的简单例子,继承\多态的,详细讲解运行的每一步

    java中的多态是动态绑定的,也就是说在编译期不能确定一个方法的执行体是哪个方法(在继承中重写的方法).执行果支委会根据在堆上分配的的引用去寻找方法体,所以产生你你所不想要的结果是正常的也是正确的.改 ...

  4. java 发送短信例子_利用java实现的一个发送手机短信的小例子

    今天闲来无事,在微博上看到一个关于用java实现的一个发送手机短信的程序,看了看,写的不太相信,闲的没事,把他整理下来,以后可能用得着 JAVA发送手机短信,流传有几种方法:(1)使用webservi ...

  5. 【源码+图片素材】Java王者荣耀游戏开发_开发Java游戏项目【王者荣耀】1天搞定!!!腾讯游戏_Java课程设计_Java实战项目_Java初级项目

    王者荣耀是当下热门手游之一,小伙伴们是否想过如何制作一款属于自己的王者荣耀游戏呢? 本课程讲解了一个王者荣耀游戏的详细编写流程,即使你是刚入门Java的新手,只要你简单掌握了该游戏所需要的JavaSE ...

  6. java 传绝对路径无效_【Java并发005】原理层面:volatile关键字全解析

    一.前言 在Java 5之前,volatile是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果. 在Java 5之后,volatile关键字才得以重获生机. volatile关键字虽 ...

  7. java ug二次开发_使用Java进行UG二次开发:简单的例子(上) | 学步园

    最近因为要进行TeamCenter二次开发(胖客户端定制),所有要开始研究Java了.因此突发奇想为什么不能使用Java进行二次开发呢?现在对UG进行的开发以C/C++应用为主.大多数使用的是原来的U ...

  8. java 反编译class文件_用Java实现JVM第三章《解析class文件》

    解析class文件 案例介绍 本案例主要介绍通过java代码从class文件中解析:class文件.常量池.属性表: 作为类(或者接口)信息的载体,每个class文件都完整地定义了一个类.为了使jav ...

  9. java抽象类例子_关于java抽象类的例子

    在网上找了很久,发现没有一个比较好的关于java抽象类的例子,刚好自己这些天在书上看到一个不错的猜数字游戏的例子,所以拿出来改进了下,希望能给你一些帮助,具体内容如下 建2个类依次为AbstractG ...

最新文章

  1. 关于SQLServer和MySQL动态条数限制
  2. 想知道聊天室系统是怎么做的吗?
  3. opencv2函数学习之threshold:实现图像阈值化
  4. Err:query must begin with SELECT or FROM
  5. mysql数据库备份到oss_备份MySQL数据库并上传到阿里云OSS存储
  6. 开源netcore前后端分离,前端服务端渲染方案
  7. java线程死锁研究
  8. 百变头像框制作微信小程序源码下载,免服务器和域名
  9. 小程序的优势和劣势是什么?
  10. CAD基础+常用快捷(四)
  11. 论文速递-ANALYSIS OF VISUAL REASONING ON ONE-STAGE OBJECT DETECTION
  12. java生成条码_Java生成商品条形码
  13. ESP8266NodeMcu连接不上WIFI解决方法
  14. 什么是用户标签体系?
  15. TRS过期后解决办法
  16. 移动开发技术总结!字节大神强推千页PDF学习笔记,附超全教程文档
  17. JS:判断是否是移动端
  18. JavaScript实现2048小游戏,我终于赢了一把
  19. 设计模式第一篇——简单工厂模式&类图
  20. table th、td设置最大高,超高度出现滚动条

热门文章

  1. Python Django 前后端数据交互 之 HttpRequest、HttpResponse、render、redirect
  2. 搭建阿里云ecs服务器(一:购买)
  3. 如何正确使用Java8的Optional机制
  4. Midnight.js – 实现奇妙的固定头部切换效果
  5. hdu-----(4857)逃生(拓扑排序)
  6. linux消息队列操作
  7. 思考ANDROID架构(4):HOW-TO, 如何从API洞悉软件的话语权
  8. Asp.net中基于Forms验证的角色验证授权[转]
  9. html设置复选框图片,css实现图片右上角添加复选框的方法
  10. ajax请求文件下载 php,使用Ajax请求下载文件