×
Ви дійсно бажаєте відкрити доступ до тестування за курсом С# Базовий (ООП) на 40 днів?
ВІДЕОУРОК № 2. Класи та об’єкти. Діаграми класів
Перший відео урок містить масу корисної інформації: автор протягом 3-х годин докладно та максимально зрозуміло розповідає про класи, їх поля, властивості та екземпляри, а також розкриває тему об'єктно-орієнтованого програмування та демонструє реалізацію одного з її головних принципів – інкапсуляцію. Весь матеріал підкріплюється зрозумілими прикладами.
Вивчивши зміст цього уроку, ви зможете:
- розуміти суть основних парадигм ООП;
- розуміти, як влаштовані та для чого призначені класи;
- створювати класи та правильно їх використовувати;
- розуміти призначення полів та властивостей, вміти їх реалізовувати;
- створювати конструктор класу;
- розуміти принцип інкапсуляції та реалізовувати його мовою C#.
У відео уроці "Класи та об'єкти. Діаграми класів" буде продовжено тему уроку "Введення в OOП. Класи та об'єкти", а також буде розкрито тему можливості мови програмування C# розділяти визначення класу між двома та/або більше файлами, що називається частковими або partial класами. Після ознайомлення з частковими класами в С# будуть розглянуті діаграми класів, зв'язки відношень між класами, такі як асоціація, агрегація, композиція, реалізація, самоасоціація залежності та інші.
Всі мови ООП, включаючи С#, засновані на трьох парадигмах (концепціях), які називають інкапсуляцією, наслідуванням і поліморфізмом. В ході відео уроку Вам буде представлена інформація про дві основні парадигми ООП – поліморфізм і наслідування, також Ви познайомитеся з модифікаторами доступу та віртуальними членами. В ході уроку, на прикладах, представлених тренером, Ви зможете зрозуміти практичне застосування поліморфізму та наслідування та навчитеся працювати з ієрархією класів.
У відео уроці буде продемонстровано практичні приклади створення та використання абстрактних класів та інтерфейсів. Абстракція дозволяє програмісту розглядати об'єкт, не розбираючи суму складних частин, з яких складається даний об'єкт. Під час відео уроку Ви отримаєте необхідні знання, які допоможуть Вам розібратися з поняттям абстракції в С#, а також навчитеся створювати та реалізовувати власні абстрактні класи та інтерфейси і розуміти різницю між ними.
У відео уроці розглянуто приклади створення і практичного застосування масивів та індексаторів. Тренер пояснює Вам принципи створення і практичного застосування індексаторів та способи їх перевизначення. Програмісти з досвідом знайомі із процесом звернення до індивідуальних елементів, що містять стандартні масиви. У відео уроці буде представлена можливість мови програмування С# проєктувати спеціальні класи, які можна індексувати подібно до стандартного масиву через визначення індексатора. Індексатори часто використовують при створенні спеціальних типів – колекцій. У цьому уроці Ви докладно вивчите можливості індексаторів у C#.
У відео уроці будуть розглянуті статичні класи, принципи створення та практичного застосування статичних членів. Також у ході відео уроку буде пояснено роботу та використання розширювальних методів. У другій частині відео уроку тренер розгляне поняття вкладених класів та шаблон проєктування "Одиночка" (Singleton).
У відео уроці буде представлена повна інформація про структури, розглянуто відмінності між класами та структурами, а також розказано практичні поради щодо їх застосування. Структури – фундаментальні типи даних мови програмування C#. Структури за своєю суттю прості і часто програмісти-початківці можуть не розуміти, наскільки швидко робота зі структурами може стати складною.
У цьому відео уроці будуть розглянуті такі поняття, як пакування (boxing) та розпакування (unboxing), структурний тип DateTime, а також робота з переліченнями (enum). Під час заняття тренер познайомить студентів із практичними прикладами, які дозволять з легкістю використовувати та застосовувати отримані на уроці знання. Останньою темою, розглянутою у відео уроці будуть перелічення, які надають спосіб ефективно визначити набір іменованих інтегральних констант.
Відео урок дозволяє студенту зрозуміти роботу лямбда-виразів та делегатів. Програмісти-початківці, продумуючи інтерфейс чергового класу, часто розуміють, що дуже корисною могла б бути можливість передавати у якості аргументу методів частину виконуваного коду. Делегати дозволяють Вам реалізувати такий підхід. У відео уроці буде представлена інформація про створення та застосування делегатів, а також основні труднощі під час роботи з ними.
У мові програмування C# існує два механізми для створення коду, який буде повторно використаний через різні типи – вже розглянуте раніше наслідування та узагальнення. Узагальнення, на відміну від наслідування, виражають повторне використання коду через використання універсальних шаблонів (generics), у яких застосовуються різні типи даних на етапі виконання. Під час відео уроку тренер розгляне з Вами всі основи роботи з узагальненнями та їх застосування у мові програмування C#, а також розповість про контрваріантність та коваріантність.
У відео уроці "Обмеження універсальних шаблонів" на Вас чекає продовження знайомства з універсальними шаблонами в C#. Ви дізнаєтесь, як можна використовувати обмеження для узагальнених типів даних. Під час відео уроку тренер зупинить Вашу увагу на роботі з Nullable типами, а також на операціях поглинання, показавши приклади їх практичного використання.
Весь відео урок буде повністю присвячений роботі з подіями в C#. У деталях буде розглянуто, яким чином створювати "видавців" та "підписників", а також звертатися до створених подій та викликати їх. Тренер приділить окрему увагу делегату EventHandler та базовому класу EventArgs, а також роботі з ними.
У процесі перегляду відео уроку Ви отримаєте основні відомості, які будуть потрібні Вам для роботи з багатопоточністю в мові програмування C#. Багатопотоковість – важливий засіб багатозадачного програмування середовища .NET. Відео урок дасть Вам основне розуміння багатопоточності у мові програмування С#. Також під час уроку тренер розповість Вам про використання делегатів ThreadStart і ParameterizedThreadStart і пояснить роботу з критичними секціями, як засобами синхронізації доступу потоків до різних ресурсів, котрі розділяються.
У відео уроці будуть пояснені колекції, їх призначення та приклади їхнього практичного застосування. Також Ви детально вивчите базові інтерфейси IEnumerable, IEnumerator. Також в ході відео уроку тренер розгляне з Вами приклади створення та використання колекцій користувача, продемонструє наочні приклади по роботі оператора yield.
У цьому відео уроці Ви дізнаєтеся, які системні винятки існують в мові C# і як правильно обробляти виняткові ситуації за допомогою конструкції try-catch-finally. Також ви навчитеся створювати свої об'єкти виключення. Під час виконання програми може скластися ситуація, коли коректне виконання програми неможливе. Наприклад, програма читає файл на диску, якого немає. У такій ситуації у додатку виникає спеціальний об'єкт – виняток. Виняток описує проблему, яка виникла в момент виконання коду і дозволяє розробнику обрати потрібну дію для вирішення проблеми.
У даному відео уроці тренером буде розглянуто базовий клас object, його застосування та використання, а також техніка перевантаження операторів. У процесі пояснення буде пройдено техніку клонування, а також буде розглянуто призначення шаблону проєктування «Прототип» (Prototype) та інтерфейсу ICloneable. Вам буде продемонстровано практичне використання техніки перевантаження операторів.
Даний відео урок буде дуже важливим для розуміння всіх сучасних технологій. Під час відео уроку тренер познайомить Вас з основами LINQ, а також з анонімними та динамічними типами, що активно використовуються при побудові запитів. Мова LINQ – це набір функцій, що дозволяє значно розширити можливості синтаксису мови програмування C#. Language Integrated Query (LINQ) представляє розширення мови C#, яке дає можливість працювати з різними джерелами даних, використовуючи синтаксис запитів, подібний до мови SQL.
У цьому відеоуроці Ви дізнаєтеся, що таке простір імен і як правильно організовувати проєкт, використовуючи простір імен. Також Ви дізнаєтесь, як створювати бібліотеки (DLL) у мові C#. Тренер розгляне тип проекту Class Library та на простому прикладі пояснить, для чого використовуються бібліотеки. Наприкінці уроку Ви вивчите нові модифікатори доступу internal і internal protected та розглянете деякі препроцесорні директиви, дізнаєтесь, як вони можуть допомогти при розробці великих рішень.
Здравствуйте! И тема сегодняшнего урока: «использование классов и объектов». В этом уроке мы рассмотрим такие понятия, как частичные классы, частичные методы, рассмотрим различные парадигмы ООП, и так же рассмотрим язык моделирования UML (Unified Modeling Language) – это язык для представления визуального формализма при моделировании объектно-ориентированных систем. Так же мы рассмотрим отношения связей между классами.
И первое, что мы рассмотрим – понятие «частичные классы» или «partial class». Давайте посмотрим на этот слайд. На слайде мы видим представление классов, как они выглядят, и вот на этом слайде есть комментарий: «В С# реализована возможность разделить создание класса или метода (структуры, интерфейса) между двумя или более исходными файлами или модулями. Каждый исходный класс содержит определение типа или метода, и все части объединяются при компиляции приложения». Давайте мы зайдем в visual studio и посмотрим как выглядят частичные классы в коде, Обратите внимание мы открываем папку “PartialClasses” в первом проекте и здесь мы имеются два файла с расширением .cs. Заходим в первый файл “PartialClass_1.cs”. На 6-й строке мы создаем partial class с именем «PartialClass». На 8-й строке мы создаем метод с именем «MethodFromPart1», который ничего не принимает, ничего не возвращает. В методе мы выводим на экран строку, чтобы оттенить работу нашего метода. Теперь заходит во второй файл с расширением .cs «PartialClass_2.cs» и в нем на 6-й строке мы так же создаем partial class, обратите внимание на ключевое слово partial – оно говорит о том что класс будет «частичным», то есть один класс будет разбит на несколько частей и разносится по нескольким файлам. Зачем это делается? Это делается для удобства. Сейчас мы посмотрим, где такие классы встречаются в практической деятельности. На 8-й строке мы создаем метод с именем «MethodFromPart2». Обратите внимание, если в первом файле мы создали метод с именем «MethodFromPart1» то здесь у нас имеется метод с именем «MethodFromPart2», в котором мы выводим строку: «II part». Теперь если мы зайдем в класс Program, в теле метода main на 11 строке мы создаем экземпляр класса PatialClass под названием instance и на 13-й строке мы обращемся к экземпляру нашего класса и вызываем метод «MethodFromPart1» и метод «MethodFromPart2». Обратите внимание, здесь у нас создается экземпляр одного класса, но, тем не менее, получается, что методы присутствуют как из одной части, так и с другой. Что это такое? Это некое удобство, чтобы мы могли распределять функциональность по разным частям класса например, в каком-то случае тело класса может быть слишком большим и разные программисты работают над одним классом, в каком-то случае у нас имеется раздельная функциональность, которая должна входить в этот класс, например, если у нас есть вспомогательная функциональность, то она может быть вынесена в какую-то одну часть, а некая бизнес-логика может быть вынесена в другую, снова же для удобства. Мы такой подход видим часто в шаблоне, при создании проекта «Windows Forms Application».
Давайте мы сейчас попытаемся создать такой проект. Мы создаем проект по шаблону «Windows Forms Application» и сейчас мы посмотрим, что у нас здесь сгенерировалось. Если мы зайдем в код и нажмем клавишу F7, обратите внимание, на 13-й строке мы создаем класс Form1, который помечен спецификатором partial. Если мы теперь посмотрим что у нас тут еще есть, перейдем допустим в файл Form1.Designer.cs. Обратите внимание у нас здесь имеется еще один partial class «Form1». Таких класса «Form1» их два: в одной части обычно хранятся методы обработчики событий элементов управления. Обычно, если мы по кнопке дважды кликаем, здесь автоматически генерируется обработчик событий. Давайте посмотрим как это выглядит. Заходи в Designer Form, открываем Toolbox, возьмем на пример кнопочку и поместим ее в область формы. Дважды кликаем и в одной из частей класса Form1 метод обработчик события нажатия на кнопку button_Click1. То есть мы видим, что partial классы достаточно часто используются в программировании, если мы их видим сразу же, после создания шаблона «Windows Forms Application».
Хорошо, мы с вами продолжаем. Еще раз вернемся к презентации и посмотрим на эти коды, которые здесь представлены. У нас создается один PartialClass, второй одноименный PartialClass и в каждом классе имеется свой метод. Далее в теле метода Main() мы создаем экземпляр класса PatialClass, который в действительности будет объединен в один класс, то есть вся функциональность будет объединена. И мы видим, что в примере мы обращаемся к методам, которые расположены в разных частях этого класса. Еще раз, для разделения класса на несколько частей, используется ключевое слово patial.
И следующее, что мы рассмотрим, это такие конструкции как partial или частичные методы. Частичные методы – это методы, где «прототип» или сигнатура метода определена при создании частичного класса, а реализация происходит в любой другой (только одной) части этого класса. Что это значит? Вот сморите, у нас имеется частичный класс и в этом классе у нас есть только сигнатура метода. Это напоминает старый подход, когда мы использовали компилируемые языки программирования, когда у нас в проекте (например в проекте С++) присутствовал файл с расширением .cpp и с расширением .h (так сказать header – заголовочный файл). В заголовочных файлах мы обычно определяли только прототипы, которые состояли, практически, только из сигнатуры. И тут мы тоже видим только прототип. В С++, когда мы задавали прототип в заголовочном файле, то мы говорили, что мы объявляем какую-то конструкцию, а уже в .срр файле мы определяли эту конструкцию. Поэтому, когда мы программируем на языке C#, это не совсем корректно говорить, что тут мы объявляем класс или метод, а там – определяем, потому что объявить можно в одном месте, а определить - в другом, и невозможно определить ранее не объявленное. А когда вы просто что-то создаете, то нужно говорить, что мы просто создаем. Поэтому я рекомендую говорить не «объявляем или определяем какую-то конструкцию», а говорить, что мы создаем (например, мы создаем класс, мы создаем метод, мы создаем свойство, и так далее). Но относительно частичных методов мы можем говорить, что тут мы объявляем, а там определяем, потому что в одной части класса мы объявляем метод, а сама реализация – в другой части. И вот обратить внимание в теле main мы создаем экземпляр класса PartialClass, у нас происходит слияние двух частей и далее мы вызываем на экземпляре метод СallPatrialMethod(). Обратите внимание, что в теле метода СallPartialMethod() мы вызываем PartialMethod, модификатор доступа используется private, кстати с partial методами мы не можем использовать никаких модификаторов доступа. Они всегда будут private. Давайте мы перейдем к следующему слайду. И здесь мы видим правила использования частичных методов: частичные методы должны быть определены только частичных классах, частичные методы должны быть помечены ключевым словом partial, частичные методы всегда являются private, попытка явного использования сними модификатора доступа приведет к ошибке, частичные методы должны возвращать void, частичные методы могут быть не реализованными – это значит, что в одной части можем его объявить а в другой можем пока не определять (не реализовывать). Давайте перейдем к программному коду и посмотрим, как у нас выглядит работа в коде с частичными методами.
Заходим во второй проект. Обратите внимание, у нас в папке PartialMethod находятся двя файла PatialClass_1 и PartialClass_2. Заходим в PatialClass_1. Видим, что на 6 строке мы создаем PartialClass. В теле этого класса мы объявляем частичный метод PartialMethod. Обратите внимание, здесь используется только его сигнатура, но не используется тело. На 11 строке мы объявляем еще один частичный метод MyMethod. Помните, мы говорили что, частичные методы не могут иметь возвращаемого типа? Давайте попробуем это проверить. При попытке описать новый частичный метод с возвращаемым типом int "partial int My();" - компилятор выдаст нам ошибку. Главное помнить, что частичные методы могут иметь аргументы, но не могут иметь возвращаемых значений. И еще важно помнить, что частичные методы объявляются в одной части класса, а реализуются в другой. Зачем так делается, мы с вами будем смотреть дальше пример использования частичных методов. Сейчас мы смотрим правила их создания и варианты использования. Сразу скажу, что частичные методы встречаются достаточно редко.
На 6 строке мы создаем частичный класс с именем PartialClass. На 9 строке мы уже определяем метод PartialMethod, ранее объявленым в первой части. Нотация звучит как и в С++: в хедере - объявляем, в срр - определяем. Мы понимаем, что частичные методы являются private и к ним мы можем обратиться только внутри класса, в котором они созданы. И на 15 строке мы создаем открытый метод CallPartialMethod. В теле этого метода на 17 строке мы вызываем PartialMethod, а на 15 строке - вызываем MyMethod. Обратите внимание, что метод MyMethod - не реализован. При выполнении программы у нас ошибки нет, не смотря на то, что у нас происходит здесь вызов. Давайте снимем комментарий и еще раз выполнить программу и видим что, нам выводится текст, указанный в методе MyMethod: " реализация частичных методов в других частях класса не обязательна", хотя мы можем это сделать. То есть мы можем вызвать метод, если у нас есть объявление, но нет определения.
Я думаю, что с частичными методами и частичными классами все предельно понятно: это достаточно простые конструкции, они используются в основном для удобства. Дальше мы еще будем с ними встречаться и посмотрим варианты использования.
И следующее что мы с вами рассмотрим такое понятие как инкапсуляция. На 7 строке мы создаем класс MyClass, а на 9 строке мы создаем поле того же типа, что и мы создаем. То есть получается что здесь создается ссылка на самого себя. На 11 строке мы создаем метод с именем Method. На 16 строке создаем открытый метод CallMethod и в нем мы присваиваем полю my ссылку на экземпляр класса MyClass. Но при этом мы сразу же обращаемся к закрытому private методу Method данного класса. Если мы попробуем сделать то же самое за пределами класса, у нас будет ошибка. На 29 строке в теле метода main мы создаем экземпляр класса MyClass, вызываем открытый метод CallMethod. Но если мы сейчас попытаемся обратиться к закрытому методу, то компилятор выдаст ошибку. То есть правило следующее: объект не может скрывать (инкапсулировать) ничего от другого объекта того же класса, то есть внутри само класса инкапсуляция не работает, то есть не работает реализация членов класса. Здесь мы также видим новую технику - технику само-ассоциации, но об этом мы поговорим чуть позже, когда подойдем к рассмотрению языка UML.
А сейчас мы рассмотрим одну особенность - поля только для чтения. Обратите внимание, у нас имеется ключевое слово readonly - это модификатор, который можно использовать только для полей. Здесь мы на 10 строке создаем открытое поле, только для чтения, и присваиваем ему некоторые значения, в данном случае слово "hello". На 15 строке в конструкторе мы присваиваем новое значение этому полю "поле только для чтения". При этом, попытка присвоения значения из любого другого места, кроме как конструктора - приведет к ошибке. Даже если мы в этом же классе создадим еще один метод, например void M() и присвоим этому полю некоторые значения - у нас тоже будет ошибка. Поэтому поля только для чтения не немного похожи по своему поведению на константы, но на самом деле они являются полноценным полем, но инициализировать их мы можем только во время их создания либо в конструкторе класса, который содержит такое поле. Давайте вернемся к презентации и посмотрим описание. Если поле используется с модификатором readonly, то присвоение значений таким полям может происходить только при создании или в конструкторе того же класса.
А сейчас мы посмотрим, что такое язык UML. Расшифровывается как Unified Modeling Language -унифицированный язык моделирования. На этом языке невозможно программировать, но можно моделировать объектно-ориентированные системы, либо часть этих систем, для их удобного представления. Чтобы обеспечить визуальный формализм, с помощью которого мы можем производить как создание, так и анализ программного обеспечения. Об этом языке подробно можно посмотреть на сайте omg.org в меню раздел technology и раздел UML. UML имеет множество различных диаграмм, но нас, как программистов, будет интересовать только 2-3 типа диаграмм: диаграммы классов, диаграммы последовательности и диаграммы кооперации. Полностью создать модель с использованием языка uml достаточно хлопотное и дорогое занятие, потому что язык uml позволяет описать модель объектно-ориентированной системы, но иногда это нерационально писать полностью все сущности, которые есть у нас в программе.
Вернемся к презентации и посмотрим, что из себя представляет диаграмма классов. Диаграммы классов - это такие диаграммы, которые позволяют нам представлять классы прямоугольниками и между ними проводить разного рода линии. Основные элементы языка uml - это прямоугольник и линия. Прямоугольник будет символизировать собой некий класс, структуру или какой либо другой стереотип, линия будет представлять собой одну из нескольких связей отношений. Прямоугольник принято называть классификатором. Сам классификатор разбивается на секции. 1 секция - это секция имени. Обратите внимание, секции, фактически нарисованы как карандашом под линейку. Это значит, что uml диаграммы мы можем рисовать как на бумаге, так и с помощью каких-то программных средств. Такие программные средства есть даже у нас в visual studio, которые мы можем посмотреть . Давайте откроем и попробуем создать новый проект: Add -> New project -> Modeling projects. Кликаем правой кнопкой мыши по Modeling projects и выбираем Add -> new item. И видим, что здесь у нас в шаблонах имеется UML Class Diagram. Открываем палитру элементов. И видим, что мы в область диаграммы можем поместить класс. Конечно не принято, чтобы классы хранились в такой белой области . Вы спросите а как принято? Давайте откроем любой пример. Видите вот эту странную конструкцию namespace, в которую складываются все классы? Конструкцию namespace мы рассмотрим на последнем уроке, потому что с помощью этой конструкции мы сможем формировать слои. И когда мы будем проектировать архитектуру нашего приложения, конечно же, мы будем формировать слои. Эти слои являются не чем иным как конструкцией пространств имен - namespace. В языке uml конструкции namespace представляются в виде Package. И мы берем это пространство имен и туда вкладываем наши классы. Например, создадим 3 класса: 1 - Document, 2 - Title, 3- Body. И мы видим, что класс Document должен как-то использовать класс Title и Body. Document - это у нас некий ассоциативный объект, который сам не обладает полноценный функциональностью, а собирает эту функциональность из частей, которые в нём написаны. И давайте проведем какую-то связь между этими классами. Проводим ассоциативную связь между классами Document и Title, Document и Body. Направим какую-то стрелочку от Document к Title. Что это значит? Посмотрите на направление этой стрелки. Фактически Document является источником выстрела стрелки, а Title является целью, куда она должна попасть. И вот мы понимаем, что если мы проводим именно такую связь отношений, она называется ассоциацией, это значит, что Document знает об этих частях. Вот эти части не знают ничего о документе, потому что в классе Title не создается поле или какая-то переменная типа Document. Поэтому Title ничего не может знать о документе, который его содержит. И как вы помните, в примере мы рассматривали, что в Document описываются поля типа Title и типа Body . Вот соответственно от него и исходят стрелы к этим классам.
Перейдем обратно к презентации. Мы видим, что классификатор разбивается на секции: 1 секция это секция имени , 2 секция - секция атрибутов , где находится описание полей. Обратите внимание на слово атрибуты. В документации uml поля обозначается не как поля, а как атрибуты. Но при программировании на C# так говорить нельзя, потому что в языке C# есть такая конструкция как атрибуты. Давайте мы ее рассмотрим, как она выглядит. Давайте зайдем в какой-то файл, например AssemblyInfo.cs. И видим, например на строке 8 какую странную конструкцию – это и есть атрибуты. Их вы будете изучать на курсе professional. Конструкция атрибутов пришла к нам из аспектно-ориентированных языков. У нас есть низкоуровневые языки, процедурные языки, функциональные языки, объектно-ориентированные языки, аспектно-ориентированые языки и так далее. Так вот, понятие аспекта у microsoft было названо понятием атрибут. Просто запомните, что в секции атрибутов в нашем случае хранятся поля и мы бы в своей нотации сказали, что это секция полей. Следующая секция - это секция операций. По правилам языка uml метод или функция, созданные в классе, мы говорим, что мы создали операции. Когда мы создали экземпляр этого класса, поставили точку и пытаемся вызвать эту функцию мы говорим, что мы вызываем метод. То есть мы создаем класс, называем эту функцию операцией, во время создания, пока мы в ней что-то пишем. А когда мы уже на экземпляре через точку обращаемся к этой функции, мы говорим, что мы вызываем метод. Но это чистая нотация ООП в представлении языка uml. Далее, обратите внимание на последнюю секцию. Это секция обязанностей и она не обязательна. В этой секции пишутся некие "to do" - что нам нужно сделать. Обязанность можно добавить в коде, написав комментарий вот таким образом: // todo: обязанность. И теперь, если в visual studio зайти в tasklist, то там можно увидеть то, что нужно сделать. То есть, это такая возможность сделать какой-то план или заметки самому себе.
Давайте теперь посмотрим, как вот этот класс, который представлен с использованием языка uml, представить с помощью языка С#. То что находится в секции имени у нас используются вот здесь: "class MyClass". Мы создаем класс с именем MyClass, в секции атрибутов мы создаем поле field и в секции операций мы создаем метод Method(). Давайте теперь посмотрим, как представлен класс на диаграммере visual studio Class Diagram (он доступен только в редакции ultimate). В этом диаграммере мы также можем создать некие классы, провести связь ассоциации, создать методы, поля. Он очень похож на язык uml, но это не он. Этот язык называется DSL (domain specific language). Domain - это определенный архитектурный слой, который описывает именно бизнес сущности, описывает бизнес-модель разрабатываемой программы. Потому что программы разделяются обычно на 3 слоя: 1 слой программы описывает только пользовательский интерфейс, другой слой описывает работу с бизнес логикой , там где мы работаем с такими сущностями как документ, сотрудник и другими суцностями, третий слой это слой по работе с данными. Так вот язык DSL предназначен именно для 3-го слоя.
В языке dsl мы уже имеем дело с секциями полей и методов. Также, обратите внимание, под названием класса находится такое слово как class, мы, так же, встречались c такой конструкцией как структура (struct). А что такое class или что такое структура (struct)? Одним словом эти сущности называются стереотипами. На следующем слайде мы видим список всех стереотипов, которые имеются в языке C#. Мы с вами рассмотрели конструкции класса, краем глаза посмотрели на такой стереотип как структура (вы помните, что все простые типы данных являются структурами (int, boolean), а тип string является классом). Далее у нас будут такие стереотипы как абстрактные классы, интерфейсы, generic структуры , generic интерфейсы, generic классы, generic абстрактные классы, generic делегаты, сами по себе делегаты, перечислительный тип Enum (он является единственным пользовательским скалярным типом данных).
Обратите внимание, у нас имеется классификатор (это класс), у нас имеется секция полей, секция методов, возле каждого поля и метода имеются какие-то значки . Вот эти значки языке dsl обозначают модификаторы доступа если возле синего кубика ничего нет (синие кубики обозначают поля , розовые кубики обозначают методы), значит используется модификатор доступа public. В языке uml public представлен плюсом. Поля с модификатором доступа private, обозначаются минусом.
Теперь рассмотрим все возможные отношения между классами. Обычная линия и линия со стрелкой обозначает связь ассоциации (мы с вами ее рассматривали). Связь отношения ассоциации звучит так: "я знаю о...". То есть источник знает о цели. Следующая - агрегация, которая звучит так: «состою из...» Мы видим, что в данном случае документ состоит из Title и Body, поэтому здесь нам нужно взять связь отношения агрегации. И теперь мы видим, что документ не знает о своих частях, а, в действительности, состоит из этих частей. И когда я смотрю на диаграмму классов и вижу связь агрегации, я понимаю что документ - это некий составной объект , который состоит из каких-то частей . И допустим, если бы мы описывали какую-то жизненную сущность например холодильник , то мы бы сказали что холодильник состоит из, например коробки с дверями и морозильной системы. Следующая связь отношений - композиция. Композиция это жесткая форма агрегации. Она звучит так: «состоит из и не может без него жить». Например, может ли документ жить без Body? Без Title мы можем как-то обойтись, а вот без body - не можем, поэтому здесь связь агрегации не совсем подходит. И нам здесь лучше выбрать связь отношения композиции. И теперь мы видим, что документ состоит из двух частей и не может состоять без части Body. Идем дальше. Следующая связь отношения это обобщение (так же переводится как наследование). Наследование это процесс передачи всего открытого и защищенного состояния поведения одного класса к другому. Реализация напоминает исследование, но это немножко другое и их нужно различать. Что еще хотелось бы заметить, при описании объектно-ориентированное проектирования часто используется тоже такое слово как композиция. Так вот, если вы будете читать книгу "Паттерны проектирования" , вы будете часто встречать такое слово как композиция . Но в контексте этого источника композиция звучит не как жесткая форма агрегации, а как собирательное понятие ассоциации и агрегации.
Мы с вами идем дальше. Давайте сейчас посмотрим, какая бывает ассоциация. Ассоциация бывает направленная (однонаправленная). Чтобы создать такую конструкцию, нам нужно создать один класс именем MyClass1 и второй класс именем MyClass2. В классе MyClass1 создаем поле MyObj типа MyClass2.
Двунаправленная (или не направленная) - такая зависимость называется циклической зависимостью, она не рекомендуется к использованию. Чтобы создать такую конструкцию, нам нужно создать один класс именем MyClass1 и второй класс именем MyClass2. В классе MyClass1 создаем поле MyObj типа MyClass2. В классе MyClass2 создаем поле MyObj типа MyClass1.
Рефлексивная ассоциация (само-ассоциация) - с ней мы уже встречались, когда у нас в классе было создано поле типа этого же класса. Такая ассоциация выражается стрелочкой, которая выходит из нашего класса и в него же входит. То есть этот класс одновременно является и источником и целью.
Часто допускают такую ошибку , что само-ассоциацию некоторые программисты называют само-агрегацией. Дело в том, что само-агрегации не может быть по определению (ее не бывает). Почему? Потому что мы знаем что ассоциация это "знает о", агрегация - "состоит из", и мы не можем сказать что, например я состою из самого себя.
Теперь давайте рассмотрим какие есть диаграммы. Sequence Diagram - в этой диаграмме у нас находятся диаграммы объектов. То есть, если в диаграмме классов мы работали с классами, то в sequence diagram мы имеем дело с объектами. UseCase Diagram - эти диаграммы интересует больше бизнес-аналитика: "у нас есть система, у нас есть пользователь, этот пользователь взаимодействует с системой каким-то образом...". Программистам редко приходится использовать такие диаграммы. UML Activity Diagram - такие диаграммы тоже описывает последовательности (такие диаграммы мы рассмотрим на курсе UML), они очень редко используются и скоро будут заменены диаграммами BPMN. UML Component diagrams - здесь у нас идет работа с компонентами. Компонент - это большой сложный объект и главный принцип компонента - он должен быть независимым. С такими компонентами приходится работать по определенным правилам - по контрактам. И, по правде сказать, язык C# не совсем объектно-ориентированный - он компонентно-ориентированный (объектная ориентация является основой для компонентной ориентации. Процедурная ориентация является основой для объектной ориентации). Layer diagram - здесь мы строим общее представление о приложении. Мы уже говорили, что в основном приложение делится на три слоя. Presentation Layer – там, где находится работа со всеми графическими составляющими, business layer – там, где у нас идет работа с бизнес объектами, и data layer.
Идем дальше. И сейчас мы рассмотрим использование техники в фабричных методов. У нас имеется класс Product , имеется конструктор, в котором мы вводим строку, имеется фабрика - это отдельный класс, в котором имеется специальный фабричный метод - это методы которые порождают продукты. И в итоге на 27 строке мы создаем фабрику, на 29 строке мы создаем локальную переменную product типа Product и присваиваем ей возвращаемое значение фабричного метода, внутри которого создается экземпляр класса Product на куче и возвращается ссылка на него. Эта ссылка присваивается вот этой переменной. И получается? что как в жизни: если мы, допустим, посмотрим на какую-нибудь кондитерскую фабрику - это большой объект, внутри которой стоят станки (фабричные методы), которые выплевывают из себя какой-то продукт.
Мы рассмотрели первую работу с фабриками и фабричными методами. И если вас интересует более углубленное изучение, вы можете зайти на наш видео портал, найти вебинар по паттернам проектирований и его посмотреть (там хорошо и очень детально описывается фабричный подход в программировании).
И теперь давайте посмотрим последний пример. На 5 строке создаем класс MyClass1, на седьмой строке конструктор оттеняет его работу выводом строки. На 13 строке мы создаем класс с именем MyClass2, на пятнадцатой строке мы создаем поле MyObj типа MyClass1 и зануляем его. Смотрите, что мы здесь пытаемся сделать. Мы в методе Method создаем экземпляр класса MyClass1. Можем ли мы назвать этот метод фабричным? Нет, фабричным методом мы можем назвать только тот метод, который имеет возвращаемое значение типом порождаемого этого продукта. А если происходит вот такое создание, то этот метод не является фабричным (таким способом не рекомендуется создавать объекты).
Мы подошли к концу этого урока давайте вернемся к презентации и посмотрим, что мы с вами сегодня изучали. Мы с вами изучали частичные классы (partial classes), такие понятия как частичные методы (partial methods), рассмотрели правила использования частичных методов, рассмотрели такую конструкцию языка как readonly, мы подошли к знакомству с языком uml, мы это сделали, потому что uml хорошо описывает различные объектно-ориентированные подходы, различные правила и, как мы видим, этот язык подходит не для программирования, а для моделирования объектно-ориентированных систем. Так же, мы рассмотрели с вами, какие у нас имеются диаграммы языка и связи отношений uml. Мы рассмотрели основные лексические единицы языка uml, как мы понимаем это прямоугольник, который называется классификатором, и линия, которая выражает собой различные связи отношений. Дальше мы рассмотрели более подробно о классификаторе, познакомились с таким понятием как стереотип, рассмотрели связи отношений, разобрали что такое ассоциация, агрегация и композиция, и поговорили вообще об объектно-ориентированном программировании, об его парадигмах. Об этом мы, конечно же, будем говорить еще много на протяжении всего курса. Будем повторять, будем расширять, будем исправлять те не полные иллюзии абстракции, которые мы готовы воспринять на таком уровне. Пока мы не можем все полностью понять, приходится что-то недоговаривать или говорить немножко искаженно, в упрощенной форме, чтобы потом вносить корректировки. Хорошо, мы тогда заканчиваем наш урок, спасибо за внимание, до новых встреч.