简体   繁体   English

Liskov替代原理和虚拟方法

[英]Liskov substitution Principle and Virtual Method

I have scenario where a virtual function is overridden in derived class with additional pre-conditions. 我有一个方案,其中虚函数在派生类中带有其他前提条件被覆盖。 Here is the snapshot - 这是快照-

class Process
{
    protected virtual void ValidateDates()
    {
        if (Entity.StartDate.Date > Entity.EndDate.Date)
        {
            AddFailure("Start date cannot be later than the End date");
        }
    }
}

class InitialProcess : Process
{
    protected override void ValidateDates()
    {
        base.ValidateDates();
        if (IsImmediateProcess)
        {
            if (Entity.StartDate.Date > CurrentDateTime.Date)
            {
                AddFailure("Start date cannot be later than the current date");
            }
        }
    }
}

If I understand correctly, the code here breaks Liskov substitution by imposing an additional pre-condition - IsImmediateProcess and other of date check. 如果我理解正确,那么这里的代码通过施加一个附加的先决条件-IsImmediateProcess和其他日期检查来破坏Liskov替换。 Is it correct? 这是正确的吗? Or is it alright for a overridden function to call a base function and then add its own behavior to it? 还是让覆盖的函数调用基本函数然后向其添加自己的行为好吗?

I cannot move the condition introduced by InitialProcess type in the overridden method to the base type as it is specific for InitialProcess. 我无法将重写方法中InitialProcess类型引入的条件移动到基​​本类型,因为它是InitialProcess特有的。

What could have been the best way to achieve the overridden behavior in such scenarios, where derived class overrides the behavior and wants to substitute its own behavior, without breaking Liskov principle, if it does so like in this case? 在这种情况下,实现派生类的最佳方法是什么,如果派生类在不违反Liskov原理的情况下覆盖了行为并希望替换其自身的行为(如果在这种情况下这样做的话)?

Assuming you meant class InitialProcess : Process 假设您要class InitialProcess : Process

This is exactly following the Liskov principle. 这恰好遵循里斯科夫原则。

Both classes have the same interface but different (extended) behaviour. 这两个类具有相同的接口,但行为不同(扩展)。 The derived class does not have a different pre-condition, it has a different validation-rule. 派生类没有不同的前提条件,它具有不同的验证规则。 Which is quite OK and does not break anything. 这是完全可以的,并且不会破坏任何内容。

As Henk Holterman says, it not violate LSP. 正如Henk Holterman所说,它不违反LSP。 Is strengthened the postconditions, and do not weakened the preconditions, which ok. 是加强后置条件,而不是削弱先决条件,这样就可以了。

So, it do what base class do by calling: 因此,它通过调用来执行基类的工作:

base.ValidateDates();

and add some post conditions (strengthened the postconditions): 并添加一些后置条件(加强了后置条件):

if (IsImmediateProcess)

IMHO 恕我直言

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM