(精品原创)Java代码优化->代码复用与重构

引言

  很多人在写代码刚开始可能会和我一样,不会去考虑重构和复用,因为一个需求给到你,也有相应的计划时间,我们更多的考虑是如何最快的实现业务,产品在催、PM在催、客户也在催。不过渐渐的会在完成一个业务时,用更优的方案来进行优化。因为你会发现,自己写的代码越简洁,自己越舒服。(PS:虽然网络一直在传言代码写的好,离职少不了,哈哈)
  接下来我用一些案例,来阐明一些简单的优化方案,仅供大家参考,大神勿喷。

案例

1. SQL复用
 背景描述:

  虽然现在大家都已经用了Mybaits,或者是Mybaits-plus,再加上sql生成器,很多时候写SQL非常方便,只需要调用生成器生成出的方法,.insert() / .save(),就可以实现新增或修改操作,但还是有些情况避免不了的使用原生SQL,例如JdbcTemplate。此案例在调用第三方接口时,用于存储大表数据。
  当我们遇到需要新增一个表时,当字段太多,往往要写一大段SQL(因为正常写INERT假设不加列名,会导致新增列时出现异常),后期如果维护也非常麻烦,假设再加一个表,又是一段SQL,因此我选择抽象出一个生成INSERT的SQL方法。

 思路:

  简单的抽象工具方法,可以让一些验证或其他重复性工作的维护成本大大降低,增加代码可读性。
  第一步是发现这个问题,你的逻辑中可能存在大量的重复,或重复复杂逻辑难以维护,这时需要考虑能否抽象成工具方法。以本案例为例,即使使用生成器,接口返回字段与实际存储字段不符,那么就导致我一个实体类要写几十个set(PS:这里也可以抽象构造方法,将Map传入,为另一种思路,但相比较差,因为我有多个表多个接口,可能要抽象N个构造方法),因此我需要一个生成INSERT的SQL方法。
  第二步要明确你需要什么,有哪些是可变参数。以本案例为例,我需要的是他拼接出的最终SQL,拿到之后直接执行即可。思考可变参数,每个表的表名列名不同,实际数据也不同,接口返回的实际Key也不同,因此我们需要:列名,实际Map的key,表名,数据。
  第三步就可以抽象方法进行测试了。以本案例为例,拼接SQL时选择将头先行拼接INERT INTO。然后将Sql分为两部分进行For循环拼接,一部分拼接列名,一部分拼接插入值。插入值的地方有两种额外情况,一种是默认的可用不可用状态,例如valid_status,默认的插入时间input_time,这种类型的数据我会在数据库中设置默认值,因为实际返回Key并没有。还有一种是空值,拼接时不能直接用map.get(key),应该拼接上NULL,。最终对拼接完成的sql去掉最后一位,进行合并即可。(PS:示例如下,实际情况和场景可自由发挥)

 demo:
/**
 * @description:    拼接新增Sql
 * @author:         zeus
 * @createDate:     2019/8/2 10:28
 * @param:          data: 数据源
 *                  colKey:配置列,key代表data所对应的实际key,value代表插入表的列名
 * 	                tableName:需要插入的表名
 * @version:        1.0
 */
public static String concatInsertSql(Map<String, Object> data, Map<String, String> colKey, String tableName){
    StringBuilder sqlHeader = new StringBuilder(" INSERT INTO ");// 拼接SQL
    sqlHeader.append(tableName).append(" (");
    StringBuilder sql = new StringBuilder(" (");
    for(String key : colKey.keySet()) {
        sqlHeader.append(colKey.get(key)).append(",");
        if(data.get(key) != null){
            String str = getConcatStr(data.get(key).toString());
            sql.append("'").append(str).append("',");
        }else{
            sql.append("NULL,");
        }
    }
    sqlHeader.deleteCharAt(sqlHeader.length()-1).append(") VALUES ");
    sql.deleteCharAt(sql.length()-1).append(")");
    sqlHeader.append(sql);
    return sqlHeader.toString();
 }
2. 表格导入导出
后续更新中。。。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
/* * 原始需求背景: * 网宿CDN要按月收取客户的服务费用,根据流量的大小、 * 服务的类型等,收取不同的费用,收费规则如下: * web应用:1000元/M * 流媒体应用:1000元/M*0.7 * 下载应用:1000元/M*0.5 * 月末打印报表时,要罗列每个用户每个频道的费用、客户总费用, * 还要打印该客户的重要性指数,重要性指数=网页流/100+下载流量/600; * * 需求变更场景: * 系统已经开发出来了,接下来,运维部门现在希望对系统做一点修改, * 首先,他们希望能够输出xml,这样可以被其它系统读取和处理,但是, * 这段代码根本不可能在输出xml的代码复用report()的任何行为,唯一 * 可以做的就是重写一个xmlReport(),大量重复report()中的行为,当然, * 现在这个修改还不费劲,拷贝一份report()直接修改就是了。 * 不久,成本中心又要求修改计费规则,于是我们必须同时修改xmlReport() * 和report(),并确保其一致性,当后续还要修改的时候,复制-黏贴的问题就 * 浮现出来了,这造成了潜在的威胁。 * 再后来,客服部门希望修改服务类型和用户重要性指数的计算规则, * 但还没决定怎么改,他们设想了几种方案,这些方案会影响用户的计费规则, * 程序必须再次同时修改xmlReport()和report(),随着各种规则变得越来越复杂, * 适当的修改点越 来越难找,不犯错误的机会越来越少。 * 现在,我们运用所学的OO原则和方法开始进行改写吧。 */
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值