当前位置:首页 > 软件设计 > 正文内容

我在大厂做 CR——再谈怎么高雅修正代码

邻居的猫1个月前 (12-09)软件设计1767

书接上回为什么需求依靠注入再做下扩展

上文谈到:“根据笼统接口编程的确是最佳实践:把易于变化的功用点经过界说笼统接口的办法露出出来,不同的完成做到阻隔和扩展,这表现了开闭准则”

public class Foo {
  private Bar bar ;
  @Inject
  public Foo(Bar bar) {
    this.bar = bar;
  }
  public String doSomething(int key) {
    //Bar#getResult 体会了代码的复杂性,经过注入不同的 Bar 完成目标,做到功用点的阻隔和扩展
    return bar.getResult(key);
  }
}

但在实在项目里,往往是多人协作一同开发,一些前史原因导致某些代码片段的完成往往“千奇百怪”,既不能很好的单侧掩盖,一起也充满着违反了开闭准则的“代码坏滋味”;

而此刻的你,作为“被选中的人”,需求对其功用迭代;

或许经过你的评价后,能够去雷厉风行的架构演进,这是点赞的;

但有时也要大局 ROI 去评价雷厉风行重构收益是否足够大,有时分咱们只能退让(trade-off)。即:如安在严重的交给周期内做到比较好的重构,不让代码持续堕落;

所以这次持续介绍两种修正代码的艺术:办法新增和办法掩盖

战略 1:办法新增

经过新增办法来阻隔旧逻辑,即:在旧办法里横切“缝隙”,注入新的事务逻辑被调用;

拿之前的 Case 举例,一个前史老办法,需求对回来的数据调集过滤掉空目标:

public class Foo {
   private Bar bar;
   public Foo() {
       bar = new Bar();
   }
   public List<Data> doSomething(int key) {
       //依靠三方服务,RPC 调用成果集
       List<Data> result = bar.getResult(key);
       //过滤掉空目标
       return result.stream().filter(Objects::nonNull).collect(Collectors.toList());
   }
}

此处逻辑很简略,运用了Java Lambda 表达式做了过滤,但这样的写法无疑落井下石:的确原先办法现已很 Low 了,也无法单侧。本次只是在最终加了一段简略的逻辑。现已轻车熟路了,或许不少人都会这样搞;

但作为好的程序员,眼前现状的确咱们只能退让,但后续的每一行代码,需求做到保质保量,努力做到不影响原有事务逻辑下做到可测验;

“办法新增”:经过新增办法 getDataIfNotNull 来阻隔旧逻辑:

public List<Data> doSomething(int key) {
       //依靠三方服务,RPC 调用成果集
       List<Data> result = bar.getResult(key);
       return getDataIfNotNull(result);
}

如下 getDataIfNotNull 作为新增办法,很简单对其进行独立测验,一起原有的办法 doSomething 也没有持续堕落

public List<Data> getDataIfNotNull(List<Data> result) {
   return result.stream().filter(Objects::nonNull).collect(Collectors.toList());
}

能够看到长处很明显:新老代码明晰阻隔;当然为了愈加责任清楚,运用新增类阻隔会更好;

战略 2:办法掩盖

将待修正的办法重命名,并创立一个新办法和原办法名和签名共同,一起在新办法中调用重命名后的原办法;

假设有新需求:针对 doSomething 办法做一个音讯告诉操作,那么“办法掩盖”即:将原办法 doSomething 重命名为 doSomethingAndFilterData,再创立一个与原办法同名的新办法 doSomething,最终在新办法中调用更名后的原办法:

//将原办法 doSomething 重命名为 doSomethingAndFilterData
public List<Data> doSomethingAndFilterData(int key) {
       //依靠三方服务,RPC 调用成果集
       List<Data> result = bar.getResult(key);
       return getDataIfNotNull(result);
}

//创立一个与原办法同名的新办法 doSomething
public List<Data> doSomething(int key) {
       //调用旧办法
       List<Data> data = this.doSomethingAndFilterData(key);
       //调用新办法
       doNotifyMsg(data);
       return data;
}

//新的扩展办法契合阻隔扩展,不影响旧办法,也支撑单侧掩盖
public void doNotifyMsg(List<Data> data){
      //
}

办法掩盖的另一种写法:通常是再界说一个新的办法,然后在新的办法顺次调用新老事务逻辑;

一般在架构演进的时分,用于切流新老逻辑;例如:根据客户端版别,大于 3.10.x 的客户端切流运用新的逻辑——咱们创立一个新的办法调用新旧两个办法。

//老的前史代码,不做改造
public List<Data> doSomething(int key) {
       //依靠三方服务,RPC 调用成果集
       List<Data> result = bar.getResult(key);
       List<Data> data = getDataIfNotNull(result);
       return data;
}

//新创立一个办法,聚合调用新老逻辑
public List<Data> doSomethingWithNotifyMsg(int key) {
       List<Data> data = this.doSomething(key);
       //调用新办法
       doNotifyMsg(data);
       return data;
}

//新的扩展办法契合阻隔扩展,不影响旧办法,也支撑单侧掩盖
public void doNotifyMsg(List<Data> data){
       //
}

这样的优点是明显易见的,不针对旧办法做修正,一起在更高维度的“上层”切流:确保新功用正常迭代演进,老功用保持不变

boolean enableFunc=getClientVersion()>DEFAULT_CLIENT_VERSION;
if (enableFunc){
       return doSomethingWithNotifyMsg();
   } else {
       return doSomething();
}

能够看到“办法掩盖”不管用何总办法完成,它不会在当时旧办法里添加逻辑,而是经过运用新办法作为进口,这样防止新老逻辑耦合在一同;

“办法掩盖”能够再进阶一步,运用独立的类来阻隔,也便是装修者形式。通常情况下原有的类现已非常复杂了,现已不想在它上做功用迭代了,考虑运用装修者来解耦:

class DecoratedFoo extends Foo{
   private Foo foo;
   public DecoratedFoo(Foo foo){
   }

   @Override
   public List<Data> doSomething(int key) {
       List<Data> data = super.doSomething(key);
       notifyMsg();
       return data;

   }
   private void notifyMsg(){

   }
}

扫描二维码推送至手机访问。

版权声明:本文由51Blog发布,如需转载请注明出处。

本文链接:https://www.51blog.vip/?id=323

分享给朋友:

“我在大厂做 CR——再谈怎么高雅修正代码” 的相关文章

软件设计师教程第五版,软件设计师教程第五版——全面解析与学习指南

软件设计师教程第五版,软件设计师教程第五版——全面解析与学习指南

《软件设计师教程(第五版)》是一本专为软件设计师考试(中级)准备的权威教材,由清华大学出版社出版。以下是该书的详细信息: 书籍简介《软件设计师教程(第五版)》依据2018年审定通过的软件设计师考试大纲编写,涵盖了软件设计师(中级)岗位所要求的主要知识及应用技术。本书由褚华和霍秋艳两位专家撰写,于20...

python面向对象还是面向过程, 面向过程编程(POP)

python面向对象还是面向过程, 面向过程编程(POP)

Python 是一种多范式编程语言,既支持面向对象编程(OOP)也支持面向过程编程(POP)。这意味着你可以根据自己的需求选择使用哪种编程范式。面向对象编程是一种编程范式,它通过将数据和操作数据的函数组合在一起,创建对象来模拟现实世界中的实体。在面向对象编程中,你将创建类来定义对象的结构和功能,然后...

商业模式顶层设计,构建企业可持续发展的基石

商业模式顶层设计,构建企业可持续发展的基石

商业模式顶层设计是指在一个组织或企业中,从最高层次出发,对整个商业模式进行全面的规划和设计。它涉及到对企业的核心价值主张、目标市场、客户关系、收入来源、关键资源、关键业务、重要合作和成本结构等关键要素的深入分析和决策。在进行商业模式顶层设计时,需要考虑以下几个方面:1. 核心价值主张:明确企业为顾客...

pageobject设计模式

pageobject设计模式

PageObject设计模式是一种常用于自动化测试的面向对象编程(OOP)方法。这种模式的主要目的是将测试代码与UI元素分离,使得测试更加模块化、可维护和可重用。以下是PageObject设计模式的基本概念和实现方法:1. PageObject类: PageObject类是PageObject...

策略设计模式,什么是策略设计模式?

策略设计模式,什么是策略设计模式?

策略设计模式(Strategy Design Pattern)是一种行为设计模式,它定义了一系列的算法,把它们一个个封装起来,并且使它们可以互相替换。这种类型的设计模式属于行为型模式,其特征是将算法的使用与算法的实现分离。 主要角色1. 环境(Context):使用策略接口来调用策略。2. 策略(S...

软件架构设计 pdf, 软件架构的定义与重要性

软件架构设计 pdf, 软件架构的定义与重要性

以下是几本关于软件架构设计的PDF电子书资源,您可以参考下载:1. 《软件架构设计:程序员向架构师转型必备 》 该书从程序员成长的视角,深入浅出地讲述了架构师的修炼之道,涵盖了架构设计的基础概念、实践过程、模块划分等内容。您可以通过以下链接下载: 2. 《软件架构与设计》...