Joh*_*n H 15 c# single-responsibility-principle solid-principles
我正在努力了解SRP,但是,虽然我理解了如何应用它的原因,但我并没有真正看到这样做的好处.考虑这个例子,取自Robert Martin的SRP PDF:
interface IModem
{
void Dial(string number);
void Hangup();
void Send(char c);
char Recv();
}
Run Code Online (Sandbox Code Playgroud)
他建议将其分为两个界面:
interface IModemConnection
{
void Dial(string number);
void Hangup();
}
interface IModemDataExchange
{
void Send(char c);
char Recv();
}
Run Code Online (Sandbox Code Playgroud)
我也一直在阅读这篇文章,它更进了一步:
interface IModemConnection : IDisposable
{
IModemDataExchange Dial(string number);
}
interface IModemDataExchange
{
void Send(char c);
char Recv();
}
Run Code Online (Sandbox Code Playgroud)
在这一点上,我理解functional(Send / Recv)和non-functional(Dial / Hangup)方面的含义,但我没有看到在这个例子中分离它们的好处.考虑到这个基本实现:
class ConcreteModem : IModemConnection
{
public IModemDataExchange Dial(string number)
{
if (connection is successful)
{
return new ConcreteModemDataExchange();
}
return null;
}
public void Dispose()
{
//
}
public bool IsConnected { get; private set; }
}
Run Code Online (Sandbox Code Playgroud)
在这一点上,让我再次引用罗伯特马丁,即使他正在谈论与PDF不同的例子:
其次,如果对GraphicalApplication的更改导致Rectangle由于某种原因而发生更改,则该更改可能会强制我们重建,重新测试和重新部署ComputationalGeometryApplication.如果我们忘记这样做,该应用程序可能会以不可预测的方式破坏.
这是我不明白的.如果我必须创建第二个实现IModemDataExchange,并且我想要使用它,我仍然需要更改Dial方法,这意味着该类也需要重新编译:
public IModemDataExchange Dial(string number)
{
if (some condition is met)
{
return new ConcreteModemDataExchange();
}
else if (another condition is met)
{
return new AnotherConcreteModemDataExchange();
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
我无法看到这样做是为了减少改变对班级的影响.它仍然需要重新编译,那么有什么好处呢?你从这样做中获得了什么,这对于生产高质量的代码非常重要?
Pat*_*irk 10
对我来说,上面的调制解调器示例总是看起来像接口隔离原则而不是SRP的情况,但除此之外.
在你关于这个问题的部分中Rectangle,我认为你只是误解了它.Martin使用Rectangle作为共享库的示例.如果GraphicalApplication需要一个新方法或更改Rectangle类中的语义,那么这会影响ComputationalGeometryApplication因为它们都"链接"到Rectangle库.他说它违反了SRP,因为它负责定义渲染边界和代数概念.想象一下,如果GraphicalApplication从DirectX更改为OpenGL,其中y坐标被反转.您可能希望更改一些内容Rectangle以促进此操作,但您可能会导致更改ComputationalGeometryApplication.
在我的工作中,我尝试遵循SOLID原则和TDD,并且我发现SRP使得为类编写测试变得简单并且还使课程集中.遵循SRP的类通常非常小,这降低了代码和依赖性的复杂性.在删除课程时,我会尝试确保课程要么"做一件事",要么"协调两件(或更多件事)".这使他们保持专注,并使他们改变的原因仅取决于他们做的一件事,对我而言,这是SRP的重点.