在下面的视频中,作者采用了一个现有的类并将单一责任原则分配给它。他参加了一个打印类,该类的任务是访问数据、格式化和打印报告。他将每个方法分解为自己的类,因此他创建了一个 DataAccess 类来处理数据访问,他创建了一个 ReportFormatter 类来处理报表的格式,他创建了一个 ReportPrinter 类来处理报表的打印。原来的 Report 类只剩下一个方法 Print(),它调用 ReportPrinter 的类方法 Print。DataAccess 和 ReportFormatter 似乎有责任,但 ReportPrinter 依赖于 DataAcess 和 ReportFormatter,所以这不会破坏 SRP 还是我误解了它?
4 回答
单一职责原则表明给定的类应该有单一职责(或“改变的理由”)。它本身并没有表明如何履行这一责任。这样做可以而且经常需要多个其他班级作为合作者的合作。
不看视频,这听起来像是一个合理的设计。SRP 没有被破坏,因为处理数据访问的方法没有出现在 ReportPrinter 类中,只有“我可以调用某些东西来获取我想要的数据”的概念。
您可以将它推得更远,并有一个协调器类只负责协调数据访问类、格式化程序类和打印机类的活动。您还可以以不同的方式排列对象,例如让协调器将数据发送到格式化程序,格式化程序将其发送到打印机,而协调器不(直接)知道打印机。
关于协调狭隘对象的努力,必须知道一些事情。这成为他们的责任。只要您不知道或不关心它们是如何做的,就可以了解其他对象将要做什么的想法或概念。将接口视为“责任接缝”是一个好的开始。
如果您将对象视为相互传递数据而不是“做”事情,这也会很有帮助。因此,ReportFormatter 返回(或转发)一个表示格式化报表的新对象,而不是(从概念上)在现有报表上执行对象。
不,它不会破坏 SRP。
假使,假设
DataAccess implements IDataAccess
ReportFormatter implements IReportFormatter
ReportPrinter implements IReportPrinter
事件虽然ReportPrinter relies on DataAccess and ReportFormatter
,合同的任何变更IDataAccess or IReportFormatter
都应由DataAccess and ReportFormatter
各自执行。ReportPrinter
不担心这些类的职责变化。
您可以拥有Composition
或实现Mediator模式以在这三个类之间提供松散耦合并完成工作。保持coupling
部分远离responsibility
。
SRP 不解决依赖关系。将类分解为单一职责类将有助于以后打破这些依赖关系。SRP 解决了经常一起提到的两个原则之一:内聚和耦合。SRP 是关于高内聚的,并且依赖关系可以表示高耦合。好的设计具有高内聚和低耦合。有时这两个原则可能不一致。