我应该向 class 添加新方法而不是使用单一职责原则吗

Should I add new methods to a class instead of using Single Responsibility Principle

我们举办了一个研讨会,我向我的团队介绍了单一职责原则,以便我们在我们的项目中使用它。 我使用了以下流行示例:

class Employee:
    save()
    calculate_salary()
    generate_report()

然后我让团队告诉我们这个 class 是否一切正常。每个人都告诉我没关系。 但我在这里看到了三个违反 SRP 原则的行为。 如果我说所有方法都应该从 class 中提取,我说得对吗? 我的推理:

如果更改我们的数据库,save() 方法是更改​​的原因。

calculate_salary()方法是变化的原因,因为工资政策可能会改变。

generate_report() 方法是更改​​的原因,如果我们想更改报告的呈现方式(即 csv 而不是 html)。

我们采用最后一种方法。我想出了以下 HtmlReportGenerator class.

class HTMLReportGenerator:
    def __init__(self, reportable):
        self.reportable = reportable

    def generate_csv_report()

class CSVReportGenerator:
    def __init__(self, reportable):
        self.reportable = reportable

    def generate_html_report()

现在即使此生成器的业务逻辑发生变化,它也不会触及员工 class,这是我的主要观点。此外,现在我们可以将那些 classes 重用于 Employee class 对象以外的对象。

但团队想出了一个不同的 class:

class Employee:
    save()
    calculate_salary()
    generate_html_report()
    generate_csv_report()

他们明白自己违反了 SRP,但这对他们来说没问题。

这是我没有其他想法可以争取的地方))

对这种情况有什么想法吗?

我同意你的看法,通过添加额外的功能他们违反了 SRP 和 open/close 原则,并且每次有新的报告类型他们都会再次违反它。

我会保留 generate_report() 函数,但从具有函数 generate() 的接口类型 "ReportType" 添加一个参数。

这意味着例如您可以调用(请原谅我的Java):

employee.generate_report(new CSVReport())

employee.generate_report(new HTMLReport())

明天如果您想添加一个 XML 报告,您只需从报告界面实施 XML 报告并调用 :

employee.generate_report(new XMLReport())

这给了你很大的灵活性,不需要为新的报告类型更换员工,而且更容易测试(例如,如果 generate_report 有复杂的逻辑,你可以只创建一个 TestReport class 实现 Report 接口,只是打印到输出流进行调试和调用 generate_report(new TestReport()))