Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 在干净代码示例中理解单一责任主体SRP_Oop_Design Patterns_Coding Style_Single Responsibility Principle - Fatal编程技术网

Oop 在干净代码示例中理解单一责任主体SRP

Oop 在干净代码示例中理解单一责任主体SRP,oop,design-patterns,coding-style,single-responsibility-principle,Oop,Design Patterns,Coding Style,Single Responsibility Principle,目前,我正在阅读Bob叔叔的干净代码手册,在函数部分中查看以下示例:- public Money calculatePay(Employee e) throws InvalidEmployeeType { switch (e.type) { case COMMISSIONED: return calculateCommissionedPay(e); case HOURLY: return calculateH

目前,我正在阅读Bob叔叔的干净代码手册,在函数部分中查看以下示例:-

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),因为有不止一个原因 让它改变。第四,它违反了开闭原则(OCP) 因为每当添加新类型时,它都必须更改

他提出了如下解决方案:-

public abstract class Employee {
    public abstract boolean isPayday();
    public abstract Money calculatePay();
    public abstract void deliverPay(Money pay);
}
-- -- -- -- -- -- -- -- -
public interface EmployeeFactory {
    public Employee makeEmployee(EmployeeRecord r) throws InvalidEmployeeType;
}
-- -- -- -- -- -- -- -- -
public class EmployeeFactoryImpl implements EmployeeFactory {
    public Employee makeEmployee(EmployeeRecord r) throws InvalidEmployeeType {
        switch (r.type) {
            case COMMISSIONED:
                return new CommissionedEmployee(r);
            case HOURLY:
                return new HourlyEmployee(r);
            case SALARIED:
                return new SalariedEmploye(r);
            default:
                throw new InvalidEmployeeType(r.type);
        }
    }
}
我不能完全理解这个例子中的想法,我脑子里有一个问题我找不到答案:-

1-在第一个代码中,当添加新员工时,它将增长。是的,但这也发生在解决方案中,那么区别是什么呢?

2-第一个示例如何做不止一件事。它只计算支付“在同一抽象层次的函数”注意到如果我们考虑抛出错误是另一回事,解决方案也太过了。
BR/>

< P > 1)更多代码更难理解、调试和维护。当然,这个例子没有那么大,但你明白了。保持类的小型化和针对性有助于维护性、可扩展性和可重用性。此外,如果您更改代码,为新员工类型添加新的部分,则可能会破坏旧代码

2) 每次计算的逻辑都会有所不同。因此,全班正在做三件不同的事情。如果您将每个计算划分为自己的类,您将获得1中提到的好处,而且解决方案更易于测试

First, it’s large, and when new employee types are added, it will grow.
你是对的,这个解决方案并没有真正使整个代码变短,而且当添加一个新的员工类型时,它仍然会总体增长

Second, it very clearly does more than one thing.
原始系统将处理发送到正确的付款计算功能并计算付款。建议的解决方案解决了这一问题
HourlyEmployee.calculatePay()
现在只计算
HourlyEmployee
等员工的工资。
employeefactoryemploy
根据其返回的
员工
实现处理派遣

Third, it violates the Single Responsibility Principle (SRP) because there is more than one reason for it to change.
如果需要更改薪资计算逻辑,则需要更改原始的
calculatePay
。如果添加了新的员工类型,它也需要更改。添加新员工类型时,解决方案不需要更改为
calculatePay
。因此,改变只有一个责任和一个理由

Fourth, it violates the Open Closed Principle (OCP) because it must change whenever new types are added

回到
1
,添加新员工类型时,代码的总长度仍将更改。但是,只有与处理员工类型相关的部分需要更改。用于计算工资的代码根本不需要更改。因此,需要扩展的部分是开放的,而与扩展无关的部分是关闭的。

如果我们考虑计算佣金小时工资超过一件事,我注意到它们都是“第一代码”中的函数(在同一抽象级别),所以他们做了一件事,Uncle Bob说。“如果函数只执行比函数名称低一级的步骤,则函数只执行一件事“清除代码第36页当然,在应用解决方案后,calculatePay函数将不需要更改,而更改将应用于工厂类EmployeeFactoryImpl,这是否可以接受?@MostafaDarwish原始版本不需要只执行函数名称下方的第1级步骤。除了计算付款外,
calculatePay
还处理发送到正确付款计算功能的操作。如示例所示,这不是“比函数的指定名称低一级”。我们可以清楚地看到这一点,因为
EmployeeFactoryImpl
,它不知道任何计算工资的逻辑,仍然可以正确地处理调度。好的,我们把它称为“to”:-“要计算薪酬,我们应该选择员工类型,要选择员工类型,我们会切换员工类型,如果是佣金,我们会计算佣金…”你说得对,他们不在同一级别