Собственность и Инкапсуляция

Ниже приведен вопрос об использовании свойств в классе.

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

Многие люди не знают истинную причину использования свойств. Они просто делают это как часть стандарта кодирования.

Может кто-то ясно объяснить, как свойство лучше, чем общедоступная переменная-член, и как оно улучшает инкапсуляцию?

4 ответа

Решение

Инкапсуляция помогает, изолируя классы вызовов от изменений.

Давайте представим, что у вас есть простой класс, который моделирует автомобильный двигатель (потому что все примеры ОО должны включать автомобильную аналогию:)). У вас может быть простое поле, подобное этому:

private bool engineRunning;

Просто сделав это поле общедоступным или предоставив метод получения IsEngineRunning(), это не выглядит иначе.

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

private bool ignitionOn;
private bool starterWasActivated;

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

Если вместо этого вы начали с:

public bool IsEngineRunning()
{
    return this.engineRunning;
}

Теперь вы можете изменить его на:

public bool IsEngineRunning()
{
    return ignitionOn && starterWasActivated;
}

и интерфейс класса остается прежним (хорошие времена).

Лучше предоставлять свойства вместо переменных-членов, потому что это позволит вам выполнять все виды проверок при установке или получении значения переменной-члена.

Предположим, у вас есть переменная-член:

private int id;

и у вас есть государственная собственность

public int ID
{
    get 
    { 
       // do something before returning
    }
    set 
    {
      // do some checking here may be limits or other kind of checking
    }
}

Я сделаю это коротким. Свойства = гибкость

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

Например. возраст может быть выведен на основе даты рождения, canSwim может быть сгенерирован из hasLimbs && floats

2 Представление членов в качестве свойств может быть полезно при работе с неожиданными изменениями [кто-нибудь когда-либо прогнозировал все запросы клиента?] В системах с существующей базой данных.

Например. isAllowed имеет значение true, если пользователь старше 18 лет и кэшируется для повышения производительности. Клиент хочет запустить службу в США, и вы можете вернуть значение false, если установлено значение false, и проверять возраст, только если кэш имеет значение true.

Некоторые мысли:

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

    Например (до)

    public boolean isActive() {
        return this.is_active;
    }
    

    (после)

    public boolean isActive() {
        return this.is_active && this.approved && this.beforeDeadline;
    }
    

    Это особенно важно, если ваш код используется другими (т.е. ваш код сторонний). В определенной степени ваш интерфейс /API должен оставаться стабильным. Небольшие изменения не должны влиять на код другого кода, который его использует.

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

    Например

    public void setActive(boolean active) {
        this.is_active = active;
        this.startTimeout();
        this.updateOtherInformation();
    }
    

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

Другие вопросы по тегам