想知道我是否违反了里氏替换原则 - 后置条件规则,
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。
为了确保我们意见一致,我将首先解释什么是“后置条件”。
调用
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
完全改变了后置条件。