LSP和OCP有什么区别?

时间:2017-09-13 04:19:01

标签: solid-principles

我一直试图打破开放封闭校长和利斯科夫的替代校长之间的分歧。并且最好和最常见的例子都使用完全相同的问题。找到形状类的面积。

他们使用略有不同的方法,但使用相同的解决方案有效地解决了同样的问题。

由于这些都是SOLID的两部分,我真的试图找到一个理由支持为什么两者都被召唤出来。

我正在寻找一个对两者都不起作用的解释。

  • 感谢。

1 个答案:

答案 0 :(得分:1)

LSP:

消费者以抽象为目标(例如界面),不应该知道界面背后的具体实现。例如,客户端(例如DocumentProcessor类)对IDocumentStore具有依赖性。如果在V1中,您为其提供了SqlSeverDocumentStore实例,然后在V2中为其提供了FileSystemDocumentStore,则客户端(DocumentProcessor)应该无需修改即可运行。这可以通过确保IDocumentStore合同得到明确定义并且DocumentProcessorSqlSeverDocumentStoreFileSystemDocumentStore遵守此合同来实现。< / p>

合同不仅仅意味着接口。让两个类实现相同的接口并不意味着它们遵守相同的合同(尽管它们应该)。

例如,两种实现是否都支持保存小于或等于20MB的文档?或者其中一个支持最多10MB的文档?如果它是实现应该支持20MB文档的合同的一部分,那么所有实现都应该支持这一点。

OCP:

我们应该在发布之后避免修改组合单元(例如类或函数)。实现此目的的一种方法是使单元参数化。例如,如果您有一个函数(比如ProcessImages)从文件系统读取图像,压缩它们然后将它们发送到某个Web服务,您可以参数化此函数以接受其他负责的函数( 1)读取图像,(2)压缩图像,(3)发送图像。

E.g。 (在C#中):

public static void ProcessImages(
    Func<Image[]> getImages,
    Func<Image, CompressedImage> compressImage,
    Action<CompressedImage> sendImage)
{
    //... Orchestrate the operation here
}

而且,在Composition Root

Action processImages = () => ProcessImages(ReadImages, CompressImage, SendImage);

ReadImagesCompressImageSendImage本身就是其中的功能。

这样,如果要更改图像的压缩方式,则不会修改ProcessImages功能。相反,您将创建一个新的压缩函数(比如说CompressImageInADifferentWay),然后在这个组合根中组成ProcessImages函数,如下所示:

Action processImages =
    () => ProcessImages(ReadImages, CompressImageInADifferentWay, SendImage);

如果以完美的方式应用OCP,只有组合根本身会发生变化。

LSP允许我们实现OCP。例如,由于CompressImageCompressImageInADifferentWay遵守ProcessImages知道的某个合同,我们可以将CompressImage替换为CompressImageInADifferentWay,而无需修改ProcessImages

相关问题