解析Java编程中设计模式的开闭原则的运用

 更新时间:2016年02月03日 11:35:12   作者:lixiang0522  
这篇文章主要介绍了解析Java编程中设计模式的开闭原则的运用,开闭原则多应用于Java程序的扩展开发方面,需要的朋友可以参考下

开闭原则(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线程池之工作队列workQueue

    手把手带你理解java线程池之工作队列workQueue

    这篇文章主要介绍了java线程池之工作队列workQueue,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-09-09
  • SpringBoot+SpringSecurity处理Ajax登录请求问题(推荐)

    SpringBoot+SpringSecurity处理Ajax登录请求问题(推荐)

    这篇文章主要介绍了SpringBoot+SpringSecurity处理Ajax登录请求问题,本文给大家介绍的非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2017-12-12
  • 解决运行jar包出错:ClassNotFoundException问题

    解决运行jar包出错:ClassNotFoundException问题

    这篇文章主要介绍了解决运行jar包出错:ClassNotFoundException问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • Java日常练习题,每天进步一点点(60)

    Java日常练习题,每天进步一点点(60)

    下面小编就为大家带来一篇Java基础的几道练习题(分享)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望可以帮到你
    2021-08-08
  • ChatGpt都使用的Java BPE分词算法不要了解一下

    ChatGpt都使用的Java BPE分词算法不要了解一下

    Byte Pair Encoding(BPE)是一种文本压缩算法,它通常用于自然语言处理领域中的分词、词汇表构建等任务,本文将对 BPE 算法进行全面、详细的讲解,并提供 Java 相关的代码示例,希望对大家有所帮助
    2023-06-06
  • 解决springcloud集成nacos遇到的问题

    解决springcloud集成nacos遇到的问题

    这篇文章介绍了如何解决springcloud集成nacos遇到的问题,文章中有详细的代码示例,需要的朋友可以参考一下
    2023-04-04
  • java实现小球碰撞功能

    java实现小球碰撞功能

    这篇文章主要为大家详细介绍了java实现小球碰撞功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-01-01
  • 详解Java并发包基石AQS

    详解Java并发包基石AQS

    Java并发包(JUC)中提供了很多并发工具,这其中,很多我们耳熟能详的并发工具,譬如ReentrangLock、Semaphore,它们的实现都用到了一个共同的基类--AbstractQueuedSynchronizer,简称AQS。本文将从几个方面来详细介绍:基本实现原理、自定义同步器、源码分析
    2021-06-06
  • Flask接口如何返回JSON格式数据自动解析

    Flask接口如何返回JSON格式数据自动解析

    这篇文章主要介绍了Flask接口如何返回JSON格式数据自动解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-11-11
  • Redis 集成Spring的示例代码(spring-data-redis)

    Redis 集成Spring的示例代码(spring-data-redis)

    本篇文章主要介绍了Redis 集成Spring的示例代码(spring-data-redis) ,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-09-09

最新评论