Polymorphism - Wildfarm - Оценка на решението ми?
Здравейте,
много бих искал някой, който разбира от OOP да погледне как съм решил последната задача от темата за полиморфизъм. Постарах се да изпълня изцяло зададеното условие и да направя кода си възможно най-КПК, поне за знанията, които имам до момента.
Като цяло от задачата не се изисква кой знае какво, като дори съм учуден, че май няма подводни камъни, защото ми даде 100/100 от първият път, нещо за което принципно се празнува :D Но все пак ми отне 2-3 часа, докато я осмисля, структурирам правилно и т.н., тъй като все още материала е пресен, а се изисква да се използва почти всичко взето от този курс, за да се напише някакво basic OOP.
Много ще съм благодарен, ако някой отдели 10мин от времето си и ми напише един конструктивен отговор, дали съм се справил добре и какво мога да подобря.
Тук е ZIP с кода и вътре в него условието на задачата също така: изтегли ме
Благодаря! :)
Първо да ти благодаря за изчерпателният и подобрен анализ. Сега да поотговоря на точките :)
1. За имената на полетата в класовете си наистина доста прав, не се бях замисля, че в класа Animal няма нужда полетата ми да започват с animal, тъй като е очевидно.
2. Да, да си призная като че ли, не бях много наясно, че ако ги поставя в конструктора трябва и в пропъртитата, но вече мисля че ще го запомня :)
3. Много си прав. И на мен ми се струва излишно, но единствената причина поради, която го сложих е защото в условието на задачата също го има. Ако погледнеш дадената Class Diagram на screehshot-a, ще видиш, че има такова поле.
4. Това ми е ясно и знам, че не е правилно. За това съм сложил note под този ред: "// default condition doesn't have sence in the logic, I just want to return something as I used switch instead of if/else". Но причината поради, която го оставих така, е защото не успях да измисля какво да върна за да може да го приема Animal като обект. Пробвах с new object(), ама не става, а не мога да върна празен клас Animal, защото той е абстрактен и не се инициализира. Трябваше да си пренапиша switch-a на if, else ама не ми се пренаписваше и за това така го оставих. Ще прочета за класа, който споменаваш.
5. Това не го знаех, не знам дали сме го учили ама наистина се учудих като видях код в който работи, просто като подам обект. Но аз по навик пак така си го написах. Но сега се замислих и се сетих, че Stringbuilder-а, работи по същият начин, дори аз го ползвам бе ToString(), но ако искаме да върнем String на някъде, тогава вече ползваме ToString(), make sense, след като каза че Console.Writeline всъщност го извиква имплицитно.
6. Разбирам, преправих го на is, не е перфектно, но поне е доста по-добре от преди. Всъщност "заблудата" ми да използвам начинът за сравнение беше защото видях на една лекция, че използват .GetTyp().FullName, но тогава беше за override на ToString() мисля, и на мен просто ми дойде като първото решение в главата, как да разбера дали е това което търся всъщност.
7. Схващам ти идеята. Ако използвам Console.Writeline в някой клас, кодът ми става зависим. И ако искам това приложение да го пусна на някоя друга OS, няма да стане. Така ако си изградя един клас, който примерно използва Console.Writeline и след това използвам само този метод, който всъщност принтира, дори да сменя OS, ще трябва да направя промяната само на 1 място, а не на 200 примерно. Просто защото задачата е малка и не съм се замислял, да правя нещо такова.
8. Да и това съм пропуснал, наистина е повтаря кода. Оправих го :)
Благодаря за стойностният отговор по темата!
Здрасти отново,
4. Когато входните данни са грешни и няма как по зададения вход да създадеш обект, не създавай празен обект - това само би объркало хората. Трябва по някакъв начин да индикираш, че това е проблемна ситуация. Може да върнеш NULL, но рискуваш ползвателите да не го забележат това и впоследствие някъде кодът им да резултира в проблем. Може би е по-добре да хвърлиш изключение.
Това, всъщност, е класическият пример за една 'рецепта' наречена - фабрика за обекти (Factory design pattern). В най-опростеният му вариант се имплементира точно по този начин, обикновено примерите са със switch/case и в default-а се хвърля изключение: https://en.wikipedia.org/wiki/Factory_method_pattern#C.23
Здравей, RoYal,
браво за изчерпателния отговор / анализ / препоръка / практика, как точно да пишем код.
Всичко, което казваш е много правилно, но аз искам да обърна внимание относно т.1 как да именоваме полетата в класовете. Много често в лабовете / упражениенията се казва създайте примерно клас "Animal" с полета animalName, animalType, animalWeight и т.н. (не ме разбирай погрешно, нямам нищо против коментара ти или каквото и да било)
Не мислите ли, че е добре и в примерите да се променят тези наименования, тъй като на всички ни се набиват в главите тези неща и ние си ги пишем така, или всичко това се прави за улеснение и да разберем кое точно за какво се отнася...