У вас может быть слишком много "защищенных виртуальных" методов?
Вот вопрос для тех из вас, кто имеет опыт работы с более крупными проектами и дизайном API/каркаса.
Я работаю над каркасом, который будет использоваться многими другими проектами в будущем, поэтому я хочу сделать его приятным и расширяемым, но в то же время он должен быть простым и понятным.
Я знаю, что многие люди жалуются, что среда .NET содержит слишком много закрытых классов и частных членов. Следует ли мне избежать этой критики и открыть все мои классы с большим количеством защищенных виртуальных участников?
Можно ли сделать как можно больше моих методов и свойств protected virtual? В каких ситуациях вы могли бы избежать защищенного виртуального и сделать членов закрытыми.
Ответы
Ответ 1
В ваш класс входят члены данных; методы, которые выполняют базовые внутренние операции над теми членами данных, где функциональность никогда не должна изменяться, всегда должны быть частными. Таким образом, методы, которые выполняют основные операции с вашими членами данных, такие как инициализация и распределение, должны быть частными. В противном случае вы рискуете производными классами "второго порядка", которые получают неполный набор способов поведения; первые производные члены могут потенциально переопределить поведение класса.
Что все сказано, я думаю, вы должны быть очень осторожны с определением методов как "защищенных виртуальных". Я бы использовал большую осторожность при определении методов как "защищенных виртуальных", потому что это не только объявляет возможность переопределять функциональные возможности, но в некотором смысле определяет ожидаемое ожидание переопределенного функциональность. Это звучит для меня как переопределенный набор способов поведения; Я бы предпочел переопределить определенный набор действий. Если вы хотите иметь очень большой набор переопределяемых типов поведения, я бы предпочел бы взглянуть на Aspect Oriented Programming, что позволяет использовать этот вид очень структурированным способом.
Ответ 2
Когда вы отмечаете метод со словом virtual, вы позволяете пользователям изменять способ выполнения этой части логики. Для многих целей это именно то, что вы хотите. Думаю, вы уже это знаете.
Однако типы должны быть предназначены для такого расширения. Вы должны активно выбирать методы, где имеет смысл позволить пользователю изменить поведение. Если вы просто похлопываете по виртуальному по всему месту, вы рискуете разрушить целостность типа, это не поможет пользователю понять тип, и вы можете ввести ряд ошибок, включая проблемы, связанные с безопасностью.
Я предпочитаю консервативный подход. Я отмечаю все мои классы с помощью sealed
, если я специально не хочу включить наследование, и в тех (нескольких) случаях я делаю только необходимые методы виртуальными.
Легко удалить тег sealed
, если класс необходимо изменить, чтобы разрешить наследование в будущем. Однако, если вы хотите изменить класс, который уже используется в качестве базового класса для другого типа, вы рискуете сломать подкласс при изменении базового класса.
Ответ 3
Моя точка зрения:
- Если вы можете использовать пользователь
events
, его предпочитают методы protected
.
- Старайтесь избегать методов
protected
, насколько это возможно, если это невозможно, вы должны его использовать; -).
Ответ 4
Выбор protected
over private
- это продуманное дизайнерское решение. Вы заявляете, что ваш класс явно поддерживает использование этой функции со всеми накладными расходами (проект и выполнение), которые прилагаются к этому. Я использовал бы только protected
в тех ситуациях, когда я знаю, что это необходимо, во многом потому, что я делаю это сам. (Вы также найдете комментарии разработчиков BCL в тех же строках, что и я.)
Разница в производительности virtual
/non virtual
не имеет отношения к любой машине, достаточно мощной для работы .NET Framework.
Ответ 5
Нет, у вас не может быть "слишком много". Однако идея о том, что мы должны просто делать все защищенные, а не частные, или избегать "запечатывания" любой ценой, просто глупо. Я бы сохранил "вспомогательные методы" и внутренние структуры данных.
Ответ 6
Является ли хорошей идеей сделать как можно больше моих методов и свойств protected virtual
?
Не такая хорошая идея.
Защищенные виртуальные методы предоставляют точки расширяемости в структуре при добавлении связи.
Есть более многообещающие методы обеспечения расширяемости: Composition и Delegation.