什么是一类,一个责任原则?

时间:2012-04-21 22:29:18

标签: java design-patterns solid-principles

我想了解 One Class,One Responsibility 原则。我找到了一些关于它的文章,但没有例子。如果你能给我一个违反这个原则的课程的例子,这对我有帮助。

我熟悉一个方法应该只做一件事的想法,例如get和set方法。它不能与 One Class,One Responsibility 相同,因为set和get方法都是在类中实现的。那么这是否意味着该类违反了该规则,因为该类有责任设置和获取?

什么是一类,一个责任原则

5 个答案:

答案 0 :(得分:1)

我不是这个设计模式的100%专家,但这就是我对它的看法 - 如果我创建一个对象,那么完全负责一件事。如果它需要做其他事情,但与另一个对象有关,根据情况,我会使用继承或接口。

这个概念看起来相当简单;确保特定对象(或方法)处理一个逻辑。如果它处理更多,你需要另一个对象(或方法)。

答案 1 :(得分:0)

原则正是它所说的,而不是更多。一个班级应该只有一个责任。 但是,定义责任可能很困难。一个示例可以是“DatabaseHandler”类,它处理应用程序中的所有数据库请求。

进一步阅读:cohesion

答案 2 :(得分:0)

关于不混合责任的原则方面。

如果您有一个处理发票的InvoiceProcessor类,按业务规则进行计算,生成带有发票的PDF,处理数据库并向卖方注册额外的奖励积分,那么您就明确需要分离关注点。在这种情况下,应明确分离甚至授权给其他班级。

但是一类 - 一个责任更加微妙和可怕。如果您必须提供发票处理的解决方案,并且有多个目标可以实现,例如这些奖励积分,您可以使用违规功能来实现多个目标:计算卖家的奖励积分和客户的折扣。

在较小的范围内:如果你有一个具有数据结构的类,如优先级队列或其他什么,同时将它与数据结构混合以缓存一个部分,使用一个List和一个Map,那么你在一些地方操纵不同问题的数据,甚至可能在缓存列表内寻址,以便数据结构交织在一起。如果你有一个改变优先级并改变缓存状态的函数,那么将来很难理解这些进程。

我经常遇到需要实施某些不同方面的违规行为,而且这些行为是在一个类中完成的。然后,API具有不同抽象级别的调用,或者是一种困难的语义。

答案 3 :(得分:0)

这是你不知道自己需要的东西之一,直到你试图没有它,看看它是如何变成一团糟:

假设您编写了自己的Logger实用程序,并且因为它从简单开始(带有写入stdout的方法的单例),您决定将其所有功能放在一个类中。在使用它时,您会想到要添加的更多功能:

  • 要登录的不同目的地(stderr,文件,队列等等)

  • 更改讯息格式的功能

  • 为不同类别提供单独的记录器

  • 按日志级别过滤类别消息的能力

  • 您希望能够在程序运行时更改日志记录级别

  • 新的日志记录级别(错误,警告,信息,调查等)

等,并将每个功能的实现添加到您开始使用的同一个类中。您所做的每一项更改都意味着返回同一个班级,对其进行排序以查看相关内容,然后进行更改。该类将具有不同的生命周期事件,其中每个特征都被初始化,因此所有特征代码不在一个地方,它分布在类中的不同方法中。

因为所有代码都集中在一个类中,并且方法包含实现不同功能的代码,因此跟踪所有相关部分以进行更改会变得具有挑战性,并且总是有可能更改可能会无意中影响其他某些功能,因此某些先前存在的功能现在可能在某些情况下停止工作。因此,您必须测试类中的所有功能,更糟糕的是,所有功能的所有组合,以便捕获这些错误。这意味着测试将是不完整的,错误可以潜入。

现在看看像log4j这样的真实项目如何处理这些东西。关注点分离,不同的类处理格式化,处理输出的编写方式,为类别提供记录器,以及所有这些部分之间的交互是明确定义的,结果是当您修改或替换一个部分时不影响其他作品。用户可以创建自己的类来添加他们需要的功能(他们不需要知道有关日志框架的所有内容,他们只需要知道他们想要添加的特定类型的部分的合同)并将其插入,用户可以混合搭配不同的插件。如果插件被破坏,那么破坏不会超出该插件,并且对单个部件的更改不会威胁整个项目的完整性。如果合同管理各个部分的交互,则无需测试特定功能的所有不同组合。它的工作原理是因为它由各自负责的部分组成。

使用单一类方法你永远不会这样做,有人添加的每一项新功能都将成为项目的一个分支,并且将每个新功能合并为一个逐渐变大的任务。单一责任原则和其他SOLID规则的要点是提供一种整体策略,使得能够以受控方式更改软件而不会破坏事物。

答案 4 :(得分:0)

班级中的每件事都应该与班级应该负责的事情有关。

如果它是一个名为MailSender的类,它应该只知道如何发送邮件。创建邮件内容的代码不应该在其中。