我一直试图打破开放封闭校长和李斯科夫代课校长之间的区别。最好和最常见的例子都使用同样的问题。查找形状类的区域。
他们使用的手段略有不同,但有效地解决了同样的问题与相同的解决方案。
因为这两者都是固体的一部分,我真的想找一个理由来支持为什么两者都被呼出。
我在找一个两者都不适用的解释。
发布于 2017-09-14 10:27:41
LSP:
使用者以抽象(例如接口)为目标,不需要知道接口背后的具体实现。例如,客户端(例如,DocumentProcessor类)持有对IDocumentStore的依赖关系。如果在V1中给它一个SqlSeverDocumentStore实例,然后在V2中给它一个FileSystemDocumentStore,那么客户机(DocumentProcessor)应该可以不受修改地工作。这可以通过确保合同 of IDocumentStore的定义以及DocumentProcessor、SqlSeverDocumentStore和FileSystemDocumentStore遵守本合同来实现。
这份合同的意义不仅仅是一个接口。有两个类实现相同的接口并不意味着它们遵守相同的约定(尽管它们应该遵守)。
例如,这两种实现是否都支持保存小于或等于20 to的文档?或者其中一个支持最多为10 of的文档?如果一个实现应该支持20 an文档是契约的一部分,那么所有的实现都应该支持这一点。
OCP:
我们应该避免在释放一个组合单元(例如类或函数)之后修改它。实现这一目标的一种方法是使单元参数化。例如,如果您有一个函数(例如,ProcessImages)从文件系统读取图像,对它们进行压缩,然后将它们发送到某个web服务,则可以参数化此函数以接受负责(1)读取图像、(2)压缩图像、(3)发送图像的其他函数。
例如(在C#中):
public static void ProcessImages(
Func<Image[]> getImages,
Func<Image, CompressedImage> compressImage,
Action<CompressedImage> sendImage)
{
//... Orchestrate the operation here
}而且,在成分根中
Action processImages = () => ProcessImages(ReadImages, CompressImage, SendImage);其中ReadImages、CompressImage、SendImage本身就是函数。
这样,如果要更改图像的压缩方式,就不会修改ProcessImages函数。相反,您将创建一个新的压缩函数(例如CompressImageInADifferentWay),然后在复合根中组合ProcessImages函数,如下所示:
Action processImages =
() => ProcessImages(ReadImages, CompressImageInADifferentWay, SendImage);如果您以一种完美的方式应用OCP,那么只有组合根本身会改变。
LSP允许我们实现OCP。例如,因为CompressImage和CompressImageInADifferentWay遵守了ProcessImages知道的一些契约,所以我们可以使用CompressImageInADifferentWay替换CompressImage,而无需修改ProcessImages。
https://stackoverflow.com/questions/46188783
复制相似问题