我听说Liskov替换原则(LSP)是面向对象设计的基本原则.它是什么以及它的使用例子是什么?
oop liskov-substitution-principle definition design-principles solid-principles
你能用一个很好的C#例子解释Liskov替换原理(SOLID的'L'),以简化的方式涵盖原理的所有方面吗?如果真的有可能.
我最近在C#中将SOLID做到了非常极端的水平,并且在某些时候意识到我现在基本上没有做太多的事情.在我最近再次开始研究F#之后,我认为对于我现在正在做的很多事情,它可能是更合适的语言选择,所以我想尝试将一个真实的C#项目移植到F#作为概念的证明.我想我可以推出实际的代码(以一种非惯用的方式),但我无法想象一个架构会是什么样的,它允许我以与C#类似的灵活方式工作.
我的意思是我有很多小类和接口,我使用IoC容器编写,我也使用了像Decorator和Composite这样的模式.这导致(在我看来)非常灵活和可演化的整体架构,使我能够在应用程序的任何位置轻松替换或扩展功能.根据所需更改的大小,我可能只需要编写一个新的接口实现,在IoC注册中替换它并完成.即使更改更大,我也可以替换部分对象图,而应用程序的其余部分只是像以前一样.
现在使用F#,我没有类和接口(我知道我可以,但我认为这与我想要进行实际函数式编程的时间不同),我没有构造函数注入,而且我没有IoC容器.我知道我可以使用更高阶函数做类似Decorator模式的东西,但这似乎并没有给我带有构造函数注入的类的灵活性和可维护性.
考虑这些C#类型:
public class Dings
{
public string Lol { get; set; }
public string Rofl { get; set; }
}
public interface IGetStuff
{
IEnumerable<Dings> For(Guid id);
}
public class AsdFilteringGetStuff : IGetStuff
{
private readonly IGetStuff _innerGetStuff;
public AsdFilteringGetStuff(IGetStuff innerGetStuff)
{
this._innerGetStuff = innerGetStuff;
}
public IEnumerable<Dings> For(Guid id)
{
return this._innerGetStuff.For(id).Where(d => d.Lol == "asd");
}
}
public class GeneratingGetStuff : IGetStuff
{
public IEnumerable<Dings> For(Guid id)
{
IEnumerable<Dings> dingse;
// somehow knows how to …Run Code Online (Sandbox Code Playgroud) 单一责任原则与关注点分离有什么区别?
single-responsibility-principle separation-of-concerns solid-principles
我正处于一个非常重视单一责任原则的项目中.我们有很多小班,事情很简单.但是,我们有一个贫血的领域模型 - 我们的任何模型类都没有行为,它们只是属性包.这不是对我们设计的抱怨 - 它实际上看起来效果很好
在设计评审期间,只要将新行为添加到系统中,SRP就会被引出,因此新行为通常会在新类中结束.这使得事情很容易被单元测试,但我有时会感到困惑,因为它感觉就像将行为拉出相关的地方.
我正在努力提高我对如何正确应用SRP的理解.在我看来,SRP反对添加与一个对象共享相同上下文的业务建模行为,因为该对象不可避免地最终要么做多个相关的事情,要么做一件事但是要知道改变形状的多个业务规则其产出.
如果是这样,那么感觉最终结果是一个贫血领域模型,这在我们的项目中肯定是这样.然而,贫血领域模型是一种反模式.
这两个想法可以共存吗?
编辑:一些上下文相关的链接:
SRP - http://www.objectmentor.com/resources/articles/srp.pdf
贫血领域模型 - http://martinfowler.com/bliki/AnemicDomainModel.html
我不是那种喜欢找先知并遵循他们所说的福音的开发者.所以我没有提供这些链接,作为说明"这些是规则"的方式,只是作为两个概念的定义来源.
我对Liskov替换原则的理解是,对于派生类,基类的某些属性是真的或某些实现的基类行为.
我想这意味着当一个方法在基类中定义时,它永远不应该在派生类中被覆盖 - 因为那么替换基类而不是派生类会产生不同的结果.我想这也意味着,拥有(非纯)虚拟方法是件坏事吗?
我想我可能对这个原则有错误的理解.如果我不这样做,我不明白为什么这个原则是好的做法.谁可以给我解释一下这个?谢谢
liskov-substitution-principle design-principles solid-principles
我正在努力学习单一责任原则(SRP),但这是非常困难的,因为我很难弄清楚我应该从一个班级中删除的时间和内容,以及我应该放置/组织它的地方.
我正在谷歌搜索一些材料和代码示例,但我找到的大多数材料,而不是让它更容易理解,使它很难理解.
例如,如果我有一个用户列表,并且从该列表中我有一个叫做控制的类,可以执行很多事情,例如当用户进/出时发送问候和再见消息,验证用户应该能够进入的天气并踢他,接收用户命令和消息等.
从示例中你不需要太多了解我已经在一个类中做了太多但是我不清楚如何在之后拆分和重新组织它.
如果我理解SRP,我会有一个加入频道的课程,问候和再见,一个用户验证课程,一个阅读命令的课程,对吧?
但是我在哪里以及如何使用踢球?
我有验证课程,所以我相信我会在那里进行各种用户验证,包括天气或者不应该踢用户.
因此,kick函数将位于通道连接类中,并在验证失败时被调用?
例如:
public void UserJoin(User user)
{
if (verify.CanJoin(user))
{
messages.Greeting(user);
}
else
{
this.kick(user);
}
}
Run Code Online (Sandbox Code Playgroud)
如果你们可以借助易于理解的C#在线和免费资料,或者通过向我展示如何分割引用的示例以及可能的一些示例代码,建议等,我将不胜感激.
如何在SOLID "接口分离原则",从"单一职责原则"有什么不同?
ISP将非常大的接口拆分为更小和更具体的接口,这样客户端只需知道它们感兴趣的方法
但是,对我来说,这听起来只是将SRP应用于接口和类.毕竟,如果一个界面只负责一个概念性的东西,那么你将无法进一步分解它.
我错过了什么,或者是SR与SRP有多余?如果没有,那么ISP是什么意味着SRP没有?
oop design-patterns single-responsibility-principle solid-principles interface-segregation-principle
solid-principles ×10
oop ×6
liskov-substitution-principle ×3
single-responsibility-principle ×3
c# ×2
.net ×1
composition ×1
definition ×1
f# ×1
glossary ×1
interface-segregation-principle ×1
principles ×1
yagni ×1