Професионална програма
Loading...
+ Нов въпрос
mihayloff14 avatar mihayloff14 825 Точки

[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 4485 Точки

Според мен такива обекти трябва да могат да се достъпват само през определени публични методи - 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 825 Точки

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

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

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

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

0
mihayloff14 avatar mihayloff14 825 Точки

Здравейте,

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

Наскоро си инсталирах 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