如果一个对象解析它自己的输入,它是否被认为破坏了 SRP?
If an object parse it's own input, is it considered breaking SRP?
如果一个对象解析它自己的输入,是否被认为破坏了 SRP?
例如
class A
{
int x;
string y;
float f;
A(string x, string y, string f)
{
this.x = int.Parse(x);
if (this.x < 0 || this.x > 10)
{
throw new ArgumentOutOfRangeException();
}
this.y = y;
this.f = float.Parse(f);
}
}
或者拥有私有构造函数并使用 public 静态方法来解析和检查输入以及 return A
.
而不是传递 int、字符串和浮点数,然后解析并检查它们在其他地方是否有效。
是否违反单一职责原则?不,给出的例子是解析原始类型,构造一个基本对象,在你给出的示例代码中我不认为它本身就是一种责任。考虑到要在其中运营的业务领域,SRP 更容易解释...
详细地说,上面使用的解析是针对原始数据类型的,内置的原始类型解析有助于将一种原始类型转换为另一种原始类型。 SRP 的目的不是抽象出这样的核心功能,而是确保你的代码设计具有单一的职责。例如,当将记录保存到数据库时,您可以编写一个函数来获取原始数据,将其映射到不同的表并发送电子邮件以确认条目,这会破坏 SRP。在这样的例子中我们如何避免这种情况?使用诸如存储库模式之类的东西来抽象掉数据库问题,使用单独的 class 来管理电子邮件通信,也许使用依赖注入来确保这些组件在您的解决方案中可以轻松互换。我会认真尝试抽象所有基本类型的基本解析吗?
绝对不会。
支撑整个概念的是 "reason to change",如果您的代码设计有不止一个必须更改的原因,那就是破坏了 SRP。在给出的示例中,如果电子邮件、原始数据或到不同表的映射发生变化,我们需要更改代码,原因有 3 个以上。
也就是说,理想情况下,您的构造函数或函数应该接受正确的类型,可能有一些原因导致您不能这样做,但是如果您可以提供正确类型的值,您应该避免解析。
最后要补充的一件事:我看到许多开发人员在诸如与基本类型、解析和构造对象相关的问题上感到困惑,试图确保不会破坏任何设计原则,例如 SRP。他们花了数小时仔细研究问题,结果错过了更大的领域设计问题。尽量确保您可以看到更大的图景,并且不会忽视您的应用程序架构。我并不是建议您永远不要担心这些事情,只是不要陷入在设计应用程序时遗漏更大问题的陷阱。
如果我们同意解析是一种责任(因为它引入了与数据格式相关的变化轴),那么唯一的问题是 class A
是否还有其他责任。如果 class A
有与解析无关的额外逻辑,那将表明另一个责任。
有趣的是 class A
已经在解析和验证其输入。验证可能是与业务需求相关的第二个变化轴。这是否违反了 SRP?这取决于我们认为这两个轴独立变化的可能性有多大。
如果一个对象解析它自己的输入,是否被认为破坏了 SRP?
例如
class A
{
int x;
string y;
float f;
A(string x, string y, string f)
{
this.x = int.Parse(x);
if (this.x < 0 || this.x > 10)
{
throw new ArgumentOutOfRangeException();
}
this.y = y;
this.f = float.Parse(f);
}
}
或者拥有私有构造函数并使用 public 静态方法来解析和检查输入以及 return A
.
而不是传递 int、字符串和浮点数,然后解析并检查它们在其他地方是否有效。
是否违反单一职责原则?不,给出的例子是解析原始类型,构造一个基本对象,在你给出的示例代码中我不认为它本身就是一种责任。考虑到要在其中运营的业务领域,SRP 更容易解释...
详细地说,上面使用的解析是针对原始数据类型的,内置的原始类型解析有助于将一种原始类型转换为另一种原始类型。 SRP 的目的不是抽象出这样的核心功能,而是确保你的代码设计具有单一的职责。例如,当将记录保存到数据库时,您可以编写一个函数来获取原始数据,将其映射到不同的表并发送电子邮件以确认条目,这会破坏 SRP。在这样的例子中我们如何避免这种情况?使用诸如存储库模式之类的东西来抽象掉数据库问题,使用单独的 class 来管理电子邮件通信,也许使用依赖注入来确保这些组件在您的解决方案中可以轻松互换。我会认真尝试抽象所有基本类型的基本解析吗?
绝对不会。
支撑整个概念的是 "reason to change",如果您的代码设计有不止一个必须更改的原因,那就是破坏了 SRP。在给出的示例中,如果电子邮件、原始数据或到不同表的映射发生变化,我们需要更改代码,原因有 3 个以上。
也就是说,理想情况下,您的构造函数或函数应该接受正确的类型,可能有一些原因导致您不能这样做,但是如果您可以提供正确类型的值,您应该避免解析。
最后要补充的一件事:我看到许多开发人员在诸如与基本类型、解析和构造对象相关的问题上感到困惑,试图确保不会破坏任何设计原则,例如 SRP。他们花了数小时仔细研究问题,结果错过了更大的领域设计问题。尽量确保您可以看到更大的图景,并且不会忽视您的应用程序架构。我并不是建议您永远不要担心这些事情,只是不要陷入在设计应用程序时遗漏更大问题的陷阱。
如果我们同意解析是一种责任(因为它引入了与数据格式相关的变化轴),那么唯一的问题是 class A
是否还有其他责任。如果 class A
有与解析无关的额外逻辑,那将表明另一个责任。
有趣的是 class A
已经在解析和验证其输入。验证可能是与业务需求相关的第二个变化轴。这是否违反了 SRP?这取决于我们认为这两个轴独立变化的可能性有多大。