Loading...
mihayloff14 avatar mihayloff14 824 Точки

[Technical Issue] OOP - Капсулация на полета от обекти

Здравейте,

Тепърва започва отборната работа по ООП и следователно, започнах по-сериозно да се замислят за всякакви детайли свързани с това. В тази връзка, едно нещо във връзка с споменатия проблем не ми е ясно:

Когато се капсулират обекти, трябва ли да не се позволява публичното им get-ване?

Като пример, ако имаме поле от тип List, и в съответното му property оставим публичен getter, той ще може да бъде манипулиран от външни класове по всякакъв начин, като могат да се махат елементите му, да се добавят нови и т.н. Единственото ограничение е че това поле не може да бъде сменено с нов обект от тип List. 

Това счита ли се за лоша капсулация или е допустимо?

В противен случай, би трябвало да се правят методи във съответния клас тип AddObject, RemoveObject и т.н. Това не се отнася само за List, а и за всякакви обекти, защото през getter-а могат всячески да бъдат access-вани property-тата им.

Тагове:
0
C# OOP Basics 08/02/2015 00:47:08
Filkolev avatar Filkolev 4482 Точки

Според мен такива обекти трябва да могат да се достъпват само през определени публични методи - AddElement() за добавяне например. Също, ако се поиска самия обект, да се върне негово копие, за да не може потребителят да променя оригиналния обект. Ако това е целта разбира се.

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

0
07/02/2015 18:53:04
a_rusenov avatar a_rusenov 1103 Точки

Сещам се за 2 решения:

  • Да върнеш копие от колекцията, като е добре да е документирано, че юзъра получава копие.

public List<String> Names
{
    get
    {
        return new List<string>(this.names);
    }
}

  • Да върнеш колекцията като IEnumerable, така че да не може да се мутира, а само итерира.

public IEnumerable<String> Names
{
    get
    {
        return this.names;
    }
}

Аз бих ползвал втория вариант, като мутирането ще става през Add()/Remove() методи, но ако не се налага да има валидация, не е фатално и да си го оставиш с автоматичен getter.

3
07/02/2015 22:13:19
mihayloff14 avatar mihayloff14 824 Точки

Благодаря за отговора, за втория вариант, който предложи въобще не съм се сещал и е доста хитър.

P.S: Кодът, който си споделил не излиза коректно. Като цяло разбрах какво имаш предвид, но все пак е добре да се види и пример за това, което говориш. ^^

0
07/02/2015 22:11:44
a_rusenov avatar a_rusenov 1103 Точки

Само за 7 минути го оправих. :D

0
mihayloff14 avatar mihayloff14 824 Точки

Здравейте,

Не исках да отварям нова тема затова ще попитам тук отново въпрос на тема Капсулация.

Наскоро си инсталирах Resharper и има някои казуси, по които с него сме в постоянен спор.

В случая, той ми препоръчва property-тата, които са от тип get { return this.x } set { this.x = value } да бъдат направени автоматични.

Та питам, добра практика ли е да имаме клас, в който имаме автоматични property-та, както и такива, които не са автоматични или може би е по-добре когато има неавтоматични property-та - всички да бъдат такива?

0
nikola.m.nikolov avatar nikola.m.nikolov 830 Точки

Resharper-a подсказва за автоматични пропъртита тогава, когато в set-ъра имаме само присвояване на стойност, т.е. излишно е да се пише поле и пропърти, след като може да се използва автоматично пропърти.

Примерно за енумерациите е напълно достатъчно да има автоматично пропърти, защото на конструктора се подава променлива от типа на енумератора, така че няма нужда от никакви валидации. В моите домашни често имам хем автоматични, хем такива с валидация. Всичко зависи от конкретната задача.

 

0
19/02/2015 09:01:15
a_rusenov avatar a_rusenov 1103 Точки

От гледна точка на консистентност е добре да се прави по един начин - като решиш да пишеш автоматични, пишеш само автоматични, и обратно. Като цяло няма смисъл да пишеш пропъртита по дългия начин, ако няма валидация и просто вършат работата на автоматичните. Важното е да няма публични полета.

0
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.