设计规则之开闭原则

tip: 需要《设计模式之禅》的书籍,可以联系我

作为程序员一定学习编程之道,一定要对代码的编写有追求,不能实现就完事了。我们应该让自己写的代码更加优雅,即使这会费时费力。

相关规则:

推荐:体系化学习Java(Java面试专题)

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> {
    @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 份,想想都会头疼。

总结下,使用开闭的好处就是:面向对象,提供复用性,提升可维护性

tip:老板就喜欢你这样给他节省成本的程序员 :)

你可能感兴趣的:(设计规则和模式,开闭原则,java,开发语言)