重构坏代码篇-异曲同工的类

重构坏代码篇-异曲同工的类

**异曲同工的类(Divergent Change)**是一种代码坏味道,它指的是多个类在不同的方向上发生变化,即一个类的修改会导致其他类也需要相应的修改。

下面是一个 Java 示例:

// 异曲同工的类示例

// 原始类A
class A {
    private int x;

    public void setX(int value) {
        x = value;
    }

    public int calculate() {
        // 计算逻辑
        return x * 2;
    }
}

// 原始类B
class B {
    private int y;

    public void setY(int value) {
        y = value;
    }

    public int calculate() {
        // 计算逻辑
        return y * 3;
    }
}

// 新需求:增加一个类C,需要使用A和B的计算结果

class C {
    private A a;
    private B b;

    public C(A a, B b) {
        this.a = a;
        this.b = b;
    }

    public int calculate() {
        int resultA = a.calculate(); // 使用A的计算结果
        int resultB = b.calculate(); // 使用B的计算结果
        return resultA + resultB;
    }
}

在上述示例中,类A和类B都有自己的计算逻辑,并且类C需要使用A和B的计算结果进行进一步的计算。如果在未来需求变更,需要修改类A或类B的计算逻辑,那么类C也需要相应地进行修改,否则可能导致计算结果错误。

这种情况下,类A和类B在不同的方向上发生变化,即它们的修改会影响到其他类(如类C)。这违反了单一职责原则(Single Responsibility Principle),应该考虑重构代码,将计算逻辑从类A和类B中抽取出来,形成一个独立的类,以避免异曲同工的类问题。

重构

要解决异曲同工的类问题,可以使用以下重构手法之一:抽取方法(Extract Method)和抽取类(Extract Class)。

  1. 抽取方法(Extract Method):

    • 针对类A和类B中的计算逻辑,将其抽取为独立的方法。
    • 在类A中创建一个新的方法,例如calculateValue(),将原来的计算逻辑放入其中。
    • 在类B中也创建一个新的方法,例如calculateValue(),将原来的计算逻辑放入其中。
    • 然后,类C可以直接调用这两个抽取出来的方法,而不需要再依赖类A和类B的具体实现。
  2. 抽取类(Extract Class):

    • 创建一个新的类,例如Calculator,用于封装计算逻辑。
    • 将类A和类B中的计算逻辑移动到Calculator类中的相应方法中。
    • 类A和类B只需要引用Calculator类的实例,并调用相应的方法来获取计算结果。
    • 类C也只需要引用Calculator类的实例,并调用相应的方法来获取A和B的计算结果。

通过抽取方法或抽取类,我们将计算逻辑从原来的类中分离出来,形成一个独立的类或方法,以避免异曲同工的类问题。这样,当需要修改计算逻辑时,只需要修改独立的类或方法,而不会影响其他类的实现。这符合单一职责原则,使代码更加清晰、易于理解和维护。

请注意,具体的重构手法取决于代码的结构和需求的复杂程度。在实际应用中,可能需要结合其他重构手法或进行适当的调整,以满足具体情况的需求。

下面是使用抽取类(Extract Class)重构手法来解决异曲同工的类问题的代码示例:

// 抽取类示例

// 原始类A
class A {
    private int x;

    public void setX(int value) {
        x = value;
    }

    public int calculate() {
        // 计算逻辑
        return x * 2;
    }
}

// 原始类B
class B {
    private int y;

    public void setY(int value) {
        y = value;
    }

    public int calculate() {
        // 计算逻辑
        return y * 3;
    }
}

// 新建抽取的类Calculator
class Calculator {
    public int calculateValue(int value, int multiplier) {
        return value * multiplier;
    }
}

// 新需求:增加一个类C,需要使用A和B的计算结果

class C {
    private Calculator calculator;
    private int resultA;
    private int resultB;

    public C(A a, B b) {
        calculator = new Calculator();
        resultA = calculator.calculateValue(a.getX(), 2); // 使用Calculator类的计算方法
        resultB = calculator.calculateValue(b.getY(), 3); // 使用Calculator类的计算方法
    }

    public int calculate() {
        return resultA + resultB;
    }
}

在上述示例中,我们创建了一个新的类Calculator,用于封装计算逻辑。类A和类B的计算逻辑被移动到Calculator类中的calculateValue方法中。类C引用Calculator类的实例,并调用calculateValue方法来获取A和B的计算结果。

通过这种重构,我们将计算逻辑从原来的类A和类B中抽取出来,形成了一个独立的类Calculator。现在,当需要修改计算逻辑时,只需要修改Calculator类中的对应方法,而不会影响类A和类B的实现。这样,类C也不再依赖于类A和类B的具体实现,而是通过Calculator类来获取计算结果,解决了异曲同工的类问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值