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



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

Клас диаграми


Клас диаграмите са стандартно графично средство за изобразяване на йерархии от типове, предоставено ни от езика за моделиране UML (Unified Modeling Language). Ще се запознаем съвсем накратко с клас диаграмите без да претендираме за изчерпателност, тъй като моделирането с UML е необятна те­ма, на която са посветени хиляди страници и тази материя е извън обхвата на настоящата тема.

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


Изобразяване на типовете и връзките между тях


В UML клас диаграмите типовете се изобразяват като правоъгълници, в които са изписани членовете им, евентуално с отбелязана степен на видимост пред името: + за public, # за protected и - за private. Ето един пример (класът Rectangle):

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


Наследяване


Наследяването на клас и им­пле­мен­ти­ра­не­то на интерфейс се изобразява със зат­во­ре­на стрелка (), като стрел­­ките, обозначаващи наследяване и имплементиране се различават по то­ва, че първите обикновено са плътни, а вторите – пунктирани:

В примера класът FilledRectangle наследява класа Rectangle, а класът Square имплементира интерфейса ISurfaceCalculatable, а.


Асоциация, агрегация, композиция


Връзките меж­ду типовете се изобразяват с от­во­ре­на стрелка (). Тези връзки се наричат още асоциациационни връзки (association links).

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


Множественост на връзките


Връзките композиция и агрегация могат да имат множе­ственост, например "1 към 1", "1 към много" и т.н. Пример за множественост на връзка е връзката между сту­дент и учебна дисциплина (например "1 към много" – 1 студент изучава много учебни дисциплини).

Клас диаграми – пример


Следният пример представлява проста диаграма и илю­стри­ра основните елементи, които ни предоставя UML нотацията за из­граж­дане на клас диаграми:

По затворените стрелки разбираме, че класовете Square и Rectangle на­сле­дя­ват Shape и имплементират интерфейса ISurface­Calculatable, а те от своя страна са наследени съответно от FilledSquare и Filled­Rectangle.

Виждаме също как с отворени стрелки е изобразена връзката "тип съдържа инстанция на друг тип като свой член", както например класът Filled­Rectangle съдържа инстанция на структурата Color.

Пространства от имена (namespaces)


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

Дефиниране


Пространства от имена в C# се дефинират и използват подобно на прост­ранствата от имена в C++ и на пакетите в Java. Задават се с ключовата дума namespace по­сле­двана от името на пространството и множеството от дефиниции на ти­по­ве, оградено във фигурни скоби, както е показано на примера по-долу:

namespace SofiaUniversity

{

// Type definitions ...



}

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

Достъп до типовете


Достъпът до дефинираните в тялото на пространство типове се осъ­щест­вя­ва по два начина – чрез използване на пълно име на типа и с използва­не­то на ключовата дума using.

Пълно име на тип


Пълно име наричаме името на типа предшествано от името на про­стран­ство­­то, в което се намира, разделени с точка. Например ако класът AdministrationSystem е дефиниран в пространството SofiaUniversity, то­гава пълното му име е AdministrationSystem.SofiaUniversity. По този начин се обръщаме към имена на типове, дефинирани в пространства, раз­лич­ни от текущото.

Използването на пространства от имена позволява дефинирането на типове с едно и също име, стига те да са в раз­лич­ни пространства. Пос­редством използването на пълни имена се раз­ре­ша­ват конфликтите, породени от еднаквите имена на типовете. Например клас с име Config може да е дефиниран както в пространството SofiaUniversity. DataAccess, така и в SofiaUniversity.InternetUtilities. Ако е необ­ходимо в даден клас да бъдат използвани едновременно и двата класа, те се достъпват с пълните си имена: SofiaUniversity.DataAccess.Config и SofiaUniversity.InternetUtilities.Config.


Ключовата дума using


Директивата using , поставена в началото на файла, позволява директно използване на всички типове от указаното про­стран­ство само чрез краткото им име. Пример за това е следният фрагмент от ко­да, който се генерира автоматично от Visual Studio .NET при съз­да­ва­не­то на нов файл:

using System;

Това обръщение прави достъпно за програмата основното пространство от име­на на .NET Framework – System, което съдържа някои типове, които се използват постоянно – Object, String, Int32 и др.

Подпространства


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

Подпространства могат да бъдат дефинирани в тялото на пространството ро­дител, но могат да бъдат създадени и в отделен файл. В такъв случай се из­ползва пълно име на пространство от имена. То представлява соб­стве­ното име на пространството предшествано от родителите му, разделени с точ­ки, както например System.Windows.Forms. Пълното име на тип, де­фи­ниран в подпространство, трябва да съдържа пълното му име, например System.Windows.Forms.Form.

Следва да илюстрираме дефинирането на една простра структура от про­стран­ства от имена:

namespace SofiaUniversity.Data

{

public struct Faculty



{

// ...


}

public class Student

{

// ...


}

public class Professor

{

// ...


}

public enum Specialty

{

// ...


}

}
namespace SofiaUniversity.UI

{

public class StudentAdminForm : System.Windows.Forms.Form



{

// ...


}

public class ProfessorAdminForm : System.Windows.Forms.Form

{

// ...


}

}

namespace SofiaUniversity



{

public class AdministrationSystem

{

public static void Main()



{

// ...


}

}

}



В примера по-горе виждаме дефинициите на основното пространство SofiaUniversity и подпространствата му SofiaUniversity.Data и SofiaUniversity.UI, в които сме дефинирали нашите потребителски ти­по­ве, например класовете SofiaUniversity.AdministrationSystem и SofiaUniversity.UI.StudentAdminForm, и структурата SofiaUniversity. Data.Faculty.

Използвайки директивата using можем да включваме пространства, зададени с пълното им име. Тази директива включва единствено това пространство, което спо­менаваме изрично, но не и неговите подпрост­ранства. Например, ако ука­жем using System.Windows няма да имаме директен достъп до класа System.Windows.Forms.Form.

Използвайки ключовата дума using можем да задаваме също и псевдо­ними на пълните имена на пространствата, както например:

using WinForms = System.Windows.Forms;
namespace SofiaUniversity.UI

{

public class StudentAdminForm : WinForms.Form



{

// ...


}
// ...

}

Как да организираме пространствата?


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

Логическа организация


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

Физическа организация


Добре е логическата организация в системите, които разработваме, да отговаря на физическата – публичните типове да създаваме във файлове, носещи тяхното име, а за пространствата – директории с тяхното име, в които да се по­мест­ват типовете им. Когато създаваме вложени простран­ства, е добре да ги съз­даваме като поддиректории на тези на родителите им пространства. Така само с един поглед на структурата на проекта в Solution Explorer на Visual Studio .NET добиваме представа за нея.

За проекта от примера по-горе е удачно да организираме типовете във файлове по следния начин:



Виждаме, че класът Student от пространството SofiaUniversity.Data е разположен във файла Student.cs от поддиректорията Data на директо­рия SofiaUniversity от нашия проект. По същия принцип класът ProfessorAdminForm се намира във файла SofiaUniversity/UI/ ProfessorAdminForm.cs.

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




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




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

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