关于示例的问题在Robert C Martin的_Clean Code_
这是一个关于函数只做一件事的概念的问题。没有一些相关的上下文段落就没有意义,所以我在这里引用它们。它们出现在第37-38页:
换句话说,我们希望能够像程序一样读取程序
TO段落,每个段落描述当前的抽象级别,并在下一级别引用后续的TO段落。
要包括设置和拆卸,我们包括设置,然后我们包括测试页面内容,然后我们包括拆卸。要包含设置,我们包括套件设置,如果这是套件,那么我们包括常规设置。
事实证明,程序员学习遵循这个规则并写作是非常困难的
保持单一抽象级别的函数。但学习这个技巧也非常
重要。保持功能简洁并确保它们做“一件事”是关键。
使代码读取像一个自上而下的TO段落是一种有效的技术
保持抽象级别一致。
然后他给出了以下不良代码示例:
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);
}
}
并解释了它的问题如下:
这个功能有几个问题。首先,它很大,而且很新
员工类型被添加,它会增长。其次,它显然不止一件事。
第三,它违反了单一责任原则7
(SRP)因为不止一个
它改变的原因。第四,它违反了开放封闭原则8
(OCP)因为它
每当添加新类型时必须更改。
现在我的问题。
首先,我很清楚它是如何违反OCP的,而且我很清楚,仅凭这一点就会使它设计不佳。但是,我试图理解每个原则,而且我不清楚SRP是如何应用的。具体来说,我可以想象这个方法改变的唯一原因是增加了新的员工类型。只有一个“变革之轴”。如果需要更改计算的详细信息,这只会影响像“calculateHourlyPay()”这样的子方法
此外,虽然在某种意义上它显然做了3件事,这三件事都处于同一抽象层次,并且都可以被放入TO段中,与例子1没有区别:为了计算员工的工资,我们计算如果雇员受委托则委托工资,如果他是小时工资则按小时计算等等。因此,除了违反OCP之外,这段代码似乎符合马丁对清洁代码的其他要求,即使他认为它没有。
有人可以解释我错过了什么吗?
谢谢。
没有找到相关结果
已邀请:
3 个回复
视蕉梁拌客
痰嫉
搂腹时