Кратко съдържание


Принципи при обектно-ориентирания дизайн



страница33/73
Дата21.07.2018
Размер9.03 Mb.
#76887
1   ...   29   30   31   32   33   34   35   36   ...   73

Принципи при обектно-ориентирания дизайн


Ще разгледаме няколко много важни принципа за ефективно проектиране на типове, които всеки добър софтуерен разработчик трябва да познава и прилага. Тези принципи не се отнасят само за езика C#, а са важни концепции при проектирането и изграждането на софтуер. Те намират приложение дори не само в софтуерното инженерство, но и във всички инженерни дисциплини като цяло.

Когато създаваме софтуерни системи целим да опростим работата по раз­работването, поддържането и развиването им. Това пос­ти­гаме като се придържаме към ясна и разбираема структура на сис­те­ма­та, близка до проб­лемната област, към която е ориентирана тази система. Добре напра­веният обектно-ориентиран ди­зайн намалява значително усилията за изу­чаване на сис­те­мата при извършването на промени. За да го постигнем, е необходимо да се съобразяваме с няколко основни принципа, които ще разгледаме сега.


Функционална независимост (loose coupling)


Когато създаваме типове, които минимално зависят един от друг, можем да променяме всеки от тях без да е необходимо задълбочено познаване на цялата система. Към този принцип за функционална независимост трябва да се при­държаме и когато дефинираме членовете на един тип. Ако ми­ни­ми­зи­ра­ме вза­и­мо­за­ви­си­мостите в системите, които разработваме, ще можем много по-лесно да из­пол­зва­ме вече създадените модули, типове и методи в други проекти.

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

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

Тъй като клас диаграмите показват връзките между типовете, те ни по­ма­гат да идентифицираме нивото на независимост между тях. Използвайки клас диаграми можем чисто визуално да преценим дали типовете, които из­­­ползваме, имат прекалено много зависимости помежду си.


Силна логическа свързаност (strong cohesion)


Действията, които даден метод или клас извършва, трябва да бъдат логи­чес­ки свързани, да са насочени към решаването на една обща задача (не няколко логически несвързани задачи). Това свойство, е известно още като модулност. За да имаме ефективна модуларизация в проекта, който разработваме, трябва всички типове да предоставят ясен интерфейс, който е възможно най-прост и не съдържа излишни методи и свойства. Необходимо е още всички методи в типовете да са свързани логически и да имат имена, които ясно подсказват за какво служат. Не трябва да имаме типове, които имат няколко несвързани логически отговор­ности и изпълняват разнородни задачи. Това е признак на лош дизайн и води до много проблеми при поддръжката на системата.

Препоръчително е всеки тип, с който работим, както и всеки негов метод, да е свързан с решаването на обща задача и всяко действие, което се извършва да е стъпка или елемент от решаването й. Така системите които из­граж­даме, ще бъдат много по-раз­би­ра­еми, и от там лесни за раз­ши­ря­ва­не и под­дръж­ка. Силната свързаност на­­малява сложността в проектите ка­то спомага за ефективното разделяне на отговорностите в системата.


Упражнения


  1. Формулирайте основните принципи на обектно-ориентираното про­грамиране. Дефинирайте понятията клас, обект, атрибут, метод, ен­капсулация на данните, абстракция на данните и действията, на­сле­дяване, полиморфизъм.

  2. Дефинирайте клас Student, който съдържа като private полета данните за един студент – трите имена, ЕГН, адрес (постоянен и временен), телефон (стационарен и мобилен), e-mail, курс, спе­ци­ал­ност, ВУЗ, факултет и т.н. Използвайте изброен тип (enumeration) за специалностите, ВУЗ-овете и факултетите. Дефинирайте свойства за достъп до полетата на класа.

  3. Дефинирайте няколко конструктора за класа Student, които при­е­мат различни параметри (пълните данни за студента или само част от тях). Неизвестните данни запълвайте с 0 или null.

  4. Добавете в класа Student статично поле, което съдържа ко­ли­чест­во­то инстанции, създадени от този клас от стартирането на про­гра­ма­та до момента. За целта променете по подходящ начин конструкторите на класа, така че да следят броя създадени инстанции.

  5. Направете класа Student структура. Какви са разликите между клас и структура?

  6. Направете нов клас StudentsTest, който има статичен метод за от­пе­чатване на информацията за един или няколко студента. Методът трябва да приема променлив брой параметри.

  7. Добавете към класа StudentsTest няколко статични полета от тип Student и статичен конструктор, който създава няколко инстанции на структурата Student с някакви примерни данни и ги записва в съ­ответните статични полета.

  8. Създайте интерфейс IAnimal, който моделира животните от реалния свят. Добавете към него метод Talk(), който отпечатва на конзолата специфичен за животното писък, булево свойство Predator, което връща дали животното е хищник и булев метод CouldEat(IAnimal), който връща дали животното се храни с посоченото друго животно. За проверка на типа животно използвайте оператора is.

  9. Създайте класове, които имплементират интерфейса IAnimal и мо­делират животните "куче" и "жаба".

  10. Създайте абстрактен клас Cat за животното "котка", който им­пле­мен­тира частично интерфейса IAnimal.

  11. Създайте класове Kitten и Tomcat за животните "малко котенце" и "стар котарак", които наследяват абстрактния клас Cat и им­пле­мен­ти­рат неговите абстрактни методи

  12. Създайте клас CrazyCat, наследник на класа Tomcat за животното "луда котка", което издава кучешки звуци при извикване на вир­ту­ал­ния метод Talk().

  13. Реализирайте клас със статичен метод, който инстанцира по един обект от всеки от класовете, поддържащи интерфейса IAnimal, и им извиква виртуалния метод Talk() през интерфейса IAnimal. Съ­от­вет­стват ли си животинските писъци на животните, които ги издават?

  14. Направете всички полета на структурата Student с видимост private. Добавете дефиниции на свойства за четене и писане за всички полета.

  15. Направете свойството за достъп до ЕГН полето от структурата Student само за четене. Направете и полето за ЕГН само за четене. Не забра­вяйте задължително да го инициализирате от всички кон­стру­ктори на структурата.

  16. Напишете клас, който представя комплексни числа и реализира основните операции с тях. Класът трябва да съдържа като private полета реална и има­гинерна част за комплексното число и да пре­де­финира операторите за събиране, изваждане, умножение и деление. Реализирайте виртуалния метод ToString() за улеснение при отпечат­ването на комплексни числа.

  17. Реализирайте допълнителни оператори за имплицитно пре­об­ра­зу­ва­не на double в комплексно число и експлицитно преобразуване на комп­лексно число в double.

  18. Добавете индексатор в класа за комплексни числа, който по индекс 0 връща реалната част, а по индекс 1 връща имагинерната част на да­дено комплексно число.

  19. Организирайте всички дефинирани типове в няколко пространства от имена.

  20. Направете конструкторите на структурата Student да подава из­клю­че­ния при некоректно зададени данни за студент.

  21. Добавете предизвикване на изключения в класа за комплексни числа, където е необходимо.



Сподели с приятели:
1   ...   29   30   31   32   33   34   35   36   ...   73




©obuch.info 2024
отнасят до администрацията

    Начална страница