Скажи, что у меня есть:
interface Thing
{
GetThing();
}
class FastThing : Thing
{
public int GetThing()
{
return 1;
}
}
class SlowThing : Thing
{
public int GetThing()
{
return GetThingFromDatabase();
}
}
Это нарушение принципа подстановки Лискова?
performance
liskov-substitution
ConditionRacer
источник
источник
GetThingFromDatabase()
не достаточно медленно, чтобы сделать это спорным.Factor4096BitPublicKey();return 1;
сделало бы вещи немного интереснее.FastThing
наSlowThing
, LSP не применяется. Если вы добавите комментарий, вThing::GetThing
котором написано «Очень быстро», вопрос можно обсудить.Ответы:
Это действительно зависит. Некоторые интерфейсы имеют, например, ограничения сложности (они, очевидно, не могут быть реализованы программно). Наиболее простой случай - «GetThing () дает
int
- то есть останавливает», и в этом случае ответом будет «Нет» - обе версии GetThing () останавливают и возвращают int.Но многие интерфейсы подразумевают или прямо заявляют о гарантиях производительности, как по сложности, так и по времени. Например, в Стандарте C ++ незаконно реализовывать библиотеку с блокирующим вызовом, кроме случаев, когда Стандарт прямо разрешает.
источник
TL; DR: нет
Согласно «Поведенческому подтипу с использованием инвариантов и ограничений» (формализация принципа), он в первую очередь касается «безопасных» свойств типа объектов. Свойства, которые определяют заменяемость только в контексте информации о типе. Тип объекта ортогональн к его производительности. Поэтому разница в производительности не является нарушением принципа подстановки Лискова.
источник
Какие гарантии дает интерфейс? Так как не
GetThing
дает никаких гарантий, тогда подтипы не должны уважать это.Если бы интерфейс был чем-то похожим
GetThingInLinearTime
или базовый тип был виртуальным, а реализация по умолчанию представляла собой одну сложность, то ухудшение этой алгоритмической сложности нарушило бы LSP.источник
Производительность программного обеспечения не имеет ничего общего с принципом подстановки Лискова.
Принцип связан с заменой подтипов и поведенческим воздействием замены этого объекта только в терминах ООП.
Вход и выход
getThing()
остаются одинаковыми для обоих случаев, и как медленные, так и быстрые, вероятно, переводят объекты в одно и то же состояние.источник
Имеет ли значение, что конкретно говорит сам принцип подстановки Лискова? Если подтип нарушает ожидания потребителя супертипа, это кажется плохой вещью, независимо от того, является ли LSP более строгим.
Таким образом, на мой взгляд, все ли разумные ожидания потребителя абстракции выполняются подтипом, кажется хорошим обобщением LSP.
Тем не менее, в примере, который вы опубликовали, и с интерфейсами Java в целом, не ясно, что пользователь
Thing
интерфейса имеет какие-либо разумные ожидания относительно того, должен ли он быть быстрым или медленным. Если javadocs интерфейса должны были включать язык о том, какие операции обещают быть быстрыми, тогда мог бы быть аргумент для проблемы по соображениям производительности. Но соглашение Java для разных реализаций определенно должно иметь разные характеристики производительности.источник
Дядя Боб ответил на очень похожий вопрос, где он заявляет, что нарушение LSP требует 3 сторон:
Я бы рискнул предположить, что этот вопрос имеет структуру, аналогичную той, на которую он ответил, в которой не упоминается P , использующий T, и какое поведение P ожидает.
Вы можете найти его ответ здесь . (Вам нужно прокрутить вниз и найти ответ от пользователя по имени Роберт Мартин)
источник