这是否违反了 LSP - 后置条件规则

问题描述 投票:0回答:1

想知道我是否违反了里氏替换原则 - 后置条件规则,

public class ProcessController
{
    public virtual Dictionary<int, string> GetRunningProcess()
    {
        Dictionary<int, string> processes = new()
        {
            { 1, "system" },
            { 44, "system" },
            { 45, "user" },
            { 102, "user" },
            { 176, "user" },
            { 274, "application" },
            { 188, "application" }
        };
        return processes.Where(x => !x.Value.Equals("application")).ToDictionary();
    }
}

public class UserProcessController : ProcessController
{
    public override Dictionary<int, string> GetRunningProcess()
    {
        Dictionary<int, string> processes = new()
        {
            { 1, "system" },
            { 44, "system" },
            { 45, "user" },
            { 102, "user" },
            { 176, "user" },
            { 274, "application" },
            { 188, "application" }
        };
        Dictionary<int, string> userProcess = processes.Where(x => x.Value.Equals("user")).ToDictionary();
        return userProcess;
    }
}

public class ApplicationProcessController : ProcessController
{
    public override Dictionary<int, string> GetRunningProcess()
    {
        Dictionary<int, string> processes = new()
        {
            { 1, "system" },
            { 44, "system" },
            { 45, "user" },
            { 102, "user" },
            { 176, "user" },
            { 274, "application" },
            { 188, "application" }
        };
        Dictionary<int, string> userProcess = processes.Where(x => x.Value.Equals("application")).ToDictionary();
        return userProcess;
    }
}

LSP:后置条件不能削弱,只能加强。

父进程不返回

application
类型的进程。

第一个子项

UserProcessController
返回进程类型
user
,但不返回
application
system
。 - 弱化是后置条件吗?

第二个子节点

ApplicationProcessController
返回进程类型
application
,但不返回
user
system
。 - 弱化是后置条件吗?

在这种情况下,我可以采取哪些解决办法来遵守 LSP。

c# solid-principles liskov-substitution-principle
1个回答
0
投票

为了确保我们意见一致,我将首先解释什么是“后置条件”。

调用

ProcessController.GetRunningProcess
后,调用者可以对其程序推断出哪些内容?这些是它的后置条件。这与
GetRunningProcess
的实施无关。当然,实现需要“满足”后置条件,但除此之外,它并不规定后置条件是什么。 应该决定此方法的调用者如何推断其返回值。 一些后置条件已经编码在方法声明中,类型检查器有助于强制执行它们。例如,声明

GetRunningProcess

返回

Dictionary<int, string>
- 这是后置条件。呼叫者在拨打
Dictionary<int, string>
后保证会得到
GetRunningProcess
。子类不能重写它并将返回类型更改为
object
,因为这样调用者就不能保证再获得
Dictionary<int, string>
(因此削弱了后置条件)。例如,该方法现在可以返回
string
除了方法声明之外,您没有提到

GetRunningProcess

还有哪些其他后置条件。就方法声明中编码的后置条件而言,两个子类都不会更改后置条件。所有 3 个方法均声明返回

Dictionary<int, string>

ProcessController.GetRunningProcess

的合理后置条件是


返回表示正在运行的进程的字典。字典的键代表进程 ID,值代表进程的类型。

UserProcessController.GetRunningProcess

的合理后置条件可能是:


返回表示正在运行的进程的字典。字典的键代表进程ID,值代表进程的类型。
进程的类型始终是“用户”

那么这将加强
ProcessController.GetRunningProcess

的后置条件。我应该重复一遍,这与这些方法的实现方式无关。

应该决定后置条件是什么,只要满足后置条件,实现就是正确的,但否则实现可以做任何它想做的事。

如果
ProcessController.GetRunningProcess

的后置条件是:


返回字典[...]。
进程的类型从来都不是“应用程序”

ApplicationProcessController.GetRunningProcess

的后置条件是:


返回字典[...]。
进程的类型始终是“应用程序”

那么这将违反 LSP,因为
ApplicationProcessController

完全改变了后置条件。

    

© www.soinside.com 2019 - 2024. All rights reserved.