2017-02-15 14 views
2

Интересно, как я должен организовать свои два класса.Является ли Лисков Замена Принципом, нарушенным в моем примере?

  • Один из них представляет собой Knife: простой, прочный, простой, как кухонный нож.
  • Другой - PocketKnife, который имеет состояние открыт или закрыт.
class Knife{ 
    public function cut() {/* do the cutting */} 
} 
class PocketKnife extends Knife{ 
    private $opened = 0; // 0/1 
    // ... 
    public function cut() { 
    if ($this->opened) { 
     parent::cut(); 
    } 
    } 
} 

Ни один из классов в моем коде абстрактны.

Этот пример нарушает LSP?

На мой взгляд, это, потому что пост-условия для cut() операции должны быть:

  1. лезвие ножа становится немного «старше» после резки
  2. некоторый объект должен иметь некоторые повреждения на него (если это какая-то игра, например)

Но с PocketKnife в его закрыто состояние мы не будем иметь эти постусловий. Или я ошибаюсь?

ответ

0

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

Если у вас есть метод, например someFunc (Knife k), который вызывает k.cut(), и вы можете передать Knife или Pocketknife или WhateverKnife в этот метод someFunc и правильно работать программа, то вы не нарушаете LSP.

+1

Это не отвечает на его вопрос, он просто подтверждает идею/принцип, лежащий в основе LSP. Нарушает ли его код? Зачем? –

1

Независимо от того, нарушает ли он LSP или нет, зависит от того, какое определение «разрезать» IS (не должно быть). Если после условием работы является то, что следующее должно быть истинным:

  1. лезвие ножа становится немного «старше» после резки
  2. некоторый объект должен иметь некоторый ущерб на него (если это например, в некоторых играх)

Тогда PocketKnife не отвечает этим условиям, когда «закрыт». Следовательно, PocketKnife не может быть заменен Ножом повсюду и LSP нарушен.

Как это решить?

Ну, это зависит от контекста и необходимости в дополнительной информации. Но одним из примеров может служить пример:

class Knife{ 
     public function cut() {/* do the cutting */} 
    } 

    class PocketKnife extends Knife{ 

     private $opened = 0; // 0/1 
     // ... 

     public function cut() { 
     if (!$this->opened) { 

      // state is changed for cut to be performed. 
      $this->opened = 1; 

      parent::cut(); 

      // may need to close again, after operation. 
     } 
     } 
    } 

С этим LSP не будет разбит. Опять же, пример просто дает представление о способах решения такой проблемы.