get/ set method vs public variable

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

Re: get/ set method vs public variable

абе то винаги можеш да го направиш public ако е въпроса.

конкретен (груб) пример - в момента си го измислям - имаш клас контейнер. пъхаш вътре разни неща. имаш метод isEmpty(). обаче искаш по време на тестовете да можеш да провериш и size(). не искаш да оставяш size() достъпен за другиет.

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

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

Сигнатура!
Отговор
в отговор на Questor #42

Re: get/ set method vs public variable

ami prawsih si tazi struktura w klas koito testwash otdelno?

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

Re: get/ set method vs public variable

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

Твоят клас освен isEmpty сигурно ще има и други методи. Да кажем Add() и Remove(). Ето ти тест за размер (C#, NUnit ориентиран):


SomeCollection container = new SomeCollection();
Assert.IsTrue(container.IsEmpty());

container.Add(firstItem);
container.Add(secondItem);

Assert.IsFalse(container.IsEmpty());
container.Remove(secondItem);
Assert.IsFalse(container.IsEmpty());
container.Remove(firstItem);

Assert.IsTrue(container.IsEmpty());


Признавам примерът е прост, но често върши работа и може дори да не се имплементира Size() за по-прости случаи.

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

още по теста на Size()

Questor написа "обаче искаш по време на тестовете да можеш да провериш и size()"

тва дето си написал за теста на контейнери е ного хубаво но не виждам как от тва че IsEmpty е ок разбра че и size е ок

а шо се отнася за изнасянето на size-а в отделен клас не мислиш ли че е малко екстремно да се изнася клас за това примерно
incSize() size++
decSize() size--
getSize() size
(таман се сетих че тва мога и по просто да го запиша като typedef size unsigned; или някаква алтернативна конструкциа в другите езици)

отделно че тва че ako класа ти size работи за мене не означава че ще работи правилно и вав контейнера (най малкото заради грешки в логиката на извикване)

искам само да отбележа че не се заяждам просто от доста време агитираш ХП -то и ми е интересно как се правят нещата вав вашта секта а па ме марзи да чета дебели книги

Отговор
в отговор на userO2 #45

Re: get/ set method vs public variable

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

Сигнатура!
Отговор
в отговор на Дeшeв #46

Re: get/ set method vs public variable

Да бе и аз не се заяждам, ама просто не ми отговори на въпроса.
Демек наистина искам да изтествам 'вътрешния' size на колекцията, виж и примера в по-горния постинг.

Значи аз предимно съм писал юнит тестове на С и там не е толкова фрапиращо като се завреш с макроси навсякъде из кода и проверяваш каквото ти кефне, ама за С++ / .NET някакси не върви.
Сигнатура!

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

Отговор
в отговор на RealGuru #47

.

Това което твърдя е, че независимо дали имаш проверки в get/set методите си, или не (просто връщаш/инициализираш някаква променлива с един ред код), си е "напиперен" клас и най-вероятно говори за но дотам добър дизайн (може да има изключения). Нали никой няма да ми каже, че класа с get/set това му е работата - да прави get/set!? Най-вероятно има съвсем други функции, в който инициализацията или проверката на някаква стойност е част от главното, за което е направен.
На клиентите на класа най-вероятно им пука да ползват нещо от типа
DoSmth(), а не да се подпишкват с отделни променлива, па макар и "капсулирани"!

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

Re: get/ set method vs public variable

Аз мисля, че userO2 е отговорил много добре. Поста ми не целеше да отговаря на size() проблема, ами просто да предложи малък трик, който понякога позволява да се разминеш с отделния клас... в простите случаи естествено.

Подхода с #define private public е ужасен. Не бих го приложил освен ако не съм в изключително неприятна ситуация.

Продължавам да вярвам, че правилният въпрос не е "Как да тествам частните методи и полета?" ами "Как да НЕ тествам частните методи и полета?". Всъщност аз дори вече не ползвам толкова много частни методи и полета -- дори (о, ерес!) често залагам на публичните.

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

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

Re: още по теста на Size()

В отговор на:

не мислиш ли че е малко екстремно да се изнася клас за това примерно
incSize() size++
decSize() size--
getSize() size




Пощурявам като видя такъв въпрос. Честно! "Изнасянето" и изобщо създаването на клас не е подписване на брак! А дори и браковете се развалят.

Първо, не е само това -- като нищо може и друга логика да се вмести покрай размера.
Второ, размера на колекцията често се определя по по-интересни начини -- сети се за дървета, графове, скрити таблици от бази данни (SELECT COUNT(*) FROM MyTable например)
Трето и най-важно, разделям отговорностите. Получавам вместо един аморфен "модул" с неясни отговорности, два ясни и тестваеми класа, които мога да променям повече тъкмо защото мога да ги направя почти независими от имплементацията им. Голяма работа, че единият клас за момента ми се струва малък -- ако остане такъв мога да го "прибера" в някой друг такъв.

В отговор на:

искам само да отбележа че не се заяждам просто от доста време агитираш ХП -то и ми е интересно как се правят нещата вав вашта секта а па ме марзи да чета дебели книги




"Мързи ме да чета, я обясни там набързо за какво се пениш толкова" така ли? Книгите изобщо не са дебели, а като програмист би трябвало вече да си свикнал да четеш постоянно. Нали така?! Термина "секта" изобщо няма да го коментирам.

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

Re: get/ set method vs public variable

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

Това в кръга на шегата,не се заяждам

с малко влакче композирам патките в реката
Отговор
в отговор на Дeшeв #51

Re: get/ set method vs public variable

унификация на кода?

това добър аргумент ли е за теб?

с малко влакче композирам патките в реката
Отговор
в отговор на Дeшeв #52

Re: get/ set method vs public variable

Подхода с #define private public е ужасен. Не бих го приложил освен ако не съм в изключително неприятна ситуация.

Ако сорс файла е компилиран предварително без това #define, въобще нямам представа дали такава програма е коректна.

Всъщност аз дори вече не ползвам толкова много частни методи и полета -- дори (о, ерес!) често залагам на публичните.
Адаптираме се към 'кофти' методология с цената на компромиси в дизайна . Щегичка.

Надявам се скоро да мога да покажа пример по проблем подобен на твоя случай с дървото
Чакам с нетърпение

(бтв наистина започваш да звучиш като проповедник. 'ерес' 'залагам' 'вярвам' )

Сигнатура!
Отговор
в отговор на ZZ #53

Re: Твърдо за set/get

"някой отвън може съвсем легално да промени интегритета на капсулираните данни"

Кое му е легалното? Set метода за какво е?

с малко влакче композирам патките в реката
Отговор
в отговор на Дeшeв #54

Re: get/ set method vs public variable

Продължавам да вярвам, че правилният въпрос не е "Как да тествам частните методи и полета?" ами "Как да НЕ тествам частните методи и полета?".

е кво понеже е зададен неправилен вапрос(се си мислех че има неправилни отговори ма чак па и неправилни вапроси) ти решаваш че тоя вапрос нема смисал и си отговаряш на каквото ти кефне

ето и малко код как ще го изтестваш
в случая вапроса ми е как ще гарантираш сас тестове че boza правилно инициализира newsize (най-вече това нещо sizedownenabled)
-----------------------------------------------------------------------
class boza{
private:
newsize NEWSIZE;

pulic:
pushEntry(X){
if(NEWSIZE.needed) data=NEWSIZE.resizeup();
push(X);
}

popEntry(X){
X=pop();
if(NEWSIZE.sizedownneeded() && NEWSIZE.sizedownenabled() ) data=NEWSIZE.resizedown()
}

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

Re: get/ set method vs public variable

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

Колкото до правилната инициализация и гарантирането й -- ами не можеш ли да създадеш и тестваш въпросния нюсайз в някой метод -- дори и принадлежащ на Боза и на нужното място, в бозистия конструктор да речем, просто да извикаш метода? Можеш да потърсиш информация за Prototype или Builder дизайн патърните.

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

Re: get/ set method vs public variable

Забравих да питам и го правя сега -- какво разбираш под унификация на кода?

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

Re: get/ set method vs public variable

Става въпрос за слагане на "#define private public" в тестовия cpp файл, преди
#include "Production.H" файла. Но не знам дали по-новите компилатори понасят предефиниране на ключови думи от тоя сорт. Не е хубав вариант, но все пак става въпрос за тестов код, ако се закъса.
Варианта с "friend TestClass" помага също, но вече има ред в production code header file.
Е, вариант е, вместо да се тестват private members - да се разчита на аssert + post/pre consitions + class invariants.

Отговор
в отговор на karasko #58

..

class
{
int ID;
char* Name;
char* Address;
};
В тоя пример, какво помага get/set!?

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

Re: ..

бе не знам, ма аз кат видя char * и изобщо ей така стърчащи pointers някъде и посягам към пистолета :)

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

Че то тук баш най си требе


class A
{
protected:
char *Name;
public:
A(): Name(NULL) {}
A( const char *name ) : Name(NULL) { SetName(name); }
~A() { delete []Name; }
const char *GetName() const { return Name?Name:""; }

void SetName( const char * name )
{
if( name ) { delete []Name; Name = new char [strlen(name)+1]; strcpy(Name, name); }

}
};



System Doctor Error:
Your girlfriend is pregnant.
(A)bort, (M)arry, (I)gnore?_
Отговор