Действительно ли получение является квадратным от прямоугольника нарушение Принципа Замены Liskov? [закрытый]

В настоящее время вложенные ресурсы и маршруты в желаемом шаблоне не генерируются автоматически с чертежами по умолчанию, найденными в Ember CLI. Чертежи по умолчанию генерируют скелетные файлы и файловую структуру, а некоторые используют свою ловушку afterInstall для обновления других файлов. Следуя этим чертежам по умолчанию, вы правильно генерируете следующие элементы:

    ember g resource events
    ember g route events/view

Затем вы можете изменить Router.map в router.js с помощью предполагаемой вложенности:

    Router.map(function() {
      this.resource('events', function() {
        this.route('view', { path: "/view/:id" });
      })
    });

Теперь вы должны быть можно нажать «events / view / 1» в вашем браузере и просмотреть маршруты, которые вы искали, на вкладке Routers Ember Inspector.

В качестве альтернативы, вы можете выполнить следующее и сгенерировать пользовательский проект:

    ember generate blueprint nested-resource-route

Каталог каталога будет создан в корне вашего проекта, с вашим новым планом внутри. Используя ресурс и чертежи маршрутов в качестве основы, вы можете запустить собственный генератор, чтобы выполнить то, что вы ищете.

58
задан Georg Fritzsche 21 May 2010 в 23:21
поделиться

6 ответов

Я считаю, что рассуждение выглядит примерно так:

Допустим, у вас есть метод, который принимает прямоугольник и регулирует его ширину:

public void SetWidth(Rectangle rect, int width)
{
    rect.Width = width;
}

Это должно быть совершенно разумным, учитывая, что это за прямоугольник То есть, предположить, что этот тест пройдет:

Rectangle rect = new Rectangle(50, 20); // width, height

SetWidth(rect, 100);

Assert.AreEqual(20, rect.Height);

... потому что изменение ширины прямоугольника не влияет на его высоту.

Однако, допустим, вы получили новый класс Square из Rectangle. По определению, квадрат всегда имеет одинаковую высоту и ширину. Давайте попробуем этот тест еще раз:

Rectangle rect = new Square(20); // both width and height

SetWidth(rect, 100);

Assert.AreEqual(20, rect.Height);

Этот тест не удастся, потому что установка ширины квадрата на 100 также изменит его высоту.

Таким образом, принцип подстановки Лискова нарушается путем получения Square из Rectangle.

"is- «правило имеет смысл в« реальном мире »(квадрат определенно является своего рода прямоугольником),

60
ответ дан 24 November 2019 в 18:45
поделиться

Я не согласен с тем, что получение квадрата из прямоугольника обязательно нарушает LSP.

В примере Мэтта, если у вас есть код, который полагается на независимость ширины и высоты, то он фактически нарушает LSP.

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

Так что на самом деле все сводится к тому, что означает прямоугольник абстракции в ваше решение .

5
ответ дан 24 November 2019 в 18:45
поделиться

Ответ зависит от изменчивости . Если классы прямоугольника и квадрата неизменяемы, тогда Square действительно является подтипом Rectangle , и вполне нормально выводить первое из второго. В противном случае, Rectangle и Square могли бы раскрыть IRectangle без мутаторов, но вывод одного из другого неверно, поскольку ни один из типов не является надлежащим подтипом другого. .

76
ответ дан 24 November 2019 в 18:45
поделиться

Предположим, у нас есть класс Rectangle с двумя (для простоты общедоступными) свойствами width и height. Мы можем изменить эти два свойства: r.width = 1, r.height = 2.
Теперь мы говорим, что квадрат - это прямоугольник. Но хотя утверждение гласит, что «квадрат будет вести себя как прямоугольник», мы не можем установить .width = 1 и .height = 2 для квадратного объекта (ваш класс, вероятно, регулирует ширину, если вы устанавливаете высоту, и наоборот). Итак, есть по крайней мере один случай, когда объект типа Square не ведет себя как Rectangle, и поэтому вы не можете заменить их (полностью).

2
ответ дан 24 November 2019 в 18:45
поделиться

Это довольно просто :) Более «базовый» класс (первый в цепочке производных) должен быть самым общим.

Например, форма -> Прямоугольник -> Квадрат.

Здесь квадрат - это частный случай прямоугольника (с ограниченными размерами), а прямоугольник - это особый случай формы.

Сказано по-другому - используйте тест «is a». Сквайр - это прямоугольник. Но прямоугольник - не всегда квадрат.

-3
ответ дан 24 November 2019 в 18:45
поделиться

Я считаю, что существуют методы OOD / OOP, позволяющие программному обеспечению представлять реальный мир. В реальном мире квадрат - это прямоугольник с равными сторонами.Квадрат является квадратом только потому, что у него равные стороны, а не потому, что он решил быть квадратом. Следовательно, программа OO должна с этим бороться. Конечно, если процедура, создающая экземпляр объекта, хочет, чтобы он был квадратным, она могла бы указать свойство длины и свойство ширины как равные одинаковой величине. Если программе, использующей объект, позже потребуется узнать, квадратный ли он, ей нужно только спросить об этом. Объект может иметь логическое свойство только для чтения под названием «Квадрат». Когда вызывающая процедура вызывает его, объект может вернуть (Длина = Ширина). Теперь это может быть так, даже если объект прямоугольника неизменен. Кроме того, если прямоугольник действительно неизменяем, значение свойства Square можно установить в конструкторе и сделать с ним. Почему тогда это проблема? LSP требует, чтобы подобъекты были неизменными для применения, и квадрат, являющийся подобъектом прямоугольника, часто используется в качестве примера его нарушения. Но это не кажется хорошим дизайном, потому что, когда процедура using вызывает объект как «objSquare», необходимо знать его внутренние детали. Не было бы лучше, если бы ему было все равно, квадратный прямоугольник или нет? И это потому, что методы прямоугольника будут правильными в любом случае. Есть ли лучший пример нарушения LSP?

Еще один вопрос: как объект сделать неизменным? Есть ли «неизменяемое» свойство, которое можно установить при создании экземпляра?

Я нашел ответ, и это то, что я ожидал. Так как я разработчик VB .NET, это то, что меня интересует. Но концепции одинаковы для разных языков. В VB.NET вы создаете неизменяемые классы, делая свойства доступными только для чтения, и используете конструктор New, чтобы позволить подпрограмме создания экземпляров указывать значения свойств при создании объекта. Вы также можете использовать константы для некоторых свойств, и они всегда будут одинаковыми. С момента создания объект неизменен.

1
ответ дан 24 November 2019 в 18:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: