Насколько необходимо в наши дни писать get / set методы при работе с внутренними переменными?

Ранее было чуть ли не железобетонное правило писать get/set методы при работе с внутренними свойствами объектов. Мотивация по их написанию была такой: если потребуется написать более сложную логику при работе со свойством объекта, то внутри get/set метода это сделать значительно проще.

За несколько лет, читая разные куски кода написанных классов, я всегда видел только то, что такие методы очень простые: return this.__private_var или this__private_var = value.

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


Ответы (1 шт):

Автор решения: Bogdan

Мотивация писать геттеры и сеттеры - не только упрощение описания сложной логики при работе со свойством объекта. Мотиваций несколько:

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

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

  3. Возможность контролировать и ограничивать доступ к чтению/записи свойства по любым причинам и, как следствие, предотвратить "поломку" внутреннего состояния объекта. Например, есть класс Ellipse. У него есть методы, которые используют каноническое уравнение эллипса. При отсутствии геттеров и сеттеров можно без проблем сделать myellipse.a = 0;, что впоследствии может стать сюрпризом при попытке какого-то другого метода вычислить (x*x)/(a*a). При наличии сеттера можно сделать что-то вроде (пример ниже) и получить исключение при инициализации (что несколько приятнее звонков посреди ночи со словами "твоя программа закрылась с ошибкой, нужно срочно фиксить"):

function set_a(new_a_value):
    if new_a_value == 0:
        throw Exception("Невозможно установить `a` равным 0")

    this.a = new_a_value

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

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

→ Ссылка