其他分享
首页 > 其他分享> > 写出可复用代码的基本思想与实践

写出可复用代码的基本思想与实践

作者:互联网

引言

“代码可复用性问题兼谈团队协作 ” 一文中,谈到难以写出可复用代码的一些不好的习惯和阻碍因素。本文讲讲写出可复用代码的基本技巧和实践。

代码可复用性,关键在于发现业务逻辑里的通用性部分。同时,能够发现业务逻辑里的通用部分,并能提取出来,有助于做出更好的设计,提升研发效率。


基本思想

写出可复用代码的基本思想,简而言之,就是逻辑拆分。拆分粒度越细,可复用的可能性越高。通过拆分成一系列有层次的、细粒度的函数或方法,就能建立一个可复用的代码基础。

拆分是战术层面的事情。“战略”层面,则需要对逻辑共性和差异的思考和提炼。通常包括两层:


编程技巧

泛型和函数式编程是一对强大的组合,有助于写出精炼、可复用的代码。 可阅: “一次代码重构的思考及探索 ”


实践

工具类

工具类是不依赖外部服务的“输入-输出”型函数。工具类最适合于做成可复用的,也容易写单测。

比如:“构造与使用分离:命中内容高亮及合并的展示问题解决实现”

比如:“精练代码:一次Java函数式编程的重构之旅 ” 重构得到的一系列 Util。


业务辅助类

业务辅助类是不依赖于外部服务的业务辅助工具类。这种类一般很小,能够涵盖很多业务点。而正是业务点的串联,构成了主体业务逻辑。比如:


/**
 * 从 agentDetection 获取可疑脚本信息
 */
public static ScriptDTO getScript(AgentDetection agentDetection) {
    if (AgentDetectionHelper.isInadequateAgentDetection(agentDetection)) {
        return null;
    }
    List<ScriptDTO> scripts = agentDetection.getAgentDetectionDetail().getDetail().getScripts();
    if (CollectionUtils.isNotEmpty(scripts)) {
        return scripts.get(0);
    }
    return null;
}


业务组件类

业务小组件类,依赖外部服务,提供单一的功能。 这种一般粒度比较小。封装成小组件类很适合业务复用。这种业务小组件通常散落在各种 service 的 private 方法里,而导致难以复用。


@Component
public class HostInfoHelper {
 
    private static final Logger LOG = LogUtils.getLogger(HostInfoHelper.class);
 
    private final HostProviderClient hostProviderClient;
 
    @Autowired
    public HostInfoHelper(HostProviderClient hostProviderClient) {
        this.hostProviderClient = hostProviderClient;
    }
 
    public HostDto getHost(String agentId) {
        if (agentId == null) {
            LOG.error("agentId is empty");
            return null;
        }
        HostDto host = hostProviderClient.getHost(agentId);
        if (null == host) {
            LOG.warn("No host found by agentId: {}", agentId);
            return null;
        }
        return host;
    }

}


统一机制的封装

比如 ssdeep 检测。 webshell 和 可疑脚本的 ssdeep 检测的逻辑基本相同。都是一段算法 + 样本检测缓存库 + 样本检测内存缓存 。 可以封装成统一的。公司源代码,就不便公开了。

统一机制需要指明调用来源,方便在必要的时候做差异处理。统一机制封装有点类似微服务提供的外部接口。

有一定工作经验的人是能够理解我指的是什么。

制订标准数据格式

比如很多检测能力都要用到文件上传。进程执行可疑脚本检测需要先上传文件,webshell 检测也需要先上传文件。如果我要封装一个业务功能,那么首先要封装出这个业务功能所需信息的标准数据格式。然后根据这个数据格式来构建业务功能。


/**
 * 文件上传所需信息
 * 目前文件上传下载主要依赖文件的两个信息:
 * 1. md5
 * 2. fpath: 对于容器来说,fpath 是容器在宿主机里的路径
 *
 * Created by qinshu on 2022/1/11
 */
@Getter
@Setter
@Builder
public class IdsFileUploadInfo {
 
    /** 文件MD5 */
    private String md5;
 
    /** 文件 sha256 值,未来会用这个值 */
    private String sha256;
 
    /** 文件路径 */
    private String fpath;
 
    /** 业务来源,用于文件上传回调 */
    private String app;
 
    /** 操作系统平台,不同平台使用不同上传脚本 */
    private int osType;
 
    /** 上传优先级 */
    private int priority;
 
    /** 文件保存天数,可选 */
    private int keepDays;
 
    /** 主机ID, 可选 */
    private String agentId;
 
    /** 客户ID,可选 */
    private String comId;
 
    /** 业务对象ID,用于查询关联业务表, 可选 */
    private String bizId;
 
    /** 文件上传后是否需要回调,一般是需要回调,更改任务表状态 */
    private boolean callback = Boolean.TRUE;
}


共享库封装

更大层面复用的就是共享库封装。比如入侵检测流程,基本可以看成是一系列组件的执行。每一个组件都可以是可复用的。

可阅: “事件处理业务的简易组件编排框架”


小结

本文提炼了写出可复用代码的一些基本技巧及实践。 要写出可复用的代码,基本思想是逻辑拆分。泛型和函数式编程是一对强大的组合,有助于写出精炼、可复用的代码。具体的工程技术手段有:


标签:封装,String,代码,复用,private,业务,写出
来源: https://www.cnblogs.com/lovesqcc/p/16123303.html