get/ set method vs public variable

70 отговора 2413 прегледа
в отговор на Дeшeв #61

Re: get/ set method vs public variable

оф последен опит

виж поста на Colombino как ще провериш че за Name не се заделя повече памет от колкото тряба.
(за да ни е коректна задачата допускаме че void *malloc( size_t size ); заделя точно size bytes )



[линк]

Отговор
в отговор на KpyM #62

Re: get/ set method vs public variable

Лесно... само трябва да допуснеш, че заделяча на памет е обект!

1) интерфейс за заделяне на памет. допускам, че един символ е един байт.
2) инициализираме A обектите с имплементация на въпросния интерфейс.
3) тестваме истинската имплементация дали си вика там малок или ню като хората.
4) даваме на А фалшива имплементация -- Mock object, в теста, която държи статистика за извикването на методите за заделяне на памет.

Псевдо Ц++:

A a;
MockAllocator allocator;
a.SetAllocator(allocator);
a.SetName("ivan");
ASSERT_TRUE(allocator.GetAllocatedMemorySize() == 4);

Това и на мен ми е последен опит. Истински код с public/private насоченост съм обещал на Questor и дано да успея да закърпя кода и писанията скоро.

--
Екстремно програмиране на български.
[линк]
Отговор
в отговор на Дeшeв #63

Re: get/ set method vs public variable

Не се мори толкоз :) Аз горе-долу се навивам, че ако се ползва pImpl - похвата, можеш спокойно да тестваш имплементиращия клас изотвътре без да пипаш външния.

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

Сигнатура!

Редактирано от Questor на

Отговор
в отговор на Дeшeв #64

Re: get/ set method vs public variable

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

с малко влакче композирам патките в реката
Отговор
в отговор на ZZ #65

Re: ..

Ами мога например да тура проверка, че пича не се казва "+-!#@%&", което е безобидно, или има и по-лоши варианти - пресен пример със SQL Injection, по-натам подаваш името на някое куери

с малко влакче композирам патките в реката
Отговор
в отговор на ZZ #67

Re: 2 интересни линка по въпроса.

Да, разглеждал съм тези неща.
И съм напълно съгласен с болшинството от нещата там ( и на други места ).

много проценти "за" гет/сет не означават - гет/сет за всеки дата мембър - боже опази ...
Въпроса е поставен така - да аксеваме ли директно дата мемберите на класовете, или да използваме гет/сет? Казвам пак - да.

Това не значи че не одобрявам нещо от рода на
struct GUID{
unsigned long Data1;
unsigned short Data2;
unsigned short Data3;
unsigned char Data4[ 8 ];
};
това е чисто информативна структура, поведението на обекта не се дефинира, от "капсулацията" - което го прави да не е чак капсулация. Но това е ОК.

Обаче напр. за
class DataSrc {
....
public :
BOOL m_bConnected;
UINT m_nConnectionsCount;
....
};

съм много НЕНЕ за публик данните за сметка на гет сет.

Изобщо заради факта че може да се напише много кофти нещо не зачи глобално идеята е лоша, напротив - ние често изнасяме при нас ( когато пошем ре-използваем код ), много от "капаните" на имплементацията, само и само са да можем да напишем по-сигурен, по-лесен за използване и по-"fool proof" код, и го правим доколкото е възможно.

Отговор
в отговор на BjarneStroustrup® #68

Ако направим анализ на:

"class DataSrc {
....
public :
BOOL m_bConnected;
UINT m_nConnectionsCount;
....
};"
пак май опираме до въпроса, че нещата би трябвало да са определени на малко по-ранен стадий, преди да сме стигнали до решението дали да има get/set.
Между впрочем, бъдещата имплементация на get и set едновремено прави и двата члена-данни
(m_bConnected и m_nConnectionsCount) public, бе значение в коя секция си ги сложил. Клиента на класа може да си ги сменя както си иска, без значение на проверките в set.
------------------------------
Какво имам предвид за по-ранния стадий:
По-време на дизайна бих определил за какво ми е тоя клас DataSrc, какви операции има, и как тяхното изпълнение зависи от m_bConnected и m_nConnectionsCount.
Най-вероятно конструкции от типа:
if(dataSrc.GetConnected())
{
datasrc.FuncA();
}
бих ги скрил в DataSrc и бих му предоставил сам да си решава поведението в зависимост от състоянието си.
Не че всичко е 100% вярно - няма универсални решения и дизайн. Затова имах предвид, че малко по-рано бих взел решението за get и set присъствието. И не значи, че абсолютно ги отричам.

Отговор
в отговор на KpyM #69

Java The Hut

Някой спецификации просто те задължават да пишеш get и set методи... Напр. такааа популярната JavaBeans. Освен това ако в един момент решиш да смениш типа на private променливата без getter и setter бая зор ще видиш (за Java говоря... на Цъ можеш да си направиш преобразуване на типове). getter а и setter a (не ирландски де :) ти позволяват в един момент дори да разкараш шибаната променлива и да си направиш тотален refactoring на класа без някой въобще да забележи. Знам че сега някой ще изпищи че това е кофти дизайн и трябвало тия неща да ги мисля още в началото... ама юзерите си сменят изискванията със свръхсветлинна скорост и в повечето случаи трябва и ти да реагираш със същата.
Не знам... и на мен не са ми много приятни обаче предимствата им са бая повече от недостатъците. Така де...кой не е използвал тригери в някоя БД?

Отговор
в отговор на ZZ #70

В този случай е така и не мисля,...

...че някой ще слага get/set при него.

Обаче представи си най-обикновена програма за книжарница да кажем, където се продават книги.

Ето ти един пример за класа Книга, който има следните членове.

Клас Книга
заглавие
автор
цена


Да кажем, че заглавието и авторът не се променят и се инициализират в конструктора само. Обаче кво праим с цената? Цената може да се променя според кефа на продавача. И да ти кажа, това не е структура, това си е клас, защото трябва да сложиш някои и други методи, примерно като запис, зареждане и пр. и като се слага цена трябва да я провериш дали е по-голяма от нула и дали има 2 точки след десетичната запетая и др. такива изгъзици.

Та спора е дали да направиш цена публичен член и всеки да може да го променя отвънка или да го направиш с get/set и да можеш да извършваш някои проверки като задаваш стойност.


Така, че ако говорим за класове, който нямат много връзка с база данни, тогава няма смисъл от get/set и си прав в този случай. Тогава методите като прави нещо променят частните членове. Обаче ако имаш обект, който трябва да го запишеш в база данни, тогава слагаш по един get/set на всяко поле или почти на всяко.

Отговор
в отговор на Questor #71

Re: get/ set method vs public variable

Та бях обещал код. Постнах си го на блога -- [линк].

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

Кода в примера почна да става много и не съм публикувал тестовете. Отдавна си мисля за top-down подход при писането и неговото допринасяне към проблема с тестването на обекти от които зависим. Може би в друг блог пост -- така и така съм на вълна NMock.

--
Екстремно програмиране на български.
[линк]
Отговор