Getters и Setters са лош OO дизайн?

Гетърите и сетерите са лоши

Прочитайки накратко горната статия, установявам, че гетерите и сетерите са лош OO дизайн и трябва да се избягват, тъй като противоречат на капсулирането и скриването на данни. Тъй като случаят е такъв, как може да се избегне при създаването на обекти и как може да се моделират обекти, за да се вземе това предвид.

В случаите, когато е необходим геттер или сетер, какви други алтернативи могат да се използват?

Благодаря.


person Julio    schedule 30.04.2010    source източник
comment
Разгледайте stackoverflow.com/questions/ 565095/ и приетия отговор.   -  person Don Roby    schedule 01.05.2010
comment
Интересна статия, но -1, тъй като статията обяснява отговора на вашия въпрос.   -  person Martin Smith    schedule 01.05.2010
comment
Свързано четене: c2.com/cgi/wiki?AccessorsAreEvil, c2.com/cgi/wiki?ForgetAboutWritingAccessors, c2.com/cgi/wiki?TellDontAsk   -  person Seth    schedule 01.05.2010
comment
Наистина харесвам много от нещата на Алън. Понякога може да бъде тежък, но е добър в посочването на неща като тези. Разгледайте сайта му за още неща: holub.com   -  person Bill K    schedule 01.05.2010


Отговори (13)


Getters или setters сами по себе си не са лош OO дизайн.

Това, което е лошо, е практиката на кодиране, която включва getter И setter за ВСЕКИ отделен член автоматично, независимо дали този getter/setter е необходим или не (в съчетание с правене на членове публични, които не трябва да бъдат публични) - защото това основно излага изпълнението на класа на външния свят нарушаващи скриването/абстрахирането на информацията. Понякога това се прави автоматично от IDE, което означава, че подобна практика е значително по-разпространена, отколкото се надяваме.

person DVK    schedule 30.04.2010

Пропуснахте смисъла. Валидният, важен момент от тази статия е:

Не искайте информацията, от която се нуждаете, за да свършите работата; помолете обекта, който има информацията, да свърши работата вместо вас.

Разпространението на геттери и сетери в стил Java са симптоми за пренебрегване на този съвет.

person Cory Petosky    schedule 30.04.2010
comment
Те са възможен симптом. Възможно е също проблемът просто да не се поддава на разрешаване по този начин. Или може да са симптом за използване на инжектиране на зависимост. - person Stephen C; 01.05.2010

Да, getters и setters е анти-модел в OOP: http://www.yegor256.com/2014/09/16/getters-and-setters-are-evil.html. С две думи, те не се вписват в обектно-ориентираната парадигма, защото ви насърчават да третирате обект като структура от данни. Което е голяма заблуда.

person yegor256    schedule 16.09.2014

Вярвам в включването на сетери в API само ако те наистина са част от спецификацията на класа (т.е. неговият договор с повикващия).

Всеки друг член на данните, свързан с вътрешно представяне, трябва да бъде скрит и виждам поне 2 основни причини за това:

1) Ако вътрешното представяне е изложено, промените в дизайна са по-проблематични в бъдеще и изискват и промени в API.

2) Излагането на членове на данни със сетери/гетери без предпазливост позволява на извикващите много лесно да развалят инварианта на класа. Обекти с непоследователно състояние могат да причинят грешки, които са много трудни за анализ.

За съжаление има някои рамки, които насърчават (понякога изискват) добавяне на сетери/гетери за всичко.

person Eyal Schneider    schedule 30.04.2010

Гетерите и сетерите не са лоши сами по себе си. Това, което е лошо, е практиката всяко поле да бъде частно и да се предоставят гетери/сетери за всички тях, без значение какво.

person fastcodejava    schedule 31.10.2010

Начинът, по който го чета, авторът твърди, че сляпото поставяне на гетери и сетери около полета не е по-добро от това просто да направите полето публично.

Вярвам, че авторът твърди, че гетерите и сетерите трябва да се поставят рядко и внимателно, защото идеята на OO е, че обектите трябва да ограничават експозицията си само до това, което е необходимо.

person Krumelur    schedule 30.04.2010
comment
Освен това погледнете отговора на Кори Петоски, това е просто лош начин за обработка на информация. Ако поискате от обект да извърши операция върху негови вътрешни променливи, тогава къде се появява сетер или гетер? - person Bill K; 01.05.2010

Ще отида малко по-далеч и ще кажа, че само стойностните типове трябва да имат гетери. Всеки тип стойност трябва да бъде неизменен и да се предлага с конструктор, който е променлив и има сетери.

Ако вашият тип стойност има сетери, те трябва да върнат нов екземпляр след копиране на другите стойности.

Url.setAnchor(...)

Ще върне нов Url, копиращ порта на хоста и т.н., но ще презапише котвата.

Вашите класове на тип услуга не се нуждаят от сетери (задайте ги в ctor) и определено шрифтът се нуждае от гетери. Вашият Mailer трябва да вземе хост/порт/и т.н. статични неща в своя ctor. Ако искам да изпратя имейл, тогава го изпращам в клетка send(), няма причина моят код да трябва да знае или иска или изисква хоста и други стойности на конфигурацията. Въпреки това би имало смисъл да се създаде клас MailServer като следния // тип стойност MsilServer{ String host int port String username Strung password // all come ruth getters } // factory Mailer create( MailServer)

person mP.    schedule 01.05.2010

Гетерите и сетерите са само методи. Те какво правят? Те променят поле в свойство и това е важна разлика.

Полето е малко данни, състояние в обекта. Свойството е външно наблюдавана характеристика, част от договора на обекта. Пръскането на вътрешностите на обект навсякъде, независимо дали директно или чрез гетери/сетери, винаги е лоша идея. Лош дизайн. Но да повдигнем това до степен да кажем, че гетърите и сетерите винаги са лоши? Това е просто някакъв беден програмист без чувство за добър вкус, който твърди, че неясно правило (което те всъщност не са разбрали на първо място) е чугунен закон.

Лично аз съм склонен да се опитвам да запазя имотите като неща, които не се променят неочаквано под краката на клиентите. (Клиенти от класа, който е.) Единствените свойства, които ще променя динамично, са тези, които те не могат да напишат, и дори тогава ще се опитам да го избегна. Чувствам, че свойствата са в много отношения стойности, които контролират поведението на екземпляра, които са зададени от клиента, а не произволни неща под контрола на класа. (За това е нормалното поле...)

person Donal Fellows    schedule 01.05.2010

Предлагам ви да прочетете внимателно цялата статия, тъй като тя представя добре обмислени аргументи и алтернативи. Самият въпрос е твърде отворен и отговорите, които ще получите тук, ще бъдат просто повече мнения.

person Tom Cabanski    schedule 30.04.2010

От статията:

Кога един аксесоар е подходящ? Първо, както обсъдих по-рано, добре е методът да върне обект по отношение на интерфейс, който обектът имплементира, защото този интерфейс ви изолира от промените в имплементиращия клас. Този вид метод (който връща препратка към интерфейс) всъщност не е "гетер" в смисъла на метод, който просто предоставя достъп до поле. Ако промените вътрешната реализация на доставчика, вие просто променяте дефиницията на върнатия обект, за да се съобразите с промените. Все още защитавате външния код, който използва обекта чрез неговия интерфейс.

С други думи, използвайте интерфейси както за методите getter, така и за setter, когато са необходими, така че можете да поддържате капсулиране. Като цяло е добра практика да се посочи интерфейс за тип връщане или формален параметър.

person Matthew Sowders    schedule 30.04.2010
comment
Това е съвсем погрешно, вашите класове за правене на неща трябва да излагат своята конфигурация чрез гетъри. - person mP.; 01.05.2010

Има и други статии, които казват, че са с добър дизайн. Но отговорът е следният: getXXX и setXXX са добри или лоши в зависимост от употребата. тези методи наистина правят много неща по-лесни. Така че, ако в някоя статия се казва, че това е лош дизайн, аз мисля; просто се опитва да бъде твърде строг към идеята.

Една от най-големите употреби на тези методи е в много рамка и се използва като механизъм за отразяване.

Така че не избягвайте напълно да ги използвате, по-скоро... използвайте ги разумно.

благодаря Аюсман

person Ayusman    schedule 01.05.2010

Getters и Setters са лош OO дизайн?

Само когато се използва без замисляне.

Ако трябва да създадете стойностен обект за транспортиране на данни, те са добре.

Ако създавате по-важен обект, те не трябва да са там. Разгледайте например интерфейса ArrayList*. Не виждате Object[] getElementData(), защото това би нарушило капсулирането (някой може да смекчи основния масив).

* Имам предвид публичния интерфейс на класа (методите, изложени от дефиницията на класа)

person OscarRyz    schedule 01.05.2010

Getters/Setters са напълно подходящи, при правилните условия. Масовото получаване/задаване обаче е грешно.

Аз обаче съм малко объркан. Вие отбелязахте Java, но материалът всъщност не е особено специфичен за Java (само примерите). Струва си да се отбележи, че в C++ (най-добре в 0x) много от тези проблеми не съществуват. Ако искате да промените интерфейса си от long на int, тогава между decltype, templates и auto това е лесно постижимо, поради което подобни конструкции са разтърсени. Typedef също работи добре.

person Puppy    schedule 01.05.2010