博主介绍: ✌博主从事应用安全和大数据领域,有8年研发经验,5年面试官经验,Java技术专家✌
Java知识图谱点击链接:体系化学习Java(Java面试专题)
💕💕 感兴趣的同学可以收藏关注下 ,不然下次找不到哟💕💕
开闭原则
《设计模式之禅》第6章介绍关于开闭原则,总结十字真言:对扩展开放,对修改关闭,
从Java的面向对象上看就是继承、封装,也就是说在我们实现需求时,尤其在架构设计时,我们写的一些基础对象,不允许其他人修改,但是如果你要基于我这个类扩展我们是提供了渠道的。
一、关于开闭原则的一个小例子
接下来我举一个例子说明:
例如我要封装一个持久层的Mapper类给大家用,提供基础的增、删、改、查、批量等功能
我下面是一个基础接口 Mapper,提供增删改查以及批量的一些接口,并且我基于 Mapper 提供了一个默认实现 AiocloudMapper,其他人是不能修改我的默认实现,但是我提供的 Mapper 接口可以提供大家实现去扩展,你可以扩展一个新的 MyMapper 去实现 Mapper,对增删改查赋予自己的逻辑,这就是开闭原则。
package com.pany.camp.design.principle.openclose;
import java.util.List;
/**
*
* @description: 基础 Mapper 类
* @copyright: @Copyright (c) 2022
* @company: Aiocloud
* @author: panyong
* @version: 1.0.0
* @createTime: 2023-05-30 20:29
*/
public interface Mapper<T> {
T select();
T select(Object... params);
List<T> selects();
int save(T t);
int batchSave(List<T> ts);
int update(T t);
int batchUpdate(List<T> ts);
int delete(Object param);
int deleteAll();
}
package com.pany.camp.design.principle.openclose;
import java.util.List;
/**
*
* @description: 默认实现
* @copyright: @Copyright (c) 2022
* @company: Aiocloud
* @author: panyong
* @version: 1.0.0
* @createTime: 2023-05-30 20:36
*/
public class AiocloudMapper<T> implements Mapper<T> {
@Override
public T select() {
return null;
}
@Override
public T select(Object... params) {
return null;
}
@Override
public List<T> selects() {
return null;
}
@Override
public int save(T t) {
return 0;
}
@Override
public int batchSave(List<T> ts) {
return 0;
}
@Override
public int update(T t) {
return 0;
}
@Override
public int batchUpdate(List<T> ts) {
return 0;
}
@Override
public int delete(Object param) {
return 0;
}
@Override
public int deleteAll() {
return 0;
}
}
package com.pany.camp.design.principle.openclose;
import java.util.List;
/**
*
* @description: 自定义实现
* @copyright: @Copyright (c) 2022
* @company: Aiocloud
* @author: panyong
* @version: 1.0.0
* @createTime: 2023-05-30 20:38
*/
public class MyMapper<T> implements Mapper<T> {
@Override
public T select() {
return null;
}
@Override
public T select(Object... params) {
return null;
}
@Override
public List<T> selects() {
return null;
}
@Override
public int save(T t) {
return 0;
}
@Override
public int batchSave(List<T> ts) {
return 0;
}
@Override
public int update(T t) {
return 0;
}
@Override
public int batchUpdate(List<T> ts) {
return 0;
}
@Override
public int delete(Object param) {
return 0;
}
@Override
public int deleteAll() {
return 0;
}
}
二、为什么要使用开闭原则
上面的例子是偏向于实操的,但是接下的这个问题“为什么要使用开闭原则”更偏向于面试中或者你去将开闭原则陈述给别人。首先开闭原则本质就是抽象,记住它的本质,你写代码的时候就知道如何运用它了。那么抽象的好处有什么呢?理解了这个面试时你就可以回答自如了。
1、提高复用性
在生产过程中,我们会将具有一类特点的对象进行抽象,其实也可以理解成类似于组件化,例如:A类需要实现查询方法,B类需要实现查询方法,那么如果两个地方都去写,那不是代码利用率非常低,冗余程度相当高,通过面向对象的思想,我们将查询方法抽象成 Mapper 接口的一个抽象方法。在实现一个这个接口 BaseMapper 提供一种查询实现。这样AB类只需要调用BaseMapper.select(params) 是不是就可以了。随着调用越来越多这种好处越来越明显。
2、提升可维护性
这个更好理解了,接着上面的例子,如果AB里面都写了 select() 方法,那么如果我要修改它,是不是需要改两遍,AB里面都要改,这样维护成本就变成两倍了。随着这种现象越来越多,维护越来越麻烦,万一哪天领导跟你说让你加个东西,你要复制 n 份,想想都会头疼。
💕💕 本文由激流丶创作,原创不易,感谢支持!
💕💕喜欢的话记得点赞收藏啊!