Это сеттер "зло" - PullRequest
       30

Это сеттер "зло"

3 голосов
/ 25 февраля 2009

Много говорят о том, что добытчики и сеттеры являются «злыми», а что нет.

Мой вопрос: следующий сеттер - это зло? (остальная часть класса для краткости опущена)

int balance

public void deposit(int amount)  
{  
    this.balance += amount;  
}

Этот класс эмулирует банкомат. В Великобритании есть несколько банкоматов, которые позволяют как вносить, так и снимать деньги, поэтому этот объект нуждается в способе изменения своего состояния (баланса). Является ли этот сеттер «злым»?

Ответы [ 12 ]

8 голосов
/ 25 февраля 2009

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

Меня не интересуют сеттеры и геттеры, но в основном потому, что я думаю о своих "объектах" как о объектах более высокого уровня в кодовой базе. Например. (IMO) было бы «более неправильно» выполнять операцию вне класса:

account.SetBalance(account.GetBalance() + depositAmount)

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

8 голосов
/ 25 февраля 2009

За исключением того факта, что нет обработки исключительных условий, он выглядит как совершенно хороший метод ОО - он называется тем, что он делает, и он делает то, что вы ожидаете.

4 голосов
/ 25 февраля 2009

Это вопрос с подвохом? Я спрашиваю, потому что предоставленный метод даже не является "установочным" методом. Это операция, а не собственность. Сеттеры и геттеры обычно являются методами доступа к закрытым переменным (свойствам). Поэтому я думаю, что ответ на ваш вопрос:

Это не сеттер, но как общий метод, который выполняет операцию над объектом, это вовсе не зло.

3 голосов
/ 25 февраля 2009

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

Настоящий «сеттер» будет выглядеть примерно так:

int balance

private void setBalance(int amount)
{
    this.balance = amount;
}

public void deposit(int amount)  
{  
    setBalance(this.balance + amount);  
}

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

2 голосов
/ 25 февраля 2009

Лично я бы назвал это методом, а не сеттером. Стереотипный сеттер будет

public void deposit(int new_balance)
{
    this.balance = new_balance;
}

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

1 голос
/ 25 февраля 2009

Ну, вы бы хотели проверить на наличие отрицательных сумм, нулевой суммы и т. Д. ... но дайте требование, это нормально.

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

0 голосов
/ 26 февраля 2009

это не сеттер, это нормальный метод

даже если это был сеттер, это не зло

это злой сеттер

int _balance = 0;  
public int Balance()  
{  
    get { return _balance; }  
    set { }    //now that's evil!  
}
0 голосов
/ 25 февраля 2009

Это не сеттер. Это обычный метод (или функция-член, или что-то еще).

Сеттер - это функция, которая устанавливает данную переменную в заданное значение, и обычно это плохая идея. Метод - это функция, которая выполняет заданную операцию класса. Это значимо с точки зрения класса.

Если у вас странная структура данных, у вас может не быть переменной «balance». Неважно, какая у вас структура данных, вам понадобится функция «депозит». Есть часть разницы.

0 голосов
/ 25 февраля 2009

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

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

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

0 голосов
/ 25 февраля 2009

IMO, банкомат не должен иметь «баланс» в качестве поля.

(кроме того, ваш метод депозита не является сеттером)

Вероятно, у вас должен быть объект Account с полем «баланс» и, возможно, вспомогательный метод «modifyBalance», который принимает положительное значение для увеличения или отрицательное значение для уменьшения баланса.

Тогда ваши методы ATM будут вызывать 'modifyBalance' для объекта Account при выполнении этих типов транзакций.

...