重构第十章:简化函数调用

发布时间:2023年12月22日

当我们编写软件时,代码的可读性和可维护性是至关重要的。第十章介绍了一系列精妙的方法,旨在简化函数调用,使得我们的代码更易读、更易维护。

引入参数对象(Introduce Parameter Object)

有时,一个函数的参数列表变得异常冗长,这使得代码难以维护。为了解决这个问题,我们可以引入参数对象。这就好比将相关的参数捆绑成一个对象,然后将这个对象当作函数的参数传递,使得函数调用更为清晰。

// Before
double calculateTotalSalary(double baseSalary, double bonus, double taxRate) {
    // calculation logic
}

// After
double calculateTotalSalary(SalaryCalculationParams params) {
    // calculation logic
}

以查询取代参数(Replace Parameter with Query)

有时候,函数内部需要计算一个值,而这个值却可以通过函数内部其他数据的计算得到。为了简化代码,我们可以去除函数参数,直接在函数内部计算需要的值。

// Before
double calculateTotalPrice(double basePrice, double taxRate) {
    // calculation logic using basePrice and taxRate
}

// After
double calculateTotalPrice() {
    // calculation logic using internally stored basePrice and taxRate
}

以命令取代查询(Replace Query with Command)

当一个函数返回一个值,而这个值可以通过修改对象状态得到时,我们可以将返回值的计算过程改为修改对象状态的命令。

// Before
double getTotalAmount(Order order) {
    // calculation logic
    return totalAmount;
}

// After
void calculateTotalAmount(Order order) {
    // modify order's internal state
}

移除设值函数(Remove Setting Method)

有时,对象在创建后会发生变化,但却没有提供设值函数。我们可以添加设值函数,使得对象状态可以在创建后进行修改。

// Before
Order order = new Order();
order.setDiscount(0.1);

// After
Order order = new Order();
order.applyDiscount(0.1);

封装函数(Encapsulate Function)

如果函数的调用者直接使用被调用函数的返回值,我们可以将被调用函数的返回值封装成一个新的函数,以便调用者通过新的函数获取结果。

// Before
double calculateArea(double radius) {
    return Math.PI * radius * radius;
}

// After
double getCircleArea(double radius) {
    return calculateArea(radius);
}

以工厂函数取代构造函数(Replace Constructor with Factory Method)

当我们需要更多的对象创建灵活性时,可以使用工厂函数代替直接使用构造函数,允许在创建对象时进行更多的逻辑操作。

// Before
Person person = new Person("John", 30);

// After
Person person = Person.createPerson("John", 30);

以明确的函数取代参数方法(Replace Parameter with Explicit Methods)

如果函数使用一个参数来控制其行为,而这个参数可能有多个取值,我们可以用多个明确的函数替换带有参数的函数。

// Before
double calculateDiscount(double totalAmount, String discountType) {
    // calculation logic based on discountType
}

// After
double calculateRegularDiscount(double totalAmount) {
    // calculation logic for regular discount
}

double calculateVIPDiscount(double totalAmount) {
    // calculation logic for VIP discount
}

将接收对象设为参数(Move Accumulation to Collecting Parameter)

如果一个函数内部累积某个值,但调用者可能需要多次调用才能获取全部结果,我们可以将累积值的对象作为参数传递给函数,由调用者控制累积的过程。

// Before
double calculateTotalAmount(Order order) {
    // calculate and accumulate total amount
}

// After
double calculateTotalAmount(Order order, double accumulatedTotal) {
    // accumulate total amount based on the provided accumulatedTotal
}

引入调停者(Introduce Mediator)

当多个对象需要相互通信,导致紧密耦合时,我们可以引入一个调停者对象。这个调停者负责集中对象之间的通信,降低对象之间的直接耦合。

// Before
class Colleague {
    void sendMessage(String message) {
        // communicate with other colleagues
    }
}

// After
class Colleague {
    void sendMessage(String message, Mediator mediator) {
        mediator.sendMessage(message, this);
    }
}

以管道取代函数(Replace Function with Pipeline)

当多个函数调用形成链式调用,代码难以阅读时,我们可以将链式调用替换为管道形式,使代码更加清晰。

// Before
double result = add(multiply(square(3), 2), 5);

// After
double result = Pipeline.of(3)
    .apply(Math::square)
    .apply(x -> multiply(x, 2))
    .apply(x -> add(x, 5))
    .getResult();

这些简化函数调用的方法为我们提供了更灵活、简洁的编码方式,有助于提高代码的可读性和可维护性。在使用这些方法时,请根据具体情况灵活选择,以确保代码质量和可维护性。

文章来源:https://blog.csdn.net/qq_44444470/article/details/134811412
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。