Можете ли вы когда-нибудь иметь слишком много «защищенных виртуальных» методов? - PullRequest
15 голосов
/ 26 ноября 2008

Вот вопрос для тех из вас, кто имеет опыт работы с большими проектами и разработки API / фреймворков.

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

Я знаю, что многие люди жалуются на то, что .NET Framework содержит слишком много закрытых классов и закрытых членов. Должен ли я избежать этой критики и открыть все свои классы с большим количеством защищенных виртуальных членов?

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

Ответы [ 6 ]

9 голосов
/ 26 ноября 2008

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

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

6 голосов
/ 26 ноября 2008

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

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

Я предпочитаю консервативный подход. Я отмечаю все свои классы sealed, если только я не хочу специально включить наследование, и в этих (немногих) случаях я делаю только необходимые методы виртуальными.

Легко удалить тег sealed, если класс необходимо изменить, чтобы разрешить наследование в будущем. Однако, если вы хотите изменить класс, который уже используется в качестве базового класса для какого-либо другого типа, вы рискуете сломать подкласс при изменении базового класса.

2 голосов
/ 26 ноября 2008

Моя точка зрения:

  • Если вы можете использовать events, то предпочтительнее protected методов.
  • Старайтесь избегать protected методов, насколько это возможно, если это невозможно, вы должны использовать его; -).
1 голос
/ 26 ноября 2008

Выбор protected над private - это продуманное дизайнерское решение. Вы утверждаете, что ваш класс явно поддерживает использование этой функции со всеми накладными расходами (проектирование и реализация), которые идут с этим. Я бы использовал protected только в тех ситуациях, когда я знаю, что это необходимо, в основном потому, что я делаю это сам. (Вы также найдете комментарии разработчиков BCL в том же ключе, что и я.)

Разница в производительности virtual / non- virtual не имеет значения на любой машине, которая достаточно мощна для запуска .NET Framework.

0 голосов
/ 09 августа 2015

Это хорошая идея сделать как можно больше моих методов и свойств protected virtual?

Не такая хорошая идея.

Защищенные виртуальные методы обеспечивают точки расширяемости в платформе при добавлении связи.

Существуют более многообещающие методы для обеспечения расширяемости: Композиция и Делегирование .

0 голосов
/ 26 ноября 2008

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

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