Вопрос по c#, solid-principles, stream, liskov-substitution-principle, oop – Принцип подстановки Лискова и Потоки

9

Есть ли тот факт, что естьПоток производные классы, которые нельзя написать или найти, нарушают принцип подстановки Лискова?

Например,NetworkStream нельзя искать, он броситNotSupportedException если методSeek называется.

Или потому что существованиеCanSeek флаг это нормально?

Рассматривая хорошо известный примерSquare наследование отRectangle... будет ли добавление флаговDoesHeightAffectsWidth а такжеDoesWidthAffectsHeight вRectangle исправить проблему?

Безразлично»Разве это не открывает дверь для исправления вещей, добавляя флаги?

Правильно. На самом деле у меня есть этот вопрос, потому что я читалArray vs List " разглагольствовать :) vtortola
@ PatrykĆWiek:IsReadOnly собственностьюICollection, которыйIList наследуется, имеет плохое имя, так как указывает, может ли объект иметь добавленные или удаленные элементы, а не является ли этот элемент "только для чтения» в любом более широком смысле. Хороший "список" интерфейс должен ИМХО включать как минимум, (1) размер неизменен? (2) Существующие элементы неизменяемы? (3) Может ли эта ссылка использоваться для добавления / удаления элементов? (4) Может ли эта ссылка писать вещи по индексу? (5) Можно ли безопасно ссылаться на эту ссылку на код, которыйне должен изменить коллекцию? (6) Может ли он принимать все вещи типа U? supercat
Я думаю, что тот же вопрос можно задать оIList интерфейс - в большинстве случаев этоs рассматривается как обычная изменяемая индексированная коллекция, но имеетIsReadOnly флаг иAdd можно бросить (самый простой пример:IList intList = new int[3];) ... интересный вопрос тем не менее. Patryk Ćwiek

Ваш Ответ

2   ответа
7

CanSeek технически удерживает потоковые классы от нарушения LSP. Только если он вернет истину, поиск обещает работать.

Я лично считаю, что это серьезный изгиб ISP и, возможно, SRP, и мой внутренний дизайнер предпочел бы что-то вродеSeekableStream подкласс / интерфейс, от которого могут наследоваться искомые потоки. Но я'Я уверен, что это приносит свои проблемы (например, в потоках, которые только ищем) ... и, честно говоря, реальный принцип юзабилити превосходит.

Это то, что нужно иметь в виду. Время от времени принцип и реальность сталкиваются. Принципы SOLID помогают минимизировать ненужную сложность в большинстве случаев и, как правило, поддерживают ремонтопригодность ОО-систем и предотвращают их разрушение под собственным весом. Если чистота приводит к системе, этоБольше сложный, хотя - например, потому что теперь поток, который иногда можно искать, неэто не вписывается в иерархию - тогда, возможно, случайное уродство оправдано.

Но это никогда не должно быть первым выбором только потому, что буква закона позволяет это. Твердые принципы непросто правила; Oни'репринципы, Oни'Re идеи позади слов -дух закона. Если вы придерживаетесь этого письма, проходя мимо духа, вы 'пропустить весь смысл принципа.

Что касается проблемы Square / Rectangle ... технически, наличие свойств / функций, определяющих, будет ли изменение высоты также изменять ширину, может рассматриваться в соответствии списьмо ЛСП. Опять же, это похоже на адвокатскую деятельность и раздвигает границы других принципов SOLID. Это'Это также определенно не оптимальное решение из реальностис точки зрения, поскольку это увеличивает сложность и вводит возможность случайных побочных эффектов; теперь все что хочет сказатьrect.Height = 50; может непреднамеренно изменить ширину.

@supercat: Или вы можете использовать язык, который поддерживает множественное наследование. : P ИлиSeekable интерфейс. Или, если вам нужно искать, простопопробуй сделать это и пусть это терпит неудачу на типах, которые нене могу это поддержать. cHao
Иными словами, даже с помощью утки яя не уверен, как написать класс, который, учитывая коллекцию, будет включатьcount метод, когда коллекция включает в себя один и не включает этот член, когда базовая коллекция не 'т. supercat
@cHao: проблема нет просто наследство. Если кто-то хочет создать оболочку коллекции, конструктор которой принимает получателя события и интерфейс коллекции и предоставляет те же возможности, что и базовая коллекция, но также отправляет событие каждый раз, когда он изменяется, тогда один тип сможет обрабатывать все коллекции без учета поддерживают ли они,addsetItem, или оба. Если неЧтобы использовать общий интерфейс, необходимо иметь одну оболочку для вещей, которые поддерживаютadd но нетsetItem, один для вещей, которые поддерживаютsetItem но нетaddи один для ... supercat
я не уверен, как утка печатает эту проблему, если неткакой-то механизм я нене знать, с помощью чего объекты-обертки могут преобразовывать произвольные попытки доступа к элементу в обернутые объекты, не зная и не заботясь о том, что такое попытки доступа. supercat
5

Can... методы означают, чтоStream Безразлично»т сломаю LSP.Stream обеспечиваетвозможность читать, писать и искать, но нетгарантия что любой реализующий класс будет соблюдать его.Can... методы делают это явной особенностьюStream производные по контракту классы должны реализовывать их, чтобы позволить клиентскому коду проверять, реализует ли производный класс определенное поведение перед выполнением вызова. Таким образом, любой код, который пытается записать вStream должен проверитьCanWrite перед звонкомWriteНапример, и это может быть сделано с любой правильно реализованной производнойStream, Эрго онивзаимозаменяемы, как требует LSP.

Я думаю это'Безусловно, верно, что добавление методов для определения того, реализуют ли производные классы определенную функцию, может быть использовано неправильно - если команда была недисциплинированной, у них может получиться очень широкий, раздутый интерфейс, который нарушает работу ISP. я думаю чтоStream а такжеIList хорошо разработаны в этом отношении - они не• нарушают LSP, и они определяют достаточно узкий контракт тесно связанных действий, чтобы оставаться в рамках ISP. Понятно, что их дизайн был рассмотрен.

Я думаю, что в случаеSquare наследование отRectangleВы могли бы, конечно, добавитьDoesHeightAffectsWidth а такжеDoesWidthAffectsHeight чтобы решить проблему, но команда должна решить,Это приемлемо, или же добавление этих методов нарушает ISP. Является ли добавлениеAreAllInternalAnglesEqual поддерживать трапеции слишком далеко? В определенной степени этодо инженеров, пишущих код.

Я обновил свой вопрос с беспокойством :) vtortola

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