如何用代码解放生产力
  ow7vFKHHqlkG 2023年11月19日 35 0

背景介绍

本文分享一个我遇到一个工作量巨大的任务时的解题思路与方法。
前一阵子接了个任务,是根据一个车控信号表格去写接口,本以为是个极其轻松的工作,做到后面我发现我还是太年轻了。
遇到的问题:

  • 1.车控信号数量巨多;
  • 2.信号分为上下行信号,对应的是读写接口,所对应的代码也不同;
  • 3.除了信号表还要去check另一个文件,检查prop ID是否定义;
  • 4.最后还要给应用层一个接口文档。

做到后面真的头皮发麻,写了十多个接口后,我觉得不能这样写了,抛开身心疲惫不谈,还容易出错。

解题

冷静下来分析一手,我做的事情总结下就是机械化的操作与格式化的编码。
等等...机械化、格式化!!
我一下子就想到了写个脚本去干这些事,我是程序员啊,得用代码解放生产力啊。OK,有了思路就直接撸起袖子开干。

读取数据

第一步就是得读取信号表格里面得数据,我一百度还真有这样的库,EasyExcel ,是阿里的一个三方库,可以读取表格数据转成对象。挺好用的,推荐大家start一下,万一以后用的上。

创建bean数据类:

public class VehicleExcelData {
    @ExcelProperty("Functional classification")
    private String functionalClassification;
    @ExcelProperty("Fuction Describe")
    private String functionDescribe;

    @ExcelProperty("Detail")
    private String detail;
    //private String detailedExplanation;
    @ExcelProperty("Project")
    private String project;
    //private String scope;
    //private String featureID;
    @ExcelProperty("Vehicle property ID")
    private String vehiclePropertyId;

    @ExcelProperty("Area ID")
    private String areaID;
    @ExcelProperty("DataType")
    private String dataType;

    //省略其他属性
  }

读取数据:

//读取excel
//buildSheet为表中对应的sheet名
EasyExcel.read(excelPath, VehicleExcelData.class,readListener).sheet(buildSheet).doRead();


private ReadListener<VehicleExcelData> readListener = new ReadListener<>() {

    @Override
    public void invoke(VehicleExcelData data, AnalysisContext context) {

        if (data.isAvailable() && data.getIsCheck() != null && data.getIsCheck().equals("true") ) {
            checkIsInTypesHal(data, typeHalDataArrayList);
            vehicleExcelDataList.add(data);
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        //生成sdk代码
        new SDKBuildHelper(vehicleExcelDataList, buildSheet).build();
        //生成types hal
        //new TypeHalBuildHelper(vehicleExcelDataList).build();
        //生成接口doc
        InterfaceDocWriter.writeInterfaceDoc(vehicleExcelDataList, buildSheet);
    }

};

在doAfterAllAnalysed方法里就可以拿到所有读取到的数据对象。

另外一个需要读取的源文件并非是excel表格,这时候只能去一行一行读取文件内容,按照规则去匹配字符,找到需要的数据创建对象。需要根据具体的文件,制定相应的匹配规则,例如:

private static String getType(ArrayList<TypeHalData> list, String str, TypeHalData bean) {
    //VehiclePropertyGroup:VENDOR
    if (str.isEmpty()) {
        return null;
    }
    String content = str.trim();
    if (content.contains(":")) {
        String[] dataArray = content.split(":");
        String type = dataArray[0];
        String value = dataArray[1];
        if (type.contains(VEHICLE_STRUCT_TYPE_GROUP)) {
            bean.setGroup(value);
            return "| VehiclePropertyGroup." + value;
        } else if (type.contains(VEHICLE_STRUCT_TYPE_PROPERTY_TYPE)) {
            bean.setType(value);
            return "| VehiclePropertyType." + value;
        } else if (type.contains(VEHICLE_STRUCT_TYPE_AREA)) {
            bean.setArea(value);
            list.add(bean.clone());
            return "| VehicleArea." + value + "\n end";
        }
    }
    return null;
}

模板代码编写

接下来就是如何生成代码了。这个不难,实现方式很多,我使用的是JavaPoet。 以前写kapt时使用到过KotlinPoet,甚至还有DartPoet。我还用过它来生成框架的模板代码,例如MVVM的ViewModel、Repository、Activity...... 这个库就是用来生成代码的,Poet这一系列的库也推荐大家看一下,万一用的上了。

因为我生成的代码比较多,这里就放一部分代码给大家看看(没必要看懂我写的啥hhh)。

public JavaFile buildServiceImpl() throws Exception {

    //创建类
    TypeSpec.Builder classBuilder = TypeSpec.classBuilder("ServiceImpl");

    //生成方法
    MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder("callback");
    for (VehicleExcelData data : vehicleExcelDataList) {
        if (data.getAccessMode().equals("WRITE")) continue;
        String str1 = "case " + serviceManagerName + "." + data.getIdStr() + ":\n";
        methodBuilder.addCode(str1);

        String str2 = data.getProStr() + " = (" + data.getVehicleDataType() + ")value.getValue()";
        methodBuilder.addStatement(str2);

        String str3 = "mPacket.set" + data.getProStr().substring(1) + "(" + data.getProStr() + ")";
        methodBuilder.addStatement(str3);

        String str4 = "LogUtil.debug(TAG," + "\"" + data.getIdStr() + ":\" + " + data.getProStr() + ")";
        methodBuilder.addStatement(str4);

        // methodBuilder.addStatement("LogUtil.debug(TAG, \"ID_SETTINGS_CHARGING_LIMIT:\" + mSettingsChargingLimit)");
        methodBuilder.addStatement("break");
    }

    for (VehicleExcelData data : vehicleExcelDataList) {
        if (data.getAccessMode().equals("WRITE")) continue;
        String str5 = "private " + data.getVehicleDataType() + " " + data.getProStr() + "";
        methodBuilder.addStatement(str5);
    }

    // set and get
    for (VehicleExcelData data : vehicleExcelDataList) {
        data.getAccessModeType(onReadWrite -> {
                classBuilder.addMethod(serviceGetBuilder(data).build());
                classBuilder.addMethod(serviceSetBuilder(data).build());
            }, onRead -> {
                classBuilder.addMethod(serviceGetBuilder(data).build());
            }, onWrite -> {
                classBuilder.addMethod(serviceSetBuilder(data).build());
            }
        );
    }

    classBuilder.addMethod(methodBuilder.build());
    return JavaFile.builder(buildSheet, classBuilder.build()).build();
}

//写入文件
buildServiceImpl().writeTo(new File(path));

到了这里就可以依葫芦画瓢的完成接口文档生成的工作,使用EasyExcel生成表格文档。 使用EasyExcel生成表格文档 当数据转成了对象,就可以被我们随意拿捏了。

总结

完成这一套脚本后,我的工作就简单太多了,只需要一键生成代码,再把代码粘贴到相应文件就完成了。如果说还需要优化的话 ,可以考虑在原来的接口文件中埋点添加注释之类的,下次加接口的时候直接读取上次的埋点,自动的把生成的代码放到对应的文件以及对应的行号。

灵活运用工具真的是可以事半功倍,全靠自己能不能活跃思维想到解题办法。

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月19日 0

暂无评论

推荐阅读
ow7vFKHHqlkG
作者其他文章 更多