jpo*_*poh 12 class-design single-responsibility-principle
假设我有一个如下所示的类:
internal class SomeClass
{
IDependency _someDependency;
...
internal string SomeFunctionality_MakesUseofIDependency()
{
...
}
}
Run Code Online (Sandbox Code Playgroud)
然后我想添加相关的功能,但是使用不同的依赖来实现其目的.也许类似如下:
internal class SomeClass
{
IDependency _someDependency;
IDependency2 _someDependency2;
...
internal string SomeFunctionality_MakesUseofIDependency()
{
...
}
internal string OtherFunctionality_MakesUseOfIDependency2()
{
...
}
}
Run Code Online (Sandbox Code Playgroud)
当我为这个新功能编写单元测试(或者更新我对现有功能的单元测试)时,我发现自己创建了SomeClass(SUT)的新实例,同时传入null以获取我不需要的依赖项对于我想要测试的特定功能.
这对我来说似乎是一种难闻的气味,但我发现自己走这条路的原因是因为我发现自己正在为我介绍的每一项新功能创建新的类.这似乎也是一件坏事,所以我开始尝试将类似功能组合在一起.
我的问题:如果一个类的所有依赖关系都被它的所有功能所消耗,即如果不同的功能位使用不同的依赖关系,那么它们是否应该存在于不同的类中?
小智 11
当每个实例方法接触每个实例变量时,该类最大程度地具有内聚性.当没有实例方法与任何其他方法共享实例变量时,该类具有最小的内聚性.虽然我们确实希望凝聚力很高,但80-20规则也适用.获得凝聚力的最后一点点增加可能需要做出努力.
一般来说,如果你有不使用某些变量的方法,那就是气味.但是一个小气味不足以完全重构这个阶级.这是值得关注和关注的事情,但我不建议立即采取行动.
SomeClass 是否维护内部状态,或者只是“组装”各种功能?你能这样重写吗:
\n\ninternal class SomeClass\n{\n ...\n\n\n internal string SomeFunctionality(IDependency _someDependency)\n {\n ...\n }\n\n internal string OtherFunctionality(IDependency2 _someDependency2)\n {\n ...\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n在这种情况下,如果 SomeFunctionality 和 OtherFunctionality 在某种程度上(功能上)相关,而使用占位符并不明显,则您可能不会破坏 SRP。
\n\n而且您还可以从客户端选择要使用的依赖项,而不是在创建/DI 时选择。也许为这些方法定义用例的一些测试将有助于澄清情况:如果您可以编写一个有意义的测试用例,其中在同一对象上调用两种方法,那么您就不会破坏 SRP。
\n\n至于 Facade 模式,我已经见过太多次了,当你最终得到 50 多个方法类时,我已经不喜欢它了……问题是:为什么需要它?出于效率原因 \xc3\xa0 la 老式 EJB?
\n