tip: 需要《设计模式之禅》的书籍,可以联系我
作为程序员一定学习编程之道,一定要对代码的编写有追求,不能实现就完事了。我们应该让自己写的代码更加优雅,即使这会费时费力。
相关规则:
1.6大设计规则-迪米特法则
2.6大设计原则-里氏替换原则
3.6大设计规则-接口隔离原则
4.6大设计规则-单一职责原则
5.6大设计规则-依赖倒置原则
文章目录
- 开闭原则
- 一、关于开闭原则的一个小例子
- 二、为什么要使用开闭原则
开闭原则
《设计模式之禅》第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> {@Overridepublic T select() {return null;}@Overridepublic T select(Object... params) {return null;}@Overridepublic List<T> selects() {return null;}@Overridepublic int save(T t) {return 0;}@Overridepublic int batchSave(List<T> ts) {return 0;}@Overridepublic int update(T t) {return 0;}@Overridepublic int batchUpdate(List<T> ts) {return 0;}@Overridepublic int delete(Object param) {return 0;}@Overridepublic 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> {@Overridepublic T select() {return null;}@Overridepublic T select(Object... params) {return null;}@Overridepublic List<T> selects() {return null;}@Overridepublic int save(T t) {return 0;}@Overridepublic int batchSave(List<T> ts) {return 0;}@Overridepublic int update(T t) {return 0;}@Overridepublic int batchUpdate(List<T> ts) {return 0;}@Overridepublic int delete(Object param) {return 0;}@Overridepublic int deleteAll() {return 0;}
}
二、为什么要使用开闭原则
上面的例子是偏向于实操的,但是接下的这个问题**“为什么要使用开闭原则”更偏向于面试中或者你去将开闭原则陈述给别人。首先开闭原则本质就是抽象**,记住它的本质,你写代码的时候就知道如何运用它了。那么抽象的好处有什么呢?理解了这个面试时你就可以回答自如了。
1、提高复用性
在生产过程中,我们会将具有一类特点的对象进行抽象,其实也可以理解成类似于组件化,例如:A类需要实现查询方法,B类需要实现查询方法,那么如果两个地方都去写,那不是代码利用率非常低,冗余程度相当高,通过面向对象的思想,我们将查询方法抽象成 Mapper 接口的一个抽象方法。在实现一个这个接口 BaseMapper 提供一种查询实现。这样AB类只需要调用BaseMapper.select(params) 是不是就可以了。随着调用越来越多这种好处越来越明显。
2、提升可维护性
这个更好理解了,接着上面的例子,如果AB里面都写了 select() 方法,那么如果我要修改它,是不是需要改两遍,AB里面都要改,这样维护成本就变成两倍了。随着这种现象越来越多,维护越来越麻烦,万一哪天领导跟你说让你加个东西,你要复制 n 份,想想都会头疼。
总结下,使用开闭的好处就是:面向对象,提供复用性,提升可维护性
tip:老板就喜欢你这样给他节省成本的程序员 :)