但是,只要您相信将遵循Liskov的替代原则,那为什么不容许它被取代呢?
例如,因为我希望算法的基本实现是固定的,并且仅允许特定部分由子类(重新)定义。这被广泛称为模板方法模式(我在下面强调):
因此,模板方法管理着更大的任务语义图,并管理了方法选择和方法序列的更完善的实现细节。这张大图调用了手头任务的抽象和非抽象方法。非抽象方法完全由模板方法控制,但是抽象方法(在子类中实现)提供了模式的表达能力和自由度。某些或所有抽象方法可以专用于子类,从而允许子类的编写者以对较大语义的最小修改来提供特定的行为。模板方法(非抽象方法)在此模式下保持不变,从而确保从属的非抽象方法和抽象方法按最初打算的顺序调用。
更新资料
我一直在从事的项目的一些具体示例:
- 通过各种“屏幕”与旧式大型机系统通信。每个屏幕都有一堆固定名称,位置和长度的字段,其中包含特定的数据位。请求用特定数据填充某些字段。响应返回一个或多个其他字段中的数据。每个事务遵循相同的基本逻辑,但是每个屏幕上的细节都不相同。我们在几个不同的项目中使用了模板方法,以实现屏幕处理逻辑的固定框架,同时允许子类定义屏幕特定的细节。
- 将数据库表中的配置数据导出到Excel文件/从Excel文件导出。同样,每个表的处理Excel文件和插入/更新DB记录或将记录转储到Excel的基本架构是相同的,但是每个表的详细信息是不同的。因此,模板方法是消除代码重复并使代码更易于理解和维护的非常明显的选择。
- 生成PDF文档。每个文档具有相同的结构,但是它们的内容每次都不同,这取决于许多因素。同样,使用模板方法可以轻松地将生成算法的固定框架与特定于案例的可变细节分开。事实上。它在这里甚至适用于多个级别,因为该文档由几个部分组成,每个部分都包含零个或多个字段。在这里,模板方法适用于3个不同的级别。
在前两种情况下,原始的旧版实现使用Strategy,从而导致大量重复的代码,当然,这些年来,这些代码之间到处都是细微的差异,包含许多重复的或稍有不同的错误,并且很难维护。重构为Template Method(以及其他一些增强功能,例如使用Java批注)可将代码大小减少约40-70%。
这些只是我想到的最新示例。到目前为止,几乎所有我从事的项目都可以引用更多案例。