Zend_Form 是为继承而设计的。在使用 Zend_Form 时,每个人都应该牢记这一点——实际上它不是必需的 Zend_Form,但可能是它的子类。因此,如果任何程序依赖 Zend_Form 来完全按照它的方式运行,而不是按照它的子类可以运行的方式 - 该程序是错误的。正如 Liskov 原则所说,它不是“使用基类”,而是在滥用它。
Zend_Form 主要由 Zend 框架使用,我确信它正确使用它。
我认为对于此类为继承而设计并用作基于某些框架的应用程序构建块的类,“行为”的定义应该更加抽象——将一些细节留给子类,即使类本身不是抽象的。我会说 Zend_Form 的行为是“呈现一些html 并使用一些验证规则”。在这个意义上, Zend_Form 的所有子类都以相同的方式表现。Zend_Form 非抽象只是定义了默认行为,使其更易于使用。
另外为了让它更学术一点,我可以从中做两节课。一个应该是抽象的——所有形式的基类。另一个空表单,它的行为与 Zend_Form 现在的行为完全相同,并且可以单独使用。所以它会像
// sorry, I don't like PHP so here goes java
public abstract class ZendForm{/*implementation here and NO abstract methods*/}
public final class DefaultZendForm extends ZendForm{/*nothing here*/}
这将消除对 Liskov 原则的任何混淆,但可能不会为程序增加任何实际价值。
子类应该与超类有所不同,否则创建子类没有意义。而且您总是可以滥用这种差异并编写一个适用于超类而对子类失败的程序。但这不合理。完全呈现默认(空)表单不是 Zend_Form 合同的一部分。只有属于类契约的行为才是 LSP 的主题。