Java设计模式(1:软件架构设计七大原则及开闭原则详解)
前言
在日常工作中,我们使用Java语言进行业务开发的时候,或多或少的都会涉及到设计模式,而运用好设计模式对于我而言,又是一个比较大的难题。为了解决、克服这个难题,笔主特别开了这个博客来记录自己学习的笔记和自己的理解,也欢迎对此有兴趣的朋友一起来和笔主探讨,共同学习。
一、软件架构设计模式的七大原则
1、开闭原则
对扩展开放,对修改关闭。在程序需要扩展的时候,不能去修改原有的代码实现一个热插拔的效果。简而言之,就是用抽象构建架构,用实现扩展细节。
2、单一职责原则
不要存在多于一个导致类变更的原因。简单来说,就是一个Class/Interface/Method只负责一项职责。
3、依赖倒置原则
这个原则是开闭原则的基础,是指设计结构代码时,高层模块不应该依赖于底层模块,二者应该依赖于抽象。抽象不应该依赖于细节,细节应该依赖于抽象。即:针对接口编程,依赖于抽象而不依赖于具体。
4、接口隔离原则
使用多个接口,而不使用单一的接口,客户端不应该依赖它不需要的接口。尽量的细化接口的职责,降低类的耦合度。
5、迪米特法则
又被成为最少知道原则,指的是一个对象应该对其他对象保持最少的了解。一个实体类应当尽量少地和其他实体之间发生相互作用,使得系统模块相互独立。形象来说就是:只和朋友交流,不和陌生人说话。
6、里氏替换原则
如果说实现开闭原则的关键步骤就是抽象化,那么基类(父类)和子类的继承关系就是抽象化的具体实现,所以里氏替换原则就是对实现抽象化的具体步骤的规范。即:子类可以扩展基类(父类)的功能,但不能改变父类原有的功能。
7、合成复用原则
尽量使用对象组合/聚合,而不是使用继承达到软件复用的目的。可以使系统更加的灵活,降低类与类之间的耦合度,一个类的变化对于其他类来说影响相对较少。
继承我们称之为白箱复用,相当于把实现的细节暴露给子类,组合/聚合 也成为黑箱复用,对类之外的对象是无法获取到实现细节的。
二、开闭原则详解
对扩展开放,对修改关闭。在程序需要扩展的时候,不能去修改原有的代码实现一个热插拔的效果。简而言之,就是用抽象构建架构,用实现扩展细节。
光看理论是不行的,这样的话我们只能是有一个模糊的认识,对具体的细节不太能看得清,我们先来举一个例子看一看它是怎么使用的:
例:假如我们居住的附近有一个小超市开业了,里面有各种的商品。老板想找你帮忙做一个超市商品的管理系统,那么针对超市众多商品的情况,我们首先应该会想到创建一个类来显示商品的基本信息:价格、名称等, 针对此,我们先来创建一个接口:
/**
* 商品基本信息 接口
*/
public interface Goods {
/**
* 商品的价格
*/
void getPrice();
/**
* 商品的名称
*/
void getName();
}
我们发现超市里有薯片贩卖,我们再来写一个薯片的类来实现这个接口,同时标明薯片的名称和价格:
/**
* 乐事薯片
*/
public class Crisps implements Goods{
@Override
public void getPrice() {
System.out.println("商品的价格:9.9 RMB");
}
@Override
public void getName() {
System.out.println("商品的名称:乐事薯片");
}
}
老板说以后还会有面包出售,那我们再来创建一个类来表明面包的基本信息:
/**
* 面包
*/
public class Bread implements Goods{
@Override
public void getPrice() {
System.out.println("商品的价格:5.5 RMB");
}
@Override
public void getName() {
System.out.println("商品的名称:面包");
}
}
等把这一切做好后,老板说因为新店刚刚开业,没有什么人气,就想前期通过薯片打折的方式来吸引人气(薯片打六折),这个时候我们想到的是:
1、修改
Crisps类中的getPrice()方法,但这会有一定的风险,可能会影响其他地方的调用结果。那么这个方法就可以pass掉。2、在
Goods接口中再加一个方法获取打折后的价格,但最后发现Bread类也需要去实现这个方法,但是面包并没有打折,这就对接口其他的实现类造成了影响,显然不可取。3、在
Crisps类中再加入一个方法来获得打折后的薯片价格,但这样可能会改变Crisps类的结构,可能会造成不必要的麻烦,而且开闭原则的基础就是:扩展程序的时候不能去修改原有的代码。那么这个方法也被pass。4、在增加一个类去继承
Crisps类,在子类中增加一个方法获取打折后的价格,这样通过子类我们可以获取到商品的名称,打折前的价格,打折后的价格,也不会改变Crisps类原有的结构,符合我们的规范,那我们再来编写一个类。
/**
* 薯片的子类
*/
public class CrispsDisCountPrice extends Crisps {
/**
* 打折后的价格
*/
public void getDisCountPrice(){
System.out.println("打折后的价格:"+ 9.9*0.6 +" RMB");
}
}
我们来看一下类的结构图:

Crisps类和Bread类是接口Goods的实现类,而CrispsDisCountPrice类继承了Crisps类。
写个测试类测试一下:
public class Test {
public static void main(String[] args) {
Bread bread = new Bread();
CrispsDisCountPrice crisps = new CrispsDisCountPrice();
bread.getName();
bread.getPrice();
crisps.getName();
crisps.getPrice();
crisps.getDisCountPrice();
}
}
结果:

最后
学习设计模式不能只理解于理论,要根据例子理解才能更加的清晰、透彻。接下来的几篇博客,我会将设计模式剩下的六个原则都一一说明,并举一例子。讲完七大原则后,会重点解析我们常说的23种设计模式。这是我学习记录的一个过程,谢谢!
Java设计模式(1:软件架构设计七大原则及开闭原则详解)的更多相关文章
- 设计原则:开-闭原则(Open-Closed Principle, OCP)
开-闭原则就是软件实体应当对扩展开放,对修改关闭.(Software entities should be open for extension,but closed for modification ...
- js 的七大原则--单一原则、开闭原则、替换原则(一)
一.前言: js 的七大设计原则: 1.单一原则 2.开闭原则 3.里氏替换原则 4.依赖倒转原则 5.接口隔离原则 6.合成复用原则 7.迪米尔法则 二.单一原则 1.定义:单一原则就是一个对象或者 ...
- 设计原则:开闭原则(OCP)
1.什么是开闭原则 开闭原则的英文是Open Closed Principle,缩写就是OCP.其定义如下: 软件实体(模块.类.方法等)应该"对扩展开放.对修改关闭". 从定义上 ...
- 7.10 其他面向对象设计原则1: 开-闭原则OCP
其他面向对象设计原则1: 开-闭原则OCP Open-Closed Principle (OCP)5.1 设计变坏的前兆 Signs of Rotting Design 僵硬性 Rigidit ...
- 开放-封闭原则(OCP)开-闭原则 和 依赖倒转原则,单一职责原则
单一职责原则 1.单一职责原则(SRP),就一个类而言,应该仅有一个引起它变化的原因 2.如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会消弱或抑制这个类完成其他职责的能力. ...
- 最简单直接地理解Java软件设计原则之开闭原则
写在前面 本文属于Java软件设计原则系列文章的其中一篇,后续会继续分享其他的原则.想以最简单的方式,最直观的demo去彻底理解设计原则.文章属于个人整理.也欢迎大家提出不同的想法. 首先是一些理论性 ...
- Java设计模式之五大创建型模式(附实例和详解)
一.概况 总体来说设计模式分为三大类: (1)创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. (2)结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥 ...
- Java的开发—面向对象的7大原则之开闭原则(一)
开闭原则(Open Close Principle) 一.定义: 软件中的(类.模块.函数等等)应该对于扩展是开放的,对于修改时关闭的.意味着一个实体允许在不改变它的源代码的前提变更它的行为 这里的软 ...
- 深入理解JavaScript系列(7):S.O.L.I.D五大原则之开闭原则OCP
前言 本章我们要讲解的是S.O.L.I.D五大原则JavaScript语言实现的第2篇,开闭原则OCP(The Open/Closed Principle ). 开闭原则的描述是: Software ...
随机推荐
- 关于Mapreduce Text类型赋值的错误
Mapreduce中Text类型数据被无缘无故替换? 今天偶然看到一个mapreduce demo,直接上手操作 统计两个文件中 最大值 文件中数据格式为 名字 数值 输出为 名字(最大值所对应的 ...
- WebPack系列--开启HappyPack之后,再将项目打包速度缩短5秒
效果展示 打包时间:缩短了 26.296s-20.586s=5.71s 先看两组测试数据,第一组是没有使用DllPlugin的打包测试数据,测量三次取平均值是26.296s(25.72+25.56+2 ...
- 关于nacos在windows系统启动时闪退的问题
nacos可以用来作为springcloud的配置中心使用,但在windows系统下使用的时候需要注意. nacos下载后解压,可以直接点击文件bin目录下的 startup.cmd 就可以启动. ...
- RF-获取body
一个很简单的场景:GET方法获取某URL的body信息,直接读取即可,不做处理 *** Test Cases *** GetToken Create HTTP Context host=192.168 ...
- 缓冲区溢出分析第09课:MS06-040漏洞研究——深入挖掘
前言 经过前两次的分析,我们已经对Netapi32.dll文件中所包含的漏洞成功地实现了利用.在系统未打补丁之前,这确实是一个非常严重的漏洞,那么打了补丁之后,这个动态链接库是不是就安全了呢?答案是否 ...
- visual studio 将他人的 vtk 程序在本机生成
在网上下载了一些关于vtk的资源,在本机使用visual studio 打开后,生成时出现类似与以下的错误 无法打开包括文件:"vtkStructuredPointsToPolyDataFi ...
- Andrew Ng机器学习算法入门(十):过拟合问题解决方法
在使用机器学习对训练数据进行学习和分类的时候,会出现欠拟合和过拟合的问题.那么什么是欠拟合和过拟合问题呢?
- Idea一直卡在loading archetype list问题解决(或者报Unable to import maven project: See logs for details)
暂时没有测试成功 https://blog.csdn.net/calo_missile/article/details/95898519
- thinkphp 连接多个数据库(tp5.1为例)
1.config目录下添加数据库配置,内容跟原数据库配置一样就可以(数据库名改成连接的第二个数据库名) 2.连接部分代码: $db = Db::connect(config('database2.') ...
- .NET平台系列5 .NET Core 简介
系列目录 [已更新最新开发文章,点击查看详细] 自1995年互联网战略日以来最雄心勃勃的事业 -- 微软.NET战略, 2000年6月30日. 微软公司于2002年2月13日正式推出第一代.N ...