我应该向 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()))
我们举办了一个研讨会,我向我的团队介绍了单一职责原则,以便我们在我们的项目中使用它。 我使用了以下流行示例:
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()))