Читати книгу - "Занурення в патерни проектування, Олександр Швець"
Шрифт:
Інтервал:
Додати в закладку:
В об’єктних мовах програмування за допомогою механізму інтерфейсів, які зазвичай оголошують через ключове слово interface, можна явно описувати «контракти» взаємодії об’єктів.
Наприклад, ви створили інтерфейс ЛітаючийТранспорт з методом летіти(звідки, куди, пасажири), а потім описали методи класу Аеропорт так, щоб вони приймали будь-які об’єкти з цим інтерфейсом. Тепер ви можете бути впевнені в тому, що будь-який об’єкт, який реалізує інтерфейс чи то Літак, Вертоліт чи ДресированийГрифон, зможе працювати з Аеропортом.
UML-діаграма реалізації та використання інтерфейсу.
Ви можете як завгодно змінювати код класів, що реалізують інтерфейс, не турбуючись про те, що Аеропорт втратить сумісність з ними.
СпадкуванняСпадкування — це можливість створення нових класів на основі існуючих. Головна користь від спадкування — повторне використання існуючого коду. Розплата за спадкування виражається в тому, що підкласи завжди дотримуються інтерфейсу батьківського класу. Ви не можете виключити з підкласу метод, оголошений його предком.
UML-діаграма одиничного спадкування проти реалізації безлічі інтерфейсів.
У більшості об’єктних мов програмування підклас може мати тільки одного «батька». Але, з іншого боку, клас може реалізовувати декілька інтерфейсів одночасно.
ПоліморфізмПовернемося до прикладів з тваринами. Практично всі Тварини вміють видавати звуки, тому ми можемо оголосити їхній спільний метод видавання звуків абстрактним. Усі підкласи повинні будуть перевизначити та реалізувати такий метод по-своєму.
Тепер уявіть, що ми спочатку помістили декількох собак і котів у здоровезний мішок, а потім із закритими очима будемо витягувати їх з мішка одне за одним. Витягнувши тваринку, ми не знаємо достеменно її класу. Але, якщо її погладити, тваринка видасть звук залежно від її конкретного класу.
bag = [new Cat(), new Dog()];foreach (Animal a : bag)
a.makeSound()
// Meow!
// Bark!
Тут програмі невідомий конкретний клас об’єкта змінної а, але завдяки спеціальному механізмові, що називається поліморфізм, буде запущено той метод видавання звуків, який відповідає реальному класу об’єкта.
Поліморфізм — це здатність програми вибирати різні реалізації під час виклику операцій з однією і тією ж назвою.
Для кращого розуміння поліморфізм можна розглядати як здатність об’єктів «прикидатися» чимось іншим. У вищенаведеному прикладі собаки й коти прикидалися абстрактними тваринами.
Окрім спадкування та реалізації існує ще декілька видів зв’язків між об’єктами, про які ми ще не говорили.
ЗалежністьЗалежність в UML-діаграмах. Професор залежить від навчального курсу.
Залежність це базовий зв’язок між класами, який показує, що один клас швидше за все доведеться міняти при зміні назви або сигнатури методів другого. Залежність з’являється там, де ви вказуєте конкретні назви класів — у викликах конструкторів, під час опису типів параметрів і значень методів тощо. Ступінь залежності можна послабити, якщо замість конкретних класів посилатися на абстрактні класи чи інтерфейси.
Зазвичай UML-діаграма не показує всі залежності — їх занадто багато в будь-якому реальному коді. Замість забруднення діаграми залежностями, ви повинні бути дуже прискіпливими і показувати лише ті залежності, що важливі для змісту, який ви хочете донести.
АсоціаціяАсоціація в UML-діаграмах. Професор взаємодіє зі студентом.
Асоціація — це коли один об’єкт взаємодіє з іншим. В UML асоціація позначається звичайною стрілкою, що спрямована в сторону взаємодії. Двостороння асоціація між об’єктами теж цілком прийнятна. Асоціацію можна розглядати як більш суворий варіант залежності, в якому один об’єкт завжди має доступ до об’єкта, з яким він взаємодіє. Водночас, під час простої залежності зв’язок може бути не постійним та не таким явним.
Наприклад, якщо один клас має поле-посилання на інший клас, ви можете відобразити цей зв’язок асоціацією. Цей зв’язок постійний, бо один об’єкт завжди може достукатися до іншого через це поле. Причому, роль поля може відігравати і метод, який повертає об’єкти певного класу.
Щоб остаточно зрозуміти різницю між асоціацією та залежністю, давайте подивимося на комбінований приклад. Уявіть, що в нас є клас Професор:
class Professor isfield Student student
// ...
method teach(Course c) is
// ...
this.student.remember(c.getKnowledge())
Зверніть увагу на метод навчити, що приймає аргумент класу Курс, який далі використовується в тілі методу. Якщо метод отриматиЗнання класу Курс змінить назву, чи в ньому з’являться якісь обов’язкові параметри, чи ще щось — наш код зламається. Це — залежність.
Тепер подивіться на поле студент та на те, як це поле використовується в методі навчити. Ми можемо точно сказати, що клас Студент для професора також є залежністю, бо якщо метод запам'ятати змінить назву, то код професора теж зламається. Але завдяки тому, що значення поля студент доступне для професора завжди, з будь-якого методу, клас Студент — це не просто залежність, але ще й а асоціація.
АгрегаціяАгрегація в UML-діаграмах. Кафедра містить професорів.
Агрегація — це спеціалізований різновид асоціації, що описує зв’язки один-до-багатьох, багато-до-багатьох, частина-ціле між декількома об’єктами.
Зазвичай під час агрегації один об’єкт містить інші, тобто виступає контейнером або колекцією. Тут контейнер не керує життєвим циклом компонентів і компоненти цілком можуть існувати окремо від контейнера.
В UML агрегація позначається лінією зі стрілкою на одному кінці та порожнім ромбом на іншому. Ромб спрямований в бік контейнера, а стрілка — в сторону компонента.
Пам’ятайте, що хоча ми
Увага!
Сайт зберігає кукі вашого браузера. Ви зможете в будь-який момент зробити закладку та продовжити читання книги «Занурення в патерни проектування, Олександр Швець», після закриття браузера.