Когда класс должен использовать свои собственные геттеры / сеттеры вместо прямого доступа к членам?

При создании сеттеров и геттеров в Eclipse одним из вариантов является использование геттеров и сеттеров внутри класса, а не прямой доступ к членам класса. Полезен ли этот уровень внутренней инкапсуляции класса или это заходит слишком далеко от хорошей идеи?

DUPE: Следует ли использовать свойства средства доступа из класса или только извне класса?


person stimms    schedule 25.02.2009    source источник
comment


Ответы (7)


Я думаю, что это хорошая идея, если вы хотите, чтобы возникли потенциальные побочные эффекты - проверка, ведение журнала и т. Д. (В C # я хотел бы иметь возможность объявить переменную и свойство и сказать, что only доступ к переменной осуществляется через свойство.)

Иногда вы можете обнаружить, что вам нужно установить переменную напрямую, потому что вам не нужны побочные эффекты. Например, вам может потребоваться установить две переменные вместе, и оба состояния «до» и «после» действительны, но установка любого свойства по отдельности приведет к взрыву проверки.

person Jon Skeet    schedule 25.02.2009

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

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

person Joachim Sauer    schedule 25.02.2009

Короткий ответ - "как бывает" :)

У Эрика Липперта есть отличная статья об Автоматическом vs. явные свойства, которые решают эту проблему, хотя и под несколько другим углом.

По сути, вам нужно задать следующий вопрос:

«Изнутри класса, [является ли] желаемая семантика доступа к этому ... свойству отличается от желаемой семантики доступа к свойству извне?»

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

person AwesomeTown    schedule 25.02.2009

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

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

person starblue    schedule 25.02.2009

Когда вам нужно расширить поведение геттера / сеттера класса, полезно иметь инкапсулированные поля (геттеры / сеттеры вместо прямого доступа к членам). Тем не менее, в наследовании концептуально интересно сохранить внутренние элементы вашего класса, если его подклассы не должны знать о его личных вещах. Итак, иногда поле является частным для реализации класса, так что даже подклассы не знают о нем.

person rcaval    schedule 12.03.2009

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

Я считаю, что наличие частных / внутренних свойств действительно помогает в этих случаях.

Но я точно не делаю этого ни для кого.

Последняя версия .NET / VS действительно помогает, поскольку вы можете объявить свойство как таковое:

public string SomeProperty
{
get;
set;
}

и он эффективно создает мем за сценой. Я знаю, что это вам не поможет, но я подумал, что это может быть интересно :-)

person Yossi Dahan    schedule 25.02.2009

Если вы хотите, чтобы этот член мог быть привязан к базе данных Winform или WPF, я считаю, что вам нужно объявить его как свойство. Я примерно на 95 процентов уверен, что для привязки данных требуется свойство (синтаксис получения / настройки). У меня есть небольшое решение wpf, которое демонстрирует это, но я не вижу способа прикрепить его сюда.

Вот код: (построен с VS 2008 SP1, нацелен на .net 3.5 - я использовал проект WPF). В проекте WPF есть 2 элемента: главное окно (window1) и объект, который мы тестируем (DataObject). В окне есть метка, привязанная к свойству Name в экземпляре объекта данных. Если преобразовать свойство Name в поле (удалить геттер / сеттер), привязка данных перестанет работать.

Window1.xaml:

<Window x:Class="WpfDatabinding.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
    <Label Name ="Label1" Height="28" Margin="12,24,37,0" VerticalAlignment="Top" Content="{Binding Name}"></Label>
</Grid>

Window1.xaml.cs

using System;
using System.Windows;

namespace WpfDatabinding
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        private DataObject ADataObject;

        public Window1()
        {
            InitializeComponent();
            this.ADataObject = new DataObject();
            this.ADataObject.Name = "Hello!";
            this.DataContext = this.ADataObject;
        }
    }
}

namespace WpfDatabinding
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        private DataObject ADataObject;

        public Window1()
        {
            InitializeComponent();
            this.ADataObject = new DataObject();
            this.ADataObject.Name = "Hello!";
            this.DataContext = this.ADataObject;
        }
    }
}

DataObject.cs:

namespace WpfDatabinding
{
    public class DataObject
    {
        // convert this to a field, and databinding will stop working
        public string Name
        {
            get;
            set;
        }
    }
}
person JMarsch    schedule 25.02.2009