返回

写代码勿轻心,构建函数存险情:探究构造函数里的参数依赖问题

前端

程序员的失误

我是一名软件工程师,最近在做一个新的项目。在这个项目中,我需要编写一个类来管理用户的结账信息。为了让这个类更灵活,我决定在构造函数中注入一个依赖项,以便我可以使用不同的支付方式来处理用户的结账。

public class Checkout {

    private final PaymentGateway paymentGateway;

    public Checkout(PaymentGateway paymentGateway) {
        this.paymentGateway = paymentGateway;
    }

    public void processPayment(PaymentDetails paymentDetails) {
        paymentGateway.processPayment(paymentDetails);
    }
}

这个代码看起来很简单,但它有一个致命的缺陷。如果我在以后的版本中修改了 PaymentGateway 类,那么这个代码就会中断。这是因为 Checkout 类依赖于 PaymentGateway 类,如果 PaymentGateway 类发生了变化,那么 Checkout 类也必须随之改变。

这种依赖关系被称为参数依赖。参数依赖是指一个类的构造函数接受另一个类作为参数。当另一个类发生变化时,构造函数就会中断。

参数依赖的危害

参数依赖可能会导致许多问题。其中最常见的问题是 breaking change 。breaking change是指一个代码修改导致其他代码中断。当一个类发生变化时,它可能会导致依赖于它的其他类中断。

在上面的例子中,如果我修改了 PaymentGateway 类,那么 Checkout 类就会中断。这是因为 Checkout 类依赖于 PaymentGateway 类,如果 PaymentGateway 类发生了变化,那么 Checkout 类也必须随之改变。

如何避免参数依赖

有很多方法可以避免参数依赖。其中最简单的方法是使用 依赖注入 。依赖注入是一种设计模式,它允许我们在运行时将依赖项注入到一个类中。这使得我们可以轻松地更改依赖项,而无需修改代码。

public class Checkout {

    private final PaymentGateway paymentGateway;

    public Checkout() {
        this.paymentGateway = new PaymentGateway();
    }

    public void processPayment(PaymentDetails paymentDetails) {
        paymentGateway.processPayment(paymentDetails);
    }
}

在这个例子中,我使用依赖注入将 PaymentGateway 类注入到了 Checkout 类中。这样,我就可以在运行时更改 PaymentGateway 类,而无需修改 Checkout 类的代码。

结语

参数依赖是一个常见的错误,它可能会导致许多问题。我们可以使用依赖注入来避免参数依赖,从而提高代码的质量和稳定性。