编程SOLID原理


43

随着时间的推移,我可以理解SOLID的两个部分-“ S”和“ O”。

“ O” –我在继承和策略模式的帮助下学习了开放式封闭原则。

“ S” –我在学习ORM时学会了单一职责原则(持久性逻辑从领域对象中删除)。

以类似的方式,学习SOLID的其他部分(“ L”,“ I”和“ D”)的最佳区域/任务是什么?

参考文献

  1. msdn-违反C#中的SOLID原则的危险
  2. channel9-在.NET / C#中应用SOLID原理
  3. OOPS原则(SOLID原则)

25
请注意,所有这些想法都是好主意,并且它们在一起非常好。但是,如果教条式地应用它们,将导致失败而不是成功。

3
OR-映射器有利于分离关注点,而不是单一责任原则。看到这个帖子programmers.stackexchange.com/questions/155628/...为的区别的讨论。
布朗

现实世界中的示例blog.gauffin.org/2012/05/…–
LCJ

1
@JarrodRoberson是的,这就是为什么将它们小心地称为准则的原因。也不要忘记其余的原则:adamjamesnaylor.com/2012/11/12/…(共11个)
Adam Naylor

2
@AdamNaylor的链接现在是404ing,其链接已移至adamjamesnaylor.com/post/…–
mattumotu

Answers:


54

几个月前,我一直在你的鞋子里,直到找到一篇非常有帮助的文章。

每个原则都很好地解释了每个软件开发人员在其项目中可能遇到的现实情况。我在这里简短介绍一下,指向参考SOLID软件开发,一次一步

正如评论中指出的那样,还有另一个非常好的pdf阅读材料-Pablo的SOLID Software Development

另外,还有一些不错的书更详细地描述了SOLID原理-SOLID Software Development的好书

编辑和评论每个原则的简短摘要:

  • “ S” –单一责任原则受业务需求驱动以允许更改。“改变的单一原因”可帮助您通过考虑业务概念和上下文(而不是仅考虑技术概念)来理解应将哪些逻辑上分开的概念组合在一起。 In another words,我了解到每个班级应该负一个责任。责任是完成分配的任务

  • “ O” –我学习了开放式封闭原理,并开始“优先考虑组合而不是继承”,因此,我喜欢没有虚拟方法并且可能被密封但依赖于抽象扩展的类。

  • “ L” –我在存储库模式的帮助下学习了Liskov替换原理,用于管理数据访问。

  • “我” –通过了解不应强迫客户端实现其不使用的接口(例如在ASP.NET 2.0中的成员资格提供程序中),我了解了接口隔离原理。因此界面不应该承担“很多责任”
  • “ D” –我了解了依赖倒置原理,并开始编写易于更改的代码。易于更改意味着更低的总拥有成本和更高的可维护性。

由于在注释中提到了CodePlex的有用资源,因此示例中包含了对SOLID的引用

在此处输入图片说明


3
我发现非常有用的文章下面的集合:lostechies.com/wp-content/uploads/2011/03/...
Scroog1

我读了整篇文章,但没有以图案或SOLID出售。这个例子太简单了,但是当它变得复杂时,复杂性是人为的。没有更好的选择,我还没有遇到现实的SOLID OOP。
Job

3
由于在这里提到了Lostcheies文章,因此也有此solidexamples.codeplex.com(基于Lostcheies)
深色推子

2
我是Pablos电子书的撰稿人之一。我很高兴人们仍然发现它有用。:)
肖恩·钱伯斯

1
+1000000,如果我能为您提供关于Open-Closed原则的摘要-每个人都会
误解

11

(I)接口隔离和(D)功能反转可以通过单元测试和模拟来学习。如果类创建自己的依赖关系,则无法创建良好的单元测试。如果它们依赖于过于宽泛的接口(或根本没有接口),那么进行单元测试所需模拟的内容并不是很明显。


2
+1这是非常正确的。您甚至不必遵守(imo)有时过于严格的“单元测试只能测试一件事”的规则:如果几分钟之内不能为一个班级提供一个不错的测试套件,它就可以侵犯了我和D,也可能侵犯了其他alfabet
stijn 2012年

8

Liskov替代原则基本上不允许您过度使用实现继承:您绝不应该仅将继承用于代码重用(为此存在组合)!通过遵循LSP,您可以确定在父类和子类之间确实存在“是一个关系”。

它表示您的子类必须以类似于在子类中实现方法的方式来实现子类的所有方法。永远不要在实现NOP的情况下重写方法,也不要在超类型抛出异常时返回null。在“按合同设计”条款中所述,重写方法时,应遵循超类的方法合同。防止违反该原则的一种方法是永远不要重写已实现的方法。而是提取一个接口并在两个类中都实现该接口。

GRASP的接口隔离原则,单一职责原则和高度协作原则在某种程度上是相关的。他们提到一个事实,即一个实体只应对一件事情负责,因此只有一个改变的原因,因此改变非常容易。

它实际上说如果一个类实现一个接口,那么它必须实现并使用所有这些接口的方法。如果在该特定类中不需要某些方法,则该接口不好,必须将其拆分为两个接口,其中一个仅具有原始类所需的方法。从POV来看,它与以前的原理有关,因为它不允许您创建大接口,以便它们的实现可能会破坏LSP。

您可以在Factory模式中看到Dependency Inversion;这里,高级组件(客户端)和低级组件(要创建的个体实例)都取决于抽象(界面)。将其应用到分层体系结构中的一种方法:您不应在已实现的层中而是在所调用的模块中定义与层的接口。例如,数据源层的API不应写在数据源层,而应在需要调用的商务逻辑层中。通过这种方式,数据源层继承/依赖于商务逻辑中定义的行为(因此是倒置),而不是相反(通常情况下)。这提供了设计的灵活性,使业务逻辑无需更改任何代码即可使用另一个完全不同的数据源进行工作。


1
关于里斯科夫的很好的解释。:)
John Korsnes 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.