Zend_Form и принцип подстановки Лискова - PullRequest
2 голосов
/ 22 мая 2009

Очень распространенный шаблон, который я вижу (я выбираю в Zend Framework, только потому, что я имел дело с ним в момент этого вопроса), примерно так:

class My_Form extends Zend_Form {
     public function init() {
          $this->addElement();
     }
}

Zend_Form не является абстрактным классом, но вполне пригоден для использования сам по себе. Кажется, это «рекомендуется» как место для «инкапсуляции» ваших форм в хороший класс.

Это нарушает принцип подстановки Лискова? Каждый подкласс Zend_Form будет иметь совершенно другое поведение, чем базовый класс. Было бы лучше использовать композицию для этого, или я совершенно не понимаю этот принцип?

Ответы [ 2 ]

0 голосов
/ 10 июня 2009

Zend_Form предназначен для наследования. При использовании Zend_Form все должны помнить об этом - в действительности это не будет необходим Zend_Form, но может быть его подклассом. Таким образом, если какая-либо программа полагается на то, что Zend_Form ведет себя точно так же, как и ее подкласс, - эта программа ошибочна. Он не «использует базовый класс», как утверждает принцип Лискова, он злоупотребляет им.

Zend_Form используется в основном Zend Framework, и я уверен, что он использует его правильно.

Я думаю, что для таких классов, предназначенных для наследования и используемых в качестве блоков сборки приложения, основанных на некоторой структуре, определение «поведения» должно быть более абстрактным - оставляя некоторые детали подклассу, даже если сам класс не является абстрактным. Я бы сказал, что поведение для 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*/}

Это позволило бы устранить путаницу с принципом Лискова, но, вероятно, не добавило бы реальной ценности программе.

Подкласс должен отличаться от суперкласса, иначе не имеет смысла создавать подкласс. И вы всегда можете злоупотребить этой разницей и написать программу, которая работает для суперкласса и не работает для подкласса. Но это не было бы разумно. Рендеринг формы по умолчанию (пустой) не является частью контракта Zend_Form. Только поведение, которое является частью классового контракта, является предметом для LSP.

0 голосов
/ 22 мая 2009

Принцип подстановки Лискова гласит, что если программный модуль использует базовый класс, то ссылка на базовый класс может быть заменена производным классом, не влияя на функциональность программного модуля.

Так чем же отличается MyForm от ZendForm? Изменит ли это функциональность программы?

Кроме того, проверьте эти 2 пули (из статьи Википедии ):

  • Предварительные условия не могут быть усилены в подклассе.
  • Постусловия не могут быть ослаблены в подклассе.

Возможно, вы обнаружите, что MyForm не так сильно отличается от ZendForm, и вы можете безопасно использовать наследование.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...