частные или защищенные переменные?

Как насчет:

^([A-Za-z]|[0-9]|_)+$

..., если Вы хотите быть явными, или:

^\w+$

..., если Вы предпочитаете краткий (синтаксис Perl).

8
задан John Saunders 1 February 2010 в 21:23
поделиться

10 ответов

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

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

private const string _defaultImagePath = @"C:\whatever.bmp";

protected virtual string ImagePath {
    get {return _defaultImagePath;}
}

В производном классе который хочет его изменить:

private const string _myImagePath = @"C:\other.bmp";
protected override string ImagePath {
    get {return _myImagePath;}
}

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

26
ответ дан 5 December 2019 в 05:03
поделиться

Сделайте переменные закрытыми , если вы знаете только, что конкретный класс, в котором они определены, будет единственным, кто будет использовать эти переменные. Однако, если вы хотите расширить класс, вы должны использовать protected . Private действительно так, что вы не используете переменные глобально (поэтому вы используете геттеры и сеттеры в классах), что помогает ослабить связь. Защищенный - вполне приемлемо при расширении класса.

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

4
ответ дан 5 December 2019 в 05:03
поделиться

Если он был объявлен защищенным, я мог бы просто расширить класс, и переопределить эту переменную. Но так как это было личное, мне пришлось скопировать весь код из класса и создать повторяющийся класс с единственным разница в том, что эта строка.

И если бы существовал сеттер для местоположения изображения, вам вообще не понадобился бы подкласс (или новый класс).

И если вместо того, чтобы изменить изображение, вам нужно было другое незначительное изменение, то, возможно, помогло бы создание другого защищенного / виртуального API. А может и нет. Единственное, о чем я хочу сказать, так это то, что трудно сразу рассматривать такой туманный пример и делать из него общие выводы.

Существует компромисс между тем, насколько гибкость класса дает вам с точки зрения его поведения и расширяемости, и сколько усилий требуется для разработки и тестирования класса (и дальнейшего взаимодействия между тем, насколько понятен, хорошо документирован и т. д. класс). Эти конструктивные компромиссы нельзя оценивать в вакууме, их следует оценивать в контексте. Насколько вероятны различные функции / поведения / расширения / изменения, которые класс может , возможно, поддерживать на самом деле ? Хорошо спроектированный класс имеет расширения для общих необходимых сценариев и не имеет ненужных расширений и API. (А для имеющихся там расширений есть выбор между простыми «установщиками» и более сложной расширяемостью защищенных / виртуальных / подклассов ... последнее - не компромисс, на который можно легкомысленно выбирать.)

Я не знаю, что это хорошо (или вообще) отвечает на ваш конкретный вопрос, но, как я прочитал ваш вопрос, у меня возникло ощущение, что вы намекаете, что «лучше для классов быть швейцарскими армейскими ножами, потому что расширяемость / настраиваемость - это хорошо» , и я хотел сказать, что эти «хорошие» вещи имеют компромисс. Также,

2
ответ дан 5 December 2019 в 05:03
поделиться

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

Объявление этой переменной как частной следует рассматривать как выражение намерений разработчиков для этой переменной (т. Е. Внутреннего использования), что означает, что вам нужно либо найти другую точку расширения, либо дублировать код.

Из API с точки зрения дизайна, следует использовать частный, чтобы изолировать детали реализации от вызывающих и защищенный, чтобы предоставить доступ наследникам

1
ответ дан 5 December 2019 в 05:03
поделиться

Make it private until it needs to be protected. This is an abstraction problem with languages like C#, C++ and Java where protected/private is tied to the implementation. Private members can be safely automatically inlined whereas protected cannot. This is similar to the abstraction problem in C# and C++ with monomorphism and polymorphism needing the virtual keyword.

This essentially makes a fragile base class problem. Defining everything as protected/virtual is the safest in terms of reuse but hinders optimizations. Defining everything as private/non-virtual is the most efficient.

In a language like Eiffel, the compiler automatically detects if functions can be inlined and automatically detects if a feature is polymorphic or monomorphic. http://dev.eiffel.com

0
ответ дан 5 December 2019 в 05:03
поделиться

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

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

0
ответ дан 5 December 2019 в 05:03
поделиться

Частные - это, ИМО, всегда лучше на первых порах, а затем сделать общедоступным / защищенным по мере необходимости. Намного проще создать новый метод, чем пытаться удалить функциональность, от которой кто-то зависит.

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

1
ответ дан 5 December 2019 в 05:03
поделиться

Когда я только начинал работать с объектно-ориентированной архитектурой, я делал все общедоступным или защищенным , прикидывая: «Почему я должен ограничивать то, что хотят другие люди? что делать с моим кодом? "

По мере того, как я набирался опыта, произошли две вещи:

  1. Появились современные IDE, которые сделали его смехотворно легко изменить код.
  2. Мне пришлось поддерживать много неприятный код, который был расширен в способы, которые его разработчики не планировали.

Теперь мой подход: сделать его частным , пока вам не понадобится сделать его общедоступным (или защищенным ) - и даже тогда хорошенько подумайте, действительно ли это правильное решение.

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

2
ответ дан 5 December 2019 в 05:03
поделиться

Возможно, я единственный здесь, кто согласен с тем, что, как я думаю, подразумевает автор. Идея открытия суперкласса для внесения изменений в метод доступа может быть непростой и не всегда возможной. Метод private-until-it-need-to-be-protected смехотворен и, в конечном итоге, означает, что у вас действительно не было причин использовать частный.

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

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

В заключение, я говорю:

  • Продолжайте кодировать, используя защищенные, но помните, что это открывает конфиденциальные данные для подклассов.
  • Наслаждайтесь преимуществами легкой расширяемости, но не забывайте поддерживать отношения «есть-а» между супер- и подклассами, чтобы поведение каждого оставалось верным цели метода .
  • Используйте частную переменную / защищенный метод получения, если вы хардкор или вам нужна дополнительная гарантия.
-1
ответ дан 5 December 2019 в 05:03
поделиться

Защищенные элементы являются частью API, поскольку полученные классы в других пакетах (то есть пакеты за пределами контроля вашей организации) могут видеть их. Как таковые они представляют обязательство. Совет по предпочтению частных сумм к советам избежать ненужных обязательств. Вы всегда можете сделать менее заметным элементом более видимым, но вы не всегда можете сделать обратное.

0
ответ дан 5 December 2019 в 05:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: