Делает Массив.Добавить метод нарушает LSP?
Array
класс реализует интерфейс IList
, который имеет член Add
. Array.Add
вызывающие броски NotSupportedException
. Является ли это нарушением принципа подстановки Лискова или принципа сегрегации интерфейса или их обоих?
1 ответ:
Это определенно является нарушением принципа сегрегации интерфейса. ISP утверждает, что компоненты должны зависеть только от интерфейсов, которые им действительно требуются.
Array
реализуетIList
, но явно не нуждается или не хочет всех методов, определенныхIList
, потому что он выбирает исключение, чтобы объяснить, что он не поддерживаетAdd
. Кроме того, все, что нуждается вArray
, теперь имеетIList
, несмотря на то, что не нуждается во всех своих методах (потому что все, что хочет массив, явно не беспокоится оAdd
, так как это все равно не работает). Отсутствие поддержки операции, которую ваш интерфейс предлагает реализовать, явно является нарушением провайдера; принуждение потребляющего кода зависеть от интерфейса, несмотря на то, что он не нужен полностью, также является нарушением провайдера.Это может привести к нарушению принципа подстановки Лисков. Если код зависит от
IList
, LSP утверждает, что он должен правильно функционировать при передаче любой реализацииIList
. Однако, когда переданныйArray
, этот код теперь будет выдавать исключение всякий раз, когда он пытается вызватьAdd
.Является ли это нарушением LSP, зависит от того, как вы видите исключения в отношении LSP. Если вы подходите к этому с точки зрения того, что исключения являются частью ожидаемого контракта, то все в порядке. Метод соответствует своему контракту, и любой код, который вызывает
Add
без учета возможности исключения, виноват в том, что не делает этого.Если вы больше из мнение, что
NotSupportedException
считается ошибкой или неудачей, то это явное нарушение LSP. Лично я нахожу, что твердые принципы поддерживают друг друга и их труднее рассматривать в вакууме, поэтому, используя принцип разделения интерфейса в качестве резервного, я бы сказал, что интерфейс говорит "Я могу делать эти вещи", поэтому говорить "на самом деле, я не могу делать это" - ошибка, и поэтому, вероятно, не следует рассматривать как часть действительного контракта. Если исключение не является частью контракта, то путем выбрасывания во-первых,Array
нарушает контрактAdd
и, следовательно, нарушает LSP.