『数据库』微服务化的基石——持续集成( 五 )


DTO和访问数据库的包 , 看到了这些数据结构 , 会帮助程序员快速掌握代码逻辑 , 不知道大家有没有这个体验 , 你去看一个开源软件的代码 , 首先要看的是他的数据结构 , 数据结构和关系看懂了 , 代码逻辑就比较容易懂了 , 如果数据结构没看懂 , 则光看逻辑 , 就容易云里雾里的 。
还有就是核心的代码逻辑和对接口的实现 。 在这里面是软件代码设计的内功所在 , 但是却不是流程能够控制的 。
六、有关接口设计规范上面也说过了 , Dubbo和Springcloud会对接口进行重试 , 因而接口需要保持幂等 。 也即多次调用 , 应该产生一致的结果 , 例如转账1元 , 因为调用失败或者超时重试的时候 , 最终结果还应该是转账1元 , 而非调用两次变成转账2元 。

  • 幂等判断尽量提前 , 可以使用ID作为判断条件 。
  • 接口的实现应该尽量避免阻塞 , 可以使用异步方式提升性能 。
  • 接口应该包括能够区分不同情况的异常 , 而非抛出宽泛的Exception , 不能吞掉异常 。
  • 接口的实现要有足够的容错性 , 以及对不同版本的兼容性 。 当要引入新接口的时候 , 使用先添加 , 后删除的方式 。
  • 接口应该有良好的注释 。
七、有关代码设计对于代码的设计 , 这里常说的就是SOLID原则 。
  • S是单一责任原则 , 如果你的代码中有一个类行数太长 , 可能你需要重新审视一下 , 是不是这个类承担了过多的责任 。
  • O是开放关闭原则 , 比较拗口 , 对扩展开放 , 对修改关闭 。 思想是对于代码的直接修改是非常危险的事情 , 因为你不知道这段代码原来被谁用了 , 而且当时候用的时候 , 面临的情况都是怎样的 。 因而不要贸然修改一段代码 , 而是选择用接口进行调用 , 用实现进行扩展的方式进行 。 当你要实现一段新的功能的时候 , 不要改原来的代码 , 也不要if-else , 而是应该扩展一种实现 , 让原来的调用的代码逻辑还是原来的 , 在新的情况下使用新实现的代码逻辑 。
  • L是里氏替换原则 , 如果基于接口进行编程 , 则子类一定要能够扩展父类的功能 , 如果不能 , 说明不应该继承与这个接口 。 例如你的实现的时候 , 发现接口中有一个方法在你这里实在对应不到实现 , 不是接口设计的问题 , 就是你不应该继承这个接口 , 绝不能出现not implemented类似之类的实现方法 。
  • I是接口隔离原则 , 接口不应该设计的大而全 , 一个接口暴露出所有的功能 , 从而使得客户端依赖了自己不需要的接口或者接口的方法 。 而是应该讲接口进行细分和提取 , 而不应该将太过灵活的参数和变量混杂在一个接口中 。
  • D是依赖倒置原则 , A模块依赖于B模块 , B模块有了修改 , 反而要改A , 就是依赖的过于紧密的问题 。 这就是常说的 , 你变了 , 我没变 , 为啥我要改 。 如果基于抽象的接口编程 , 将修改隐藏在后面 , 则能够实现依赖的解耦 。
以上是模块内部常见的设计原则 , 对于模块之间 , 则是对于云原生应用常说的十二要素原则 。
『数据库』微服务化的基石——持续集成
本文插图

八、有关配置文件在代码仓库中 , 还需要管理的是配置文件 , 往往在src/main/resource下面 。
配置的管理原来多使用profile进行管理 , 对于dev, test, production使用不同的配置文件 。
然而当配置非常多的时候 , 比较的痛苦 , 而且配置不断的修改 , 每次上线各种配置需要仔细的核对 , 眼睛都花了 , 才敢上线 。
我们可以将配置分为下面的三类: