gpt4 book ai didi

java - 关于 Robert C Martin Clean Code 中示例的问题

转载 作者:搜寻专家 更新时间:2023-11-01 00:53:12 24 4
gpt4 key购买 nike

这是一个关于函数只做一件事的概念的问题。如果没有一些相关的上下文上下文就没有意义,所以我会在这里引用它们。它们出现在第 37-38 页:

To say this differently, we want to be able to read the program as though it were a set of TO paragraphs, each of which is describing the current level of abstraction and referencing subsequent TO paragraphs at the next level down.

To include the setups and teardowns, we include setups, then we include the test page content, and then we include the teardowns. To include the setups, we include the suite setup if this is a suite, then we include the regular setup.

It turns out to be very difficult for programmers to learn to follow this rule and write functions that stay at a single level of abstraction. But learning this trick is also very important. It is the key to keeping functions short and making sure they do “one thing.” Making the code read like a top-down set of TO paragraphs is an effective technique for keeping the abstraction level consistent.

然后他给出了以下糟糕代码的示例:

public Money calculatePay(Employee e) 
throws InvalidEmployeeType {
switch (e.type) {
case COMMISSIONED:
return calculateCommissionedPay(e);
case HOURLY:
return calculateHourlyPay(e);
case SALARIED:
return calculateSalariedPay(e);
default:
throw new InvalidEmployeeType(e.type);
}
}

并解释了它的问题如下:

There are several problems with this function. First, it’s large, and when new employee types are added, it will grow. Second, it very clearly does more than one thing. Third, it violates the Single Responsibility Principle7 (SRP) because there is more than one reason for it to change. Fourth, it violates the Open Closed Principle8 (OCP) because it must change whenever new types are added.

现在我的问题。

首先,我很清楚它是如何违反 OCP 的,而且我很清楚,仅此一点就使它的设计很糟糕。但是,我试图理解每条原则,但我不清楚 SRP 是如何应用的。具体来说,我能想到的改变这种方法的唯一原因是增加了新的员工类型。只有一个“变化轴”。如果计算的细节需要改变,这只会影响像“calculateHourlyPay()”这样的子方法

此外,虽然在某种意义上它显然在做 3 件事,但这三件事都处于同一抽象级别,并且都可以放入一个 TO 段落中,与示例一无异:TO calculate pay对于员工,如果员工是受委托(delegate)的,我们计算委托(delegate)工资,如果他是小时工,我们计算小时工资,等等。。因此,除了违反 OCP 之外,这段代码似乎符合 Martin 对干净代码的其他要求,尽管他辩称不符合。

有人可以解释一下我错过了什么吗?

谢谢。

最佳答案

calculatePay 发生变化似乎有两个原因:

  1. 员工类型的变化
  2. 薪酬计算的变化

两个不同的变化轴。但是,calculatePay 方法的职责是支付计算。只有在薪酬计算公式发生变化时,它才应该发生变化。我认为这就是作者声明该方法违反 SRP 的原因。

在书中,作者提供了一个解决方案,他为派生自公共(public) Employee 抽象基类的每个员工类型定义类。他将 calculatePay 方法移至 Employee 基类,并定义了一个 Employee 工厂类,该类在给定员工类型的情况下创建适当的员工对象。这样每个工资计算都封装在一个特定的员工类型类中,因此不受员工类型变化的影响。此外,这个简单解决方案中的员工工厂类仅受员工类型变化的影响。因此,新的解决方案让 SRP 很高兴。

在新的解决方案中,你要求员工计算他/她的工资,我不喜欢,因为这不反射(reflect)现实。您实际上可以争辩说这也违反了 SRP。这个计算是工资部门的责任。我喜欢软件中的模型尽可能代表现实世界的领域,但我们通常不得不做出妥协。在这种情况下,我会说员工类型的变化不会定期发生。事实上,它们很可能很少发生。因此,我会将事情保留在对业务领域有意义的地方,例如要求工资单对象计算员工工资。与此同时,我将拥有并保留一套广泛的单元测试,因为人们应该拥有这些单元测试,以确保当员工类型发生变化时,一切都继续按预期工作。

关于java - 关于 Robert C Martin Clean Code 中示例的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4533111/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com