Cik*_*nas 1 oop liskov-substitution-principle solid-principles
我正在尝试以正确的方式学习OOP和OOD原则.我想对Liskov替换原则及其PRE和POST条件做一些澄清.我在这里阅读了一些主题,一些文章来自http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod等地方.
我已经编写了一个简单的基类和几个示例子类,我的假设是关于它们的前后条件,我想知道它们是否正确.注释行是我的想法:是否违反了PRE和POST条件.
public abstract class BaseClass
{
public virtual int GetResult(int x, int y)
{
if (x > 10 && y < 20)
{
return y - x;
}
throw new Exception();
}
}
public class LSPExample1 : BaseClass
{
public override int GetResult(int x, int y)
{
// PRE: weakened pre condition is ok
if (x > 10 && y <= 15)
{
// POST: Is it ok? because the available result range is narrowed by y <= 15
return y - x;
}
throw new Exception();
}
}
public class LSPExample2 : BaseClass
{
public override int GetResult(int x, int y)
{
// PRE: Same as base - OK
if (x > 10 && y < 20)
{
// POST: I assume it's bad because of parameters place changed in substraction ?
return x-y;
}
throw new Exception();
}
}
public class LSPExample3 : BaseClass
{
public override int GetResult(int x, int y)
{
// PRE Condition is bad (Strenghtened) because of (X >5) and (Y>20) ?
if (x > 5 && y > 20)
{
// POST condition is ok because base class do substraction which is weaker than multiplication ?
return x * y;
}
throw new Exception();
}
}
Run Code Online (Sandbox Code Playgroud)
我真的很感激你的时间
这是您可以实际访问源的精彩情况之一.Barbara Liskov的原始论文可用且易于阅读且易于阅读.http://csnell.net/computerscience/Liskov_subtypes.pdf
GetResult您显示的所有四种方法都接受两个整数作为输入,并返回一个整数或抛出异常.在这方面,它们都具有相同的行为,因此可以说LSP完全满足.如果没有明确的前/后条件或不变量,那么关于代码就没有别的了解.
你的例子中缺少的是合同.什么是GetResult 需要从它的调用它有什么保证它会产生?
例如,如果合同保证返回值等于y-x,那么示例2和3就会使合同失败,从而破坏LSP.但是,如果唯一的保证是返回值是Int或Exception,那么它们都会通过.
如果合同保证如果x <= 10 ||将抛出异常 y> = 20然后示例1和3中断LSP.如果唯一的保证是该方法将返回一个Int或抛出一个异常,那么它们都满足它.
代码无法告诉您保证是什么,它只能告诉您希望代码执行的操作.
由于我获得了大量的投票,我将添加一个示例(伪代码):
class Line {
int start
int end
int length() { return end - start } // ensure: length = end - start
void updateLength(int value) {
end = start + value
// ensure: this.length == value
}
}
Run Code Online (Sandbox Code Playgroud)
两个函数中的每一个中的"ensure"子句都是在调用函数后保证Line对象的状态.只要我满足子类中的保证,我的子类就会符合LSP.例如:
class Example1: Line {
void updateLength(int value) {
start = end - value
}
}
Run Code Online (Sandbox Code Playgroud)
以上满足LSP.
如果Line的updateLength函数也有一个"this.start unchanged"的ensure子句,那么我的子类将不满足LSP.
| 归档时间: |
|
| 查看次数: |
217 次 |
| 最近记录: |