展开菜单
首页 精品内容 本月促销 装机必备 Windows PDF教程 macOS软件 IOS软件 Android AI 专题
全部分类

当前位置:

首页 > 编程开发 > Java项目工程实例代码分析

Java项目工程实例代码分析

衡量代码好环的原则1评判代码指标实际上,咱们平时嘴中常说的“好”和“烂”,是对代码质量的一种描述。“好”笼统地表示代码质量高,“烂”笼统地表示代码质量低。对于代码质量的描述,除了“好”“烂”这样比较简单粗暴的描述方式之外,我们也经常会听到很多其他的描述方式。这些描述方法语义更丰富、更专业、更细化。我搜集整理了一下,罗列在了下面,一般有几下几标准,分别是可读性、可维护性、可扩展性、可复用性、灵活性、可测试性等等可读性readability软件设计大师MartinFowler曾经说过:“Anyfoolcanw

本文目录

      衡量代码好环的原则

      1 评判代码指标

      实际上,咱们平时嘴中常说的“好”和“烂”,是对代码质量的一种描述。“好”笼统地表示代码质量高,“烂”笼统地表示代码质量低。对于代码质量的描述,除了“好”“烂”这样比较简单粗暴的描述方式之外,我们也经常会听到很多其他的描述方式。这些描述方法语义更丰富、更专业、更细化。我搜集整理了一下,罗列在了下面,一般有几下几标准,分别是可读性、可维护性、可扩展性、可复用性 、灵活性、可测试性等等

      Java项目工程实例代码分析

      可读性 readability

      软件设计大师 Martin Fowler 曾经说过:“Any fool can write code that a computer can understand. Good programmers write code that humans can understand.”翻译成中文就是:“任何傻瓜都会编写计算机能理解的代码。好的程序员能够编写人能够理解的代码。”Google 内部甚至专门有个认证就叫作 Readability。只有拿到这个认证的工程师,才有资格在 code review 的时候,批准别人提交代码。可见代码的可读性有多重要,毕竟,代码被阅读的次数远远超过被编写和执行的次数。

        我个人认为,代码的可读性应该是评价代码质量最重要的指标之一。我们在编写代码的时候,时刻要考虑到代码是否易读、易理解。除此之外,代码的可读性在非常大程度上会影响代码的可维护性。毕竟,不管是修改 bug,还是修改添加功能代码,我们首先要做的事情就是读懂代码。代码读不大懂,就很有可能因为考虑不周全,而引入新的 bug。

        既然可读性如此重要,那我们又该如何评价一段代码的可读性呢?我们需要看代码是否符合编码规范、命名是否达意、注释是否详尽、函数是否长短合适、模块划分是否清晰、是否符合高内聚低耦合等等。你应该也能感觉到,从正面上,我们很难给出一个覆盖所有评价指标的列表。这也是我们无法量化可读性的原因。

        实际上,code review 是一个很好的测验代码可读性的手段。如果你的同事可以轻松地读懂你写的代码,那说明你的代码可读性很好;如果同事在读你的代码时,有很多疑问,那就说明你的代码可读性有待提高了

      • 可维护性 maintainability

        一般指的是在不破坏原代码设计的前提下,快速修改bug或增加代码,不会带来新bug,表明该代码的维护性比较好。落实到编码开发,所谓的“维护”无外乎就是修改 bug、修改老的代码、添加新的代码之类的工作。所谓“代码易维护”就是指,在不破坏原有代码设计、不引入新的 bug 的情况下,能够快速地修改或者添加代码。所谓“代码不易维护”就是指,修改或者添加代码需要冒着极大的引入新 bug 的风险,并且需要花费很长的时间才能完成。

      • 可扩展性 extensibility

        代码面对未来新需求的变化能力,一般来说,开发新需求的时候,不修改原代码或很少修改,即可达到需求开发的能力,通常会预留一些功能扩展点。

      • 可复用性 reusability

        尽量避免重复造轮子,即能够沉淀出一些通用的代码逻辑,保持与上层业务代码的解耦

      • 灵活性 flexibility

        这个词比较宽泛。通常与可维护性、可扩展性以及可复用性类似

      • 可测试性

        主要反映在写单测的时候。从两个方面体现:

      1.单元测试是否容易编写;

      2.写单元测试的时候,不能依赖环境,远程调用其他服务的借口,尽可能进行mock数据,保持服务之间的解耦。虽然要团队每人都按这个规范走很难,但我们团队有一个强制要求,就是每个功能函数不能超过50行代码,而且要求代码越短越好。

      这几个维度是评判代码维度比较重要的几个指标。

      2 指导理论

        高内聚低耦合几乎是每个程序员员都会挂在嘴边的,但这个词太过于宽泛,太过于正确,所以聪明的编程人员们提出了若干面向对象设计原则来衡量代码的优劣:

      • 开闭原则 OCP (The Open-Close Principle)

      • 单一职责原则 SRP (Single Responsibility Principle)

      • 依赖倒置原则 DIP (Dependence Inversion Principle)

      • 最少知识原则 LKP (Least Knowledge Principle)) / 迪米特法则 (Law Of Demeter)

      • 里氏替换原则 LSP (Liskov Substitution Principle)

      • 接口隔离原则 ISP (Interface Segregation Principle)

      • 组合/聚合复用原则 CARP (Composite/Aggregate Reuse Principle)

        这些理论想必大家都很熟悉了,是我们编写代码时的指导方针,按照这些原则开发的代码具有高内聚低耦合的特性,换句话说,我们可以用这些原则来衡量代码的优劣。

      代码实现技巧

      我相信每个工程师都想写出高质量的代码,不想一直写没有成长、被人吐槽的烂代码。那如何才能写出高质量的代码呢?针对什么是高质量的代码,我们刚刚讲到了七个最常用、最重要的评价指标。所以,问如何写出高质量的代码,也就等同于在问,如何写出易维护、易读、易扩展、灵活、简洁、可复用、可测试的代码,但要写好代码,也不是一蹴而就,需要非常多的实践与积累,下面简举例说明:

      1 抽像能力

        抽象思维是我们工程师最重要的思维能力,因为软件技术本质上就是一门抽象的艺术。我们工程师每天都要动用抽象思维,对问题域进行分析、归纳、综合、判断、推理,从而抽象出各种概念,挖掘概念和概念之间的关系,然后通过编程语言实现业务功能,所以,我们大部分的时间并不是在写代码,而是在梳理需求,理清概念,对需求有一个全局的认知。而抽像能力让我及团队切身感受到,它给我们在编码和设计上带来的质的变化。

      案例一:异步Excel导出

      其实导出Excel功能在我们工程里随处可见,特别是咱们的运营希望一次性导出越多数据越好,为了不给我们系统带来太大压力,对于大数据量的导出一般异步进行,针对于这样一个简单的功能,那么应该如何抽像呢?

      普通的写法:

      public String exportXXX(参数) throws Exception {
      	//业务实现
      }
      public String exportXXX2(参数) throws Exception {
      	//业务实现
      }

      抽像写法:

      我们其实可以把每个异步导出看作是一个异步任务,而每个任务可导出的内容是不一样的,因此完全可以把导出抽像一个方法,由每个具体实现类去实现导出不同的内容,具体如下:

      // export excel 
      public interface IExcelExportTask {
          String export(BizCommonExportTask exportTask) throws Exception;
      }
      //样例实现类
      XXXXExportTask implements IExcelExportTask {
      	String export(BizCommonExportTask exportTask) throws Exception{
          	public String export(BizCommonExportTask exportTask) throws Exception {
          	//组织数据筛选条件
              TestReq queryReq = GsonUtils.toObject(exportTask.getInputParams(),TestReq.class);
              String fileName = String.format("%s%s%s", exportTask.getUploadFileName(),System.currentTimeMillis(),".xlsx");
              String downUrl = excelService.uploadExcel(fileName, null, new Fetcher(PreOccupyModel.class) {
              	//循环获取数据
                  @Override
                  public List fetch(int pageNo, int pageSize) throws OspException{
                      TestQueryResp resp = testFethchLogic.fetchRecord(queryReq);
                      return pageNo > resp.getPageNum() ? Collections.emptyList() :toExcelModel(resp);
                  }
              });
              return downUrl;
          }
      }
      public class XXXXExportTask1 implements IExcelExportTask {
          @Override
          public String export(BizCommonExportTask exportTask) throws OspException {
              TestQuery query = GsonUtils.toObject(exportTask.getInputParams(), TestQuery .class);
              String fileName = String.format("%s%s%s", exportTask.getUploadFileName(), System.currentTimeMillis(), ".xlsx");
              return excelService.uploadExcel(fileName, null, new Fetcher(TestModel.class) {
                  @Override
                  public List fetch(int pageNo, int pageSize) throws OspException {
                      return XXXXLogic.queryExportItem(query, pageNo, pageSize);
                  }
              });
          }
      }
      //导出任务分发器
      public class ExcelTaskDispacther extends ApplicationObjectSupport {
      	public boolean dispacthTask(Long taskId) throws OspException {
              updateTaskStatus(exportTask,CommonExportStatus.CREATING,TransferExportStatus.CREATING,StringUtils.EMPTY);
              try {
                  String beanName =  getBeanName();
                  ExportTaskHandler exportTaskHandler = getApplicationContext().getBean(beanName , IExcelExportTask .class);
                  if(exportTaskHandler == null) {
                      log.warn(String.format("任务ID[%s]写入配置错误!", taskId));
                      return false;
                  }
                  updateTaskStatus(exportTask,CommonExportStatus.CREATE_SUCCESS,TransferExportStatus.CREATE_SUCCESS,StringUtils.EMPTY);
                  log.info(String.format("任务ID[%s]RFID为[%s]处理成功", exportTask.getId(),rfid));
                  return true;
              } catch(BusiException ex) {
                  log.info("任务ID[{}]失败,原因:{}", exportTask.getId(),ex.getMessage(),ex);
                  updateTaskResult();
              } catch(Exception ex) {
                  log.info("任务ID[{}]失败,原因:{}", exportTask.getId(),ex.getMessage(),ex);
                  updateTaskResult();
              }
              return false;
          }
      }

      案例二:系统通知

      在微服务化流行的今天,为了提升系统吞吐量,系统职责越来越细,各系统模块需要频繁交互数据,那么对于复杂的数据交互场景,比如我们调拨单,调拨单在扭转的过程中需要与很多系统交互,跟门店、仓库、库存模块有非常多的交互,我们又该如何抽像呢,以下是调拨与各系统交互的代码示例

      //接口定义
      public interface BizNotificationHandler {
          /**
           * 抛异常会当失败处理
           * 是否需要重试由BizNotificationStatus返回状态来决定
           * @param bizNotification
           * @return
           * @throws OspException
           */
          BizNotificationStatus handleNotification(BizNotification bizNotification) throws OspException;
      }
      //推送调拨差异数据给库存系统
      public class SyncDiffToSimsAndBackQuotaHandler implements BizNotificationHandler {    
          @Override
          public BizNotificationStatus handleNotification(BizNotification bizNotification) throws OspException {
              //业务逻辑实现
              return BizNotificationStatus.PROCESS_SUCCESS;
          }
      }
      //占用库存
      public class TransferOccupyInventoryHandler implements BizNotificationHandler {
          @Override
          public BizNotificationStatus handleNotification(BizNotification bizNotification) throws OspException {
              //业务实现
          }
      }
      //在GPDC生成新条码
      public class GpdcGenerateNewBarcodeHandler implements BizNotificationHandler {
          @Override
          public BizNotificationStatus handleNotification(BizNotification bizNotification) throws OspException {
              //业务代码实现
          }
      }

      其实我们在与其它系统交互的时候,我们可以把每一个交互动作抽像成一个通知事件,每次交互的时候,写一个事件通知事件即可。

      2 组合/聚合复用原则

        关于组合/聚合复用原则,其实我们在项目过程会经常遇到,比如项目里会经常管理各种单据,像采购单、调拨单、收货单等,而对于每种单据都会有各种各样的较验,我们先来看一段建调拨单代码,具体如何下:

      //接口定义
      public interface TransferValidator {
          boolean validator(CreateTransferCtx ctx) throws OspException;
      }
      //接口实现1
      public class W2sCrossPoQtyValidator implements TransferValidator {
          @Override
          public boolean validator(CreateTransferCtx ctx) throws OspException {
              //较验器代码实现
          }
      //接口实现2
      public class W2sStoreBarcodeSaleLimitValidator implements TransferValidator {
          @Override
          public boolean validator(CreateTransferCtx ctx) throws OspException {
              //较验器代码实现
          }
      }
      //较验器组装
      public class TransferValidators {
          public ValidatorChain newChain() {
              return new ValidatorChain();
          }
          public class ValidatorChain {
              private final List validators = new ArrayList<>();
              public ValidatorChain qtyValidator() {
                  validators.add(qtyValidator);
                  return this;
              }
              public ValidatorChain transferRouteCfgValidator() {
                  validators.add(transferRouteCfgValidator);
                  return this;
              }
              public ValidatorChain prodValidator() {
                  validators.add(prodValidator);
                  return this;
              }
              public ValidatorChain w2sWarehouseStoreValidator() {
                  validators.add(w2sWarehouseStoreValidator);
                  return this;
              }
              public ValidatorChain w2sStoreBarcodeSaleLimitValidator() {
                  validators.add(w2sStoreBarcodeSaleLimitValidator);
                  return this;
              }
              public ValidatorChain w2sAssignPoValidator() {
                  validators.add(w2sAssignPoValidator);
                  return this;
              }
              public ValidatorChain w2sCrossPoValidator() {
                  validators.add(w2sCrossPoValidator);
                  return this;
              }
              public ValidatorChain w2sCrossPoQtyValidator() {
                  validators.add(w2sCrossPoQtyValidator);
                  return this;
              }
              public ValidatorChain w2sCross4XupValidator() {
                  validators.add(w2sCross4XupValidator);
                  return this;
              }
              public ValidatorChain repeatLineValidator() {
                  validators.add(repeatLineValidator);
                  return this;
              }
              public ValidatorChain sstradeBarcodeValidator() {
                  validators.add(sstradeBarcodeValidator);
                  return this;
              }
              public ValidatorChain s2wWarehouseStoreValidator() {
                  validators.add(s2wWarehouseStoreValidator);
                  return this;
              }
              public boolean validator(CreateTransferCtx ctx) throws OspException {
                  for (TransferValidator validator : validators) {
                      if (!validator.validator(ctx)) {
                          return false;
                      }
                  }
                  return true;
              }
          }
      }
      //业务代码使用
      public interface TransferCreator {
          boolean createOrder(CreateTransferCtx ctx) throws OspException;
      }
      public abstract class DefaultTransferCreator implements TransferCreator {
           @Override
          public boolean createOrder(CreateTransferCtx ctx) throws OspException {
              validator(ctx)
              //实现业务逻辑
          }
          protected abstract boolean validator(CreateTransferCtx ctx) throws OspException;
       }
      //店仓调拨单 
      public class S2wRefundCreator extends DefaultTransferCreator {
      	//较验器自由组装
          @Override
          protected boolean validator(CreateTransferCtx ctx) throws OspException {
              return transferValidators.newChain()
                      .qtyValidator()
                      .transferRouteCfgValidator()
                      .prodValidator()
                      .validator(ctx);
          }
      }
      本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
      作者最新文章
      编程开发 Java
      相关文章 更多
      精品专题 更多
      装机必备

      正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

      Windows

      正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

      PDF教程

      正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

      macOS软件

      正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

      IOS软件

      正软商城iOS软件专区,精选适用于iPhone和iPad的办公、学习、影音、设计、效率及AI应用,提供功能介绍、适用设备、系统要求和正版获取方式等信息。

      AI

      正软商城AI软件专区,汇集AI写作、AI绘画、AI视频、AI办公、AI编程、AI翻译、智能客服和数据分析等人工智能工具,提供功能介绍、适用平台、收费方式及正版购买信息。

      Mac软件 更多
      讯飞智作 网页版
      讯飞智作 网页版

      讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

      火山引擎 网页版
      火山引擎 网页版

      火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

      Aperty macOS版
      Aperty macOS版

      Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

      立刻MV 网页版
      立刻MV 网页版

      立刻MV 面向音乐人、内容创作者和品牌团队,帮助用户低成本完成歌曲 MV、歌词视频、AI 分镜、图生视频与最终合成。

      蛙蛙写作 网页版
      蛙蛙写作 网页版

      蛙蛙写作 AI 创作工具,覆盖小说、剧本、文案,一键生成文稿,打通文字转视频全流程,高效解决创作难题。

      超级简历WonderCV 网页版
      超级简历WonderCV 网页版

      超级简历WonderCV是面向应届生和AI小白的智能求职平台,覆盖简历、面试与职业规划。

      音述AI 网页版
      音述AI 网页版

      音述AI,是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区。

      AionClaw macOS版
      AionClaw macOS版

      AionClaw 是可在桌面端运行的任务型 AI 助手,通过数字专家与技能市场组合办公、创作、数据和开发能力。

      Loomy macOS版
      Loomy macOS版

      Loomy 是科大讯飞推出的桌面 AI 助手,可通过对话、任务与工作目录协助处理办公、内容创作和资料整理。

      AirBuddy 3 macOS版
      AirBuddy 3 macOS版

      AirBuddy 3 是面向 macOS 的蓝牙外设增强工具,可集中查看 AirPods、Beats 与苹果设备电量,提供快速连接、播放控制、电量提醒、桌面小组件和多台 Mac 外设接力等功能。

      AirServer macOS版
      AirServer macOS版

      AirServer macOS版可把 Mac 转换为无线投屏接收端,通过 AirPlay 或 Google Cast 接收手机、平板和电脑画面,并支持多设备同时连接、高清镜像及会话录制,适合家庭娱乐、课堂教学、会议演示和应用展示。

      AnyDesk macOS版
      AnyDesk macOS版

      AnyDesk macOS版是一款适用于远程办公、设备维护和客户支持的远程桌面工具,可连接并操作异地计算机,支持文件传输、无人值守访问、会话权限控制及跨平台协作。

      WINDOWS 更多
      讯飞智作 网页版
      讯飞智作 网页版

      讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

      火山引擎 网页版
      火山引擎 网页版

      火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

      PixTV 网页版
      PixTV 网页版

      PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。

      讯飞绘文 网页版
      讯飞绘文 网页版

      讯飞绘文网页版是科大讯飞推出的AI图文创作与内容运营工具,覆盖热点选题、文章生成、稿件校对、智能配图、排版发布和数据复盘等环节,适合自媒体创作者及内容团队在线使用。

      Maya(Autodesk Maya) Windows版
      Maya(Autodesk Maya) Windows版

      Autodesk Maya 是面向影视、电视、动画和游戏行业的专业三维制作软件,集多边形与 NURBS 建模、角色绑定、关键帧和动作捕捉动画、Bifrost 特效模拟、材质开发及 Arnold 渲染于一体,

      Aperty Windows版
      Aperty Windows版

      Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

      立刻MV 网页版
      立刻MV 网页版

      立刻MV 面向音乐人、内容创作者和品牌团队,帮助用户低成本完成歌曲 MV、歌词视频、AI 分镜、图生视频与最终合成。

      蛙蛙写作 网页版
      蛙蛙写作 网页版

      蛙蛙写作 AI 创作工具,覆盖小说、剧本、文案,一键生成文稿,打通文字转视频全流程,高效解决创作难题。

      超级简历WonderCV 网页版
      超级简历WonderCV 网页版

      超级简历WonderCV是面向应届生和AI小白的智能求职平台,覆盖简历、面试与职业规划。

      音述AI 网页版
      音述AI 网页版

      音述AI,是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区。

      AionClaw Windows版
      AionClaw Windows版

      AionClaw 是可在桌面端运行的任务型 AI 助手,通过数字专家与技能市场组合办公、创作、数据和开发能力。

      Loomy Windows版
      Loomy Windows版

      Loomy 是科大讯飞推出的桌面 AI 助手,可通过对话、任务与工作目录协助处理办公、内容创作和资料整理。