Интерфейс не должен иметь свойств? - PullRequest
15 голосов
/ 10 июня 2009

Мой коллега по офису сказал мне сегодня, что плохая практика - использовать свойства в интерфейсах. Он рассказал об этом в какой-то статье (статьях) MSDN, которую я не смог найти (ну, я несколько раз пробовал в Google, возможно, с неверными ключевыми словами). Он также сказал мне, что в интерфейсе должны быть только методы. Теперь я знаю, что это не является строгим правилом, поскольку очевидно, что в .net вы можете сделать подпись свойства в интерфейсе и скомпилировать его.

Но правда ли, что это плохая практика / дизайн / упс? И почему?

Также было бы полезно указать правильную литературу или веб-ресурс.

Спасибо

Ответы [ 13 ]

19 голосов
/ 10 июня 2009

Я никогда не сталкивался с кем-либо, делающим это заявление, и не вижу для этого веской причины. .NET Framework полон интерфейсов со свойствами.

18 голосов
/ 10 июня 2009

Я просто добавлю сюда свой голос - я никогда не сталкивался с этой рекомендацией. Свойство - это фактически пара методов get / set.

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

15 голосов
/ 10 июня 2009

Широко признан термин «кодовый запах». Я предлагаю ввести понятие «запах программиста» - если кто-то настаивает на каком-то правиле, но не может объяснить, почему - это запах. Ваш коллега должен быть в состоянии объяснить, почему свойства интерфейса плохие. Если он не может - он, вероятно, неправ, даже если статья, на которую он ссылается, верна.

В этой статье, возможно, говорилось о некоторых конкретных видах интерфейсов, может быть, это было связано с COM и совместимостью или чем-то еще. Или он может быть просто неправильно понял. Понимание правил и способность объяснять их - важная часть использования правил.

9 голосов
/ 10 июня 2009

Интерфейс - это контракт для реализации класса, и я не вижу причин, почему свойства должны быть исключены из такого контракта. Кроме того, свойства являются неотъемлемой частью .NET.

В качестве примера: ICollection<T> имеет как Count, так и IsReadOnly.

2 голосов
/ 19 августа 2011

Единственный способ понять, почему свойства являются плохими для интерфейсов, - это когда вы определяете интерфейсы для служб (таких как WCF, WebServices, Remoting), которые размещены на разных компьютерах или в доменах приложений.

Причины свойства подразумевают, что они быстрые (иначе говоря, получение и установка значений), что не верно для сервисов, из-за активности сети и сериализации. Метод explizit для получения или установки значений в сервисных интерфейсах подразумевает, что выполнение операции может занять некоторое время.

2 голосов
/ 10 июня 2009

Сам по себе никогда не видел ничего подобного, но некоторое время назад некоторые говорили о том, что не следует использовать свойства в определениях кроссплатформенного интерфейса, поскольку существует множество платформ, которые не поддерживают свойства, но почти все поддерживают методы. *

1 голос
/ 10 июня 2009

Я не могу представить документацию, подтверждающую эту предпосылку. Кроме того, я могу вспомнить много примеров в BCL, которые делают совсем наоборот. Взгляните на практически любой интерфейс коллекции, и вы увидите свойства.

0 голосов
/ 13 декабря 2018

Я вижу, что это вопрос .Net; однако, мышление может исходить из опыта Java. Это напоминает мне пункт 22 из Effective Java: Используйте интерфейсы только для определения типов .

Эта рекомендация не запрещает все свойства в интерфейсах. Он специально предназначен для интерфейсов, содержащих only properties.

Когда класс реализует интерфейс, интерфейс служит типом , который можно использовать для ссылки на экземпляры класса. То, что класс реализует интерфейс, должно поэтому сказать что-то о том, что клиент может сделать с экземплярами класса. Неуместно определять интерфейс для каких-либо других целей.

Один тип интерфейса, который не проходит этот тест, - это так называемый постоянный интерфейс . Такой интерфейс не содержит методов; он состоит исключительно из статических полей финала ...

Шаблон постоянного интерфейса плохо использует интерфейсы. То, что класс использует некоторые константы внутри, является деталью реализации. Реализация постоянного интерфейса вызывает утечку этой детали реализации в экспортируемый API класса ... это представляет обязательство: если в будущем выпуске класс будет изменен, так что ему больше не потребуется использовать константы, он все равно должен реализовать интерфейс обеспечить бинарную совместимость. Если нефинальный класс реализует постоянный интерфейс, все его подклассы будут иметь свои пространства имен, загрязненные константами в интерфейсе.

Конечно, сама Java (и, вероятно, C #) содержит примеры этих константных интерфейсов. В книге также говорится об этом.

В библиотеках платформы Java есть несколько постоянных интерфейсов ... Эти интерфейсы должны рассматриваться как аномалии и не должны эмулироваться.

Я согласен с предыдущими ответами, что я никогда не видел рекомендации избегать интерфейсов, содержащих как свойства, так и методы.

0 голосов
/ 16 июня 2017

IEnumerator является идеальным примером для сценария, где для свойства интерфейса потребуется членство. Как вы собираетесь хранить текущий элемент, если не заставляете исполнителя делать это?

0 голосов
/ 19 августа 2011

Это плохой дизайн, поскольку вы загрязняете пространство переменных реализации, которое используется для хранения состояния, переменными, которые используются как часть контракта класса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...