前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >TDD | 越是“老古董”越有高效率?

TDD | 越是“老古董”越有高效率?

原创
作者头像
花花Binki
发布2024-09-22 22:38:56
发布2024-09-22 22:38:56
1201
举报
文章被收录于专栏:岚的工作随笔岚的工作随笔
封面
封面

前言

如果一个数能被3整除,那么返回结果Fizz,如果一个数能被5整除,返回Buzz。

如果两者同时满足,则输出FizzBuzz。

为了验证方法是否满足,我们在开发前设计了一组输入输出数据,测试代码也保留在了工程中。

初版业务简单,于是很快敲下代码。

代码语言:java
复制
 public static String fizzBuzz(int num) {
        if (num % 3 == 0 && num % 5 == 0) {
            return "FizzBuzz";
        } else if (num % 3 == 0) {
            return "Fizz";
        } else if (num % 5 == 0) {
            return "Buzz";
        } else {
            return String.valueOf(num);
        }
    }

接着,业务变更。在保持以前的条件下,数字里面包含3,返回Fizz,包含5返回Buzz。因为怕程序员有误解,又多加了几个代表性的数据。

比如输入57,返回FizzBuzz,因为他满足3的倍数,又同时包含5。

看起来很简单,但为了通过小部分的测试,写了一堆if else来维护准确性,勉强完成任务。

这个过程中,不知不觉中完成了一次TDD。

什么是TDD

说起TDD,可以追溯到二十多年前,他的全称是Test-Driven Development 测试驱动开发。可以理解成测试用例驱动开发,也有比较形象的理解:测试人员驱动开发人员。

为什么需要TDD

各种软件工程中的技巧,首要目标就是为了解决复杂对象问题。TDD的思维呢,就是一种通过测试数据为导向的方案。

比如在维护旧系统的时候,经常会遇到“祖传代码”,“离职代码”等遗留代码,面对这种情况,TDD怎样帮助我们?

①阅读代码与相关文档,理解代码。

②追加测试用例。

③小步迭代,增量式改进。

落地尝试

用前言中的代码来说,用以上三步骤来改进。

首先,阅读理解,这是最让人厌烦的,在当下,可以尝试用AI去理解。

解释代码
解释代码

追加测试用例,重复性的工作,也可以交给腾讯云AI代码助手

代码语言:java
复制
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class FizzBuzzTest {

    @Test
    public void testFizzBuzz() {
        assertEquals("FizzBuzz", FizzBuzz.fizzBuzz(15));
        assertEquals("Fizz", FizzBuzz.fizzBuzz(3));
        assertEquals("Buzz", FizzBuzz.fizzBuzz(5));
        assertEquals("1", FizzBuzz.fizzBuzz(1));
        assertEquals("2", FizzBuzz.fizzBuzz(2));
        assertEquals("Fizz", FizzBuzz.fizzBuzz(6));
        assertEquals("Buzz", FizzBuzz.fizzBuzz(10));
        assertEquals("FizzBuzz", FizzBuzz.fizzBuzz(30));
        assertEquals("4", FizzBuzz.fizzBuzz(4));
        assertEquals("7", FizzBuzz.fizzBuzz(7));
    }
}

小步迭代,其实就是重构这部分逻辑。

这是业务改进后,第一个代码的版本。

代码语言:java
复制
    if ((String.valueOf(num).contains("3") || num % 3 == 0) && (String.valueOf(num).contains("5") || num % 5 == 0)) {
        return "FizzBuzz";
    } else if (String.valueOf(num).contains("3") || num % 3 == 0) {
        return "Fizz";
    } else if (String.valueOf(num).contains("5") || num % 5 == 0) {
        return "Buzz";
    } else {
        return String.valueOf(num);
    }

在以上没有进行任何注释的情况下,可读性很差。如何重构呢,先抓住其特征。

很多重复的判断,那就试着提取出来(Introduce Field 引入字段)

代码语言:java
复制
  public static String fizzBuzz(int num) {
    // 包含3
    boolean containsThree = String.valueOf(num).contains("3");
    // 整除3
    boolean divisibleByThree = num % 3 == 0;
    // 包含5
    boolean containsFive = String.valueOf(num).contains("5");
    // 整除5
    boolean divisibleByFive = num % 5 == 0;

    if ((containsThree || divisibleByThree) && (containsFive || divisibleByFive)) {
        return "FizzBuzz";
    } else if (containsThree || divisibleByThree) {
        return "Fizz";
    } else if (containsFive || divisibleByFive) {
        return "Buzz";
    } else {
        return String.valueOf(num);
    }
  }

最后,代码完整的通过了测试用例。敏锐的你感觉似乎逻辑还可以再重构,刚想把字段提炼成函数,一个想法制止了你。

编程的第一法则
编程的第一法则

小节

软件工程中没有银弹,TDD也只是一种方式的选择,它降低了“判断一个人是否理解了需求“的成本,降低了“发现当前架构愿景不容易实现的需求“的成本等。其中包含的一些手段,单元测试,重构放在任何地方都是有帮助的。

代码质量是一个笼统的词,以前,能稳定运行就是好代码,现在还要加上一条:经过测试的代码才是好代码!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 什么是TDD
    • 为什么需要TDD
    • 落地尝试
  • 小节
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档