Oop 违反了哪些坚实的原则?
导言Oop 违反了哪些坚实的原则?,oop,inheritance,solid-principles,design-principles,Oop,Inheritance,Solid Principles,Design Principles,导言 我在写关于继承问题的硕士论文,并得出一些结论 指示存在继承问题的指示器 如以下示例所示: 示例 如果给定的动物实例是狗,则该方法返回字符串“Woof”;如果是猫,则返回字符串“Miau”。空字符串,因为有些动物根本不发出任何声音 因此,正确的解决方案应该是在动物类中使用多态性和getNoise方法 我分析了遗传问题的不同指标,想说 他们中的一些人违反了法律 我认为上面的例子违反了: 单一责任原则(SRP) 打开/关闭原则(OCP) Liskov替代原理(LSP) 依赖倒置原则(DIP)
我在写关于继承问题的硕士论文,并得出一些结论 指示存在继承问题的指示器 如以下示例所示: 示例
如果给定的动物实例是
狗,则该方法返回字符串“Woof”
;如果是猫,则返回字符串“Miau”
。空字符串,因为有些动物根本不发出任何声音
因此,正确的解决方案应该是在动物类中使用多态性和getNoise
方法
我分析了遗传问题的不同指标,想说
他们中的一些人违反了法律
我认为上面的例子违反了:
单一责任原则(SRP)
打开/关闭原则(OCP)
Liskov替代原理(LSP)
依赖倒置原则(DIP)
但我不确定这是否对所有人都是真的
我想:
违反原则
SRP违规
因为条件语句完全违反了SRP,因为
case语句或一个以上的if语句被认为是一个以上的责任。
存在两种情况,因此有不止一个原因需要更改方法
OCP违规
因为如果一个新的动物被添加,一个新的案例必须被添加到方法中
因此,该方法不适合修改
LSP违规
每个分支根据动物子类型执行不同的操作。
我认为这违反了LSP?!
我知道矩形、正方形和getArea的例子,但是这些
我认为这个例子也适用于违规行为
倾斜破坏
条件语句具有依赖性,这意味着语句依赖于细节,而不是违反DIP的抽象
问题:
所以问题是,对于给定的例子,给定的原则是否真的被违反了,推理是否正确
<强> SRP,因为条件语句都违反SRP,因为类似于Switter case语句,或者不止一个if if语句被认为不止一个责任。
存在两种情况,因此有不止一个原因需要更改方法
我强烈反对。对SRP的解释要有一点保留。他创造了这个原则
我将引用一些重要的内容:
什么定义了改变的理由
这个原则是关于人的
在编写软件模块时,您希望确保在请求更改时,这些更改只能来自单个人员,或者更确切地说,来自表示单个狭义定义的业务功能的单个紧密耦合的人员组。您希望将您的模块从整个组织的复杂性中分离出来,并设计您的系统,使每个模块只负责(响应)该业务功能的需求
[…]当你思考这个原则时,请记住,改变的原因是人。是人们要求改变。你也不想混淆那些人,或者你自己,把许多不同的人出于不同的原因所关心的代码混在一起
OCP因为如果添加了新动物,则必须在方法中添加新病例,因此该方法不适合修改
对。该方法假定有一组特定的实现,如果不进行修改,将无法处理新的实现
LSP每个分支根据动物子类型执行不同的操作。我认为这违反了LSP
它违反了LSP,但原因不同。如果我传入一只长颈鹿,我会得到一个意想不到的结果,一个空字符串。这意味着该方法对于动物的任何子类型都是不正确的
DIP条件语句具有依赖性,这意味着这些语句依赖于细节,而不是违反DIP的抽象
从技术上讲是正确的,但这只是违反上述其他两个原则的副作用。这并不是问题的核心
记住,原则不是规则,所以在解释它们时不要太严格/字面化。实用主义和理解为什么需要原则是关键。我不同意您的示例代码违反LSP这一事实。LSP的定义如下:
设Φ(x)是关于类型T的对象x可证明的属性。那么Φ(y)对于类型S的对象y应为真,其中S是T的子类型
考虑到来自动物的两个派生,即狗
和猫
,以及您的方法getAnimalNoise
,您没有对具体对象的某些可证明属性做出决定。您的方法是决定应该返回什么样的噪声,而不是对象本身
让我们想象一下,你可以设置一只动物的腿数
Animal a = new Animal()
a.setLegFront(2);
a.setLegRear(2);
如果你的狗
像这样覆盖了它:
class Dog extends Animal
{
public void setFrontLegs(int legs)
{
this.frontLegs = legs;
this.rearLegs = legs + 2;
}
public void setRearLegs(int legs)
{
// do nothing here for demonstration purposes
}
}
如果您现在有一家工厂返回动物
Animal createAnimal()
{
return new Dog();
}
Animal a = createAnimal();
a.setFrontLegs(2);
a.setRearLegs(2);
调用方法setFront/setRearLegs,期望结果是2和2,但实际上结果完全不同,即2和4。因此,这个例子与常见的LSP例子紧密相连,有正方形和矩形。但对我来说,这是一个比你的例子更准确的违反可证明属性的例子
其他原则的最新情况
我同意你的观点,其他原则也被违反,但对于SRP,我同意@dcastro。我要添加DIP:该方法应该依赖于MakesNoiseInterface
,而不是具体的类。@deceze不需要接口,抽象已经存在:Animal createAnimal()
{
return new Dog();
}
Animal a = createAnimal();
a.setFrontLegs(2);
a.setRearLegs(2);