Делает Массив.Добавить метод нарушает LSP?


Array класс реализует интерфейс IList, который имеет член Add. Array.Add вызывающие броски NotSupportedException. Является ли это нарушением принципа подстановки Лискова или принципа сегрегации интерфейса или их обоих?

1 4

1 ответ:

Это определенно является нарушением принципа сегрегации интерфейса. ISP утверждает, что компоненты должны зависеть только от интерфейсов, которые им действительно требуются. Array реализует IList, но явно не нуждается или не хочет всех методов, определенных IList, потому что он выбирает исключение, чтобы объяснить, что он не поддерживает Add. Кроме того, все, что нуждается в Array, теперь имеет IList, несмотря на то, что не нуждается во всех своих методах (потому что все, что хочет массив, явно не беспокоится о Add, так как это все равно не работает). Отсутствие поддержки операции, которую ваш интерфейс предлагает реализовать, явно является нарушением провайдера; принуждение потребляющего кода зависеть от интерфейса, несмотря на то, что он не нужен полностью, также является нарушением провайдера.

Это может привести к нарушению принципа подстановки Лисков. Если код зависит от IList, LSP утверждает, что он должен правильно функционировать при передаче любой реализации IList. Однако, когда переданный Array, этот код теперь будет выдавать исключение всякий раз, когда он пытается вызвать Add.

Является ли это нарушением LSP, зависит от того, как вы видите исключения в отношении LSP. Если вы подходите к этому с точки зрения того, что исключения являются частью ожидаемого контракта, то все в порядке. Метод соответствует своему контракту, и любой код, который вызывает Add без учета возможности исключения, виноват в том, что не делает этого.

Если вы больше из мнение, что NotSupportedException считается ошибкой или неудачей, то это явное нарушение LSP. Лично я нахожу, что твердые принципы поддерживают друг друга и их труднее рассматривать в вакууме, поэтому, используя принцип разделения интерфейса в качестве резервного, я бы сказал, что интерфейс говорит "Я могу делать эти вещи", поэтому говорить "на самом деле, я не могу делать это" - ошибка, и поэтому, вероятно, не следует рассматривать как часть действительного контракта. Если исключение не является частью контракта, то путем выбрасывания во-первых, Array нарушает контракт Add и, следовательно, нарушает LSP.