Как правильно изменить значение уже созданной переменной экземпляра?

Если у меня есть переменная экземпляра, которая имеет частную видимость, должен ли я использовать сеттер для изменения ее значения или просто изменить значение напрямую?

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

Ниже приведен код, который может помочь более четко передать мой вопрос.

public class A {

private int i;

public A() {
   i = 5
}

private void doSomeCalculationsA() {
   //work done here which results in the value of i being directly changed
   i = 7
}

private void doSomeCalculationsB() {
   //work done here which results in change value of i being changed via the setter
   setI(5)
}

private void setI(int newValue) {
   i = newValue;
}

}

person LDM91    schedule 07.05.2012    source источник
comment
Я большой поклонник ООП, но пропущу сеттер. Смысл сеттеров в том, чтобы вы могли реорганизовать код, не нарушая работу внешних пользователей вашего класса. Частные методы по определению являются внутренними пользователями вашего класса.   -  person Louis Wasserman    schedule 08.05.2012


Ответы (10)


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

«Всегда внедряйте вещи, когда они вам действительно нужны, никогда, когда вы просто предвидите, что они вам нужны».

person Peter Lawrey    schedule 07.05.2012

Нет смысла иметь частный сеттер/геттер, если в функции фактически не выполняются какие-либо операции/вычисления.

person user845279    schedule 07.05.2012

Здесь есть два соображения - читабельность и жесткость. Если эта переменная действительно приватная, то прямой доступ к ней вполне допустим. Это делает ссылку на переменную более удобочитаемой, потому что не возникает вопросов о том, как работает ссылка и на что она ссылается. С первого взгляда ясно, что это должна быть переменная экземпляра.

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

person David Buck    schedule 07.05.2012

Лучше всего вызывать setter/getter для переменных-членов класса Java POJO, в вашем случае я бы предложил использовать setter

person Rachel    schedule 07.05.2012

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

person Makoto    schedule 07.05.2012

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

person Stas Jaro    schedule 07.05.2012
comment
Разница в производительности незначительна. Благодаря встраиванию JIT вызовы методов в Java практически бесплатны. - person Péter Török; 08.05.2012
comment
Стоимость эффективности разработчиков гораздо важнее, чем стоимость вашего процессора. ;) - person Peter Lawrey; 08.05.2012
comment
Очевидно, но есть некоторые незначительные накладные расходы, так что вы могли бы также упомянуть об этом. - person Stas Jaro; 08.05.2012
comment
Для любой обычной программы накладные расходы на вызов метода незначительны, но если бы кто-то выполнял какую-то основную обработку данных, было бы более эффективно без вызова метода каждый раз, когда программа хочет получить доступ к переменной. - person Stas Jaro; 08.05.2012

Это будет зависеть от того, может ли другой объект снаружи изменить свое значение. Например, класс ArrayList имеет атрибут size с закрытым методом установки для операций add и remove, в то время как метод получения является общедоступным. Если другие объекты могут немедленно изменить свое значение, то ваш сеттер должен быть общедоступным.

person Luiggi Mendoza    schedule 07.05.2012

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

С точки зрения ООП, поскольку вы все еще «инкапсулированы» за черным ящиком вашего объекта, я не уверен, что это действительно имеет значение, и отсутствие сеттера все еще в порядке.

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

person Eran Medan    schedule 07.05.2012

Я не думаю, что здесь есть явный победитель, это вопрос стиля. Многие люди предпочитают использовать сеттер даже внутри класса, говоря, что он дает единую точку изменения, позволяющую, например. валидация, и легче проследить, кто меняет значение поля. Однако в современных IDE IntelliSense работает в любом случае, и ИМХО в большинстве случаев проверка никогда не потребуется, поэтому подготовка к ней может быть легким случаем спекулятивной общности. Поэтому иногда проще просто установить значение напрямую.

person Péter Török    schedule 07.05.2012

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

person cyber-monk    schedule 07.05.2012