Как избежать геттеров и сеттеров - PullRequest
25 голосов
/ 23 февраля 2012

Я читал во многих местах, что "добытчики и сеттеры - зло".И я понял, почему так.Но я не знаю, как их полностью избежать.Say Item - это класс, который содержит информацию об имени элемента, количестве, цене и т. Д., А ItemList - это класс, в котором есть список элементов.Чтобы найти общий итог:

int grandTotal()
{
int total = 0;

for (Item item: itemList)
       total += item.getPrice();

return total;
}

В вышеприведенном случае, как можно избежать getPrice ()?Класс Item предоставляет getName, setName и т. Д.

1005 * Как их избежать?

Ответы [ 15 ]

0 голосов
/ 14 марта 2019

Другая точка зрения, которой здесь пока нет: геттеры и сеттеры приглашают нарушить принцип Скажите не спрашивать !

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

Это то, как вы делаете вещи в реальности?Не за что.В реальном мире вы обычно не заботитесь о внутреннем состоянии «автономных» других «объектов».Кассир говорит вам: «Ваш счет 5,85 долларов США».Тогда вы платите.То, как вы это делаете, зависит только от вас, единственное, чего хочет / нуждается кассир, - он получает эту сумму денег с вашей стороны.

Таким образом: вы избегаете добытчиков и сеттеров, думая с точки зрения поведения , не в терминах состояние .Методы получения / установки манипулируют состоянием «извне» (выполняя avail = purse.getAvailableMoney() и purse.setAvailableMoney(avail - 5.85). Вместо этого вы хотите вызвать person.makePayment(5.85).

0 голосов
/ 14 марта 2019

Вы можете избежать использования getter и setter в некоторых местах, используя _classname__attributename, потому что это изменилось новое имя, как только вы объявите private для любого атрибута.

Так что, если Item - это класс с закрытым атрибутом, объявленным как __price

тогда вместо item.getPrice() вы можете написать _Item__price.

Это будет работать нормально.

0 голосов
/ 14 марта 2017

Геттеры и сеттеры являются злыми, потому что они нарушают инкапсуляцию и могут излишне выставлять внутреннее состояние объектов и позволяют изменять его так, как это не должно быть. Следующая статья подробно описывает эту проблему:

http://programmer.97things.oreilly.com/wiki/index.php/Encapsulate_Behavior,_not_Just_State

0 голосов
/ 26 января 2013

Используйте вспомогательный класс ShoppingCart.Метод Item item.addTo(ShoppingCart cart) добавляет цену к totalSum корзины, используя shoppingCart.addItem(Item item, int price)

Зависимость от Item до ShoppingCart не является невыгодной, если Item sпредназначены для предметов ShoppingCart s.

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

Другие мысли

Это также возможно, хотя и довольно неинтуитивнодизайн, чтобы класс Item считал сумму (item.calculateSum(List<Item> items)), так как он может получить доступ к частным частям других элементов, не нарушая инкапсуляцию.Рассмотрим приведенный пример, где getPrice() возвращает целое число.Если вы захотите изменить это значение на что-то лучше, например, BigDecimal или на пользовательский тип денег с валютой, это будет невозможно, поскольку тип возврата int предоставляет внутренний тип.

0 голосов
/ 23 февраля 2012

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

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

...