|
|||||||
АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомДругоеЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
Механізми повторного використанняНеобхідно підібрати підходящі об’єкти, віднести їх до різних класів, дотримуючи розумного ступеня деталізації, визначити інтерфейси класів й ієрархію спадкування встановити суттєві стосунки між класами. Дизайн повинен, з одного боку, відповідати розв’язуваному завданню, з іншого боку – бути загальним, щоб вдалося врахувати всі вимоги, які можуть виникнути в майбутньому. Механізми повторного використання [7,8]: - спадкування – дозволяє визначити реалізацію одного класу в термінах іншого; - композиція – це альтернатива спадкуванню класу. У цьому випадку нову, більше складну функціональність одержуємо шляхом об’єднання або композиції об’єктів. Для композиції потрібно, щоб поєднувані об’єкти мали чітко певні інтерфейси; - делегування – передача функцій, повноважень на певний час із збереженням у делегуючого суб’єкта права повернути їх до власного виконання. Водночас делегуючий суб’єкт набуває право контролю за станом і наслідками виконання делегованих функцій, повноважень; він може також фінансувати із власних коштів їх здійснення, передавати у користування необхідні для цього майнові об’єкти. І в спадкуванні, і в композиції є переваги й недоліки. Спадкування класу визначається статично на етапі компіляції, його простіше використати, оскільки воно прямо підтримано мовою програмування. У випадку спадкування класів спрощується також завдання модифікації існуючої реалізації. Якщо підклас заміщає лише деякі операції, то можуть виявитися порушеними й інші успадковані операції, оскільки не виключено, що вони викликають заміщення. Але в спадкуванні класу є й мінуси. По-перше, не можна змінити успадковану від батька реалізацію під час виконання програми, оскільки саме спадкування фіксоване на етапі компіляції. По-друге, батьківський клас нерідко хоча б частково визначає фізичне представлення своїх підкласів. Оскільки підкласу доступні деталі реалізації батьківського класу, то часто говорять, що спадкування порушує інкапсуляцію. Реалізації підкласу й батьківського класу настільки тісно зв’язані, що будь-які зміни останньої вимагають змінювати й реалізацію підкласу. Залежність від реалізації може викликати проблеми при спробі повторного використання підкласу. Якщо хоча б один аспект успадкованої реалізації непридатний для нової ПрО, то доводиться переписувати батьківський клас або заміняти його чимось більше підходящим. Така залежність обмежує гнучкість і можливості повторного використання. Із проблемою можна впоратися, якщо успадковувати тільки абстрактні класи, оскільки в них звичайно зовсім немає реалізації або вона мінімальна. Композиція об’єктів визначається динамічно під час виконання за рахунок того, що об’єкти одержують посилання на інші об’єкти. Композицію можна застосувати, якщо об’єкти дотримують інтерфейсів один одного. Для цього, у свою чергу, потрібно ретельно проектувати інтерфейси так, щоб один об’єкт можна було використати разом із широким спектром інших. Але й виграш великий. Оскільки доступ до об’єктів здійснюється тільки через їхні інтерфейси, не порушуємо інкапсуляцію. Під час виконання програми будь-який об’єкт можна замінити іншим, аби тільки він мав той же тип. Більше того, оскільки при реалізації об’єкта кодуються насамперед його інтерфейси, то залежність від реалізації різко знижується. Композиція об’єктів впливає на дизайн системи й ще в одному аспекті. Віддаючи перевагу композиції об’єктів, а не спадкуванню класів, інкапсулюється кожен клас і дається йому можливість виконувати тільки своє завдання. Класи і їхні ієрархії залишаються невеликими, і ймовірність їхнього розростання до некерованих розмірів невелика. З іншого боку, дизайн, заснований на композиції, буде містити більше об’єктів (хоча число класів, можливо, зменшиться), і поводження системи почне залежати від їхньої взаємодії, тоді як при іншому підході воно було б визначене в одному класі. У новій архітектурі (рис. 2.9) є одна принципова особливість: клас Duck тепер делегує свої аспекти поведінки (замість використання методів, визначених в класі Duck та його субкласах) (рис. 2.10). Ось як це здійснюється: 1. Спочатку до класу Duck додаються 2 змінні типу FlyBehavior або QuackBehavior. Кожний об’єкт на стадії виконання привласнює цим змінним поліморфні значення, які відповідають конкретному типу поведінки. Методи fly() та quack() видаляються з класу Duck (та всіх субкласів), тому що ця поведінка переміщена до класів FlyBehavior або QuackBehavior. В класі Duck методи fly() та quack() замінюються двома аналогічними методами: performFly() та performQuack() (рис. 2.10) [10].
Рис. 2.10. Делегування аспектів поведінки
2. Реалізація performQuack(): { QuackBehavior quackBehavior; // Кожний об’єкт Duck містить посилання на реалізацію інтерфейсу QuackBehavior public void performQuack() { quackBehavior.quack(); // Об’єкт Duck делегує поведінку об’єкта, на який посилається quackBehavior } }
Замість того, що виконувати дії самостійно об’єкт Duck доручає цю роботу об’єкту, на який посилається quackBehavior. 3. Привласнювання значень змінним flyBehavior та quackBehavior. Розглянемо фрагмент класу MallardDuck: public class MallardDuck:Duck { public MallardDuck() { quackBehavior=new Quack(); // MallardDuck використовує клас Quack для виконання дії, так що при виклику performQuack() відповідальність за виконання покладається на об’єкт Quack flyBehavior=new FlyWithWings(); // В якості реалізації FlyBehavior використовується тип FlyWithWings } }
При створенні екземпляру класу MallardDuck конструктор ініціалізує успадковану змінну екземпляра quackBehavior новим екземпляром типу Quack. Теж саме здійснюється і з іншим аспектом поведінки: конструктор MallardDuck ініціалізує змінну flyBehavior екземпляром типу FlyWithWings. На рис. 2.11 показана загальна архітектура для додатку. В ній є все, що можна очікувати: класи качок, які розширюють базовий клас Duck, а також класи поведінки, що реалізують FlyBehavior та QuackBehavior. Зверніть увагу на відношення між класами. Кожна качка містить екземпляри FlyBehavior та QuackBehavior, яким делегуються виконання відповідних операцій. Подібні зв’язки між двома класами означають, що використовується механізм композиції. Поведінка не успадковується, а надається правильно обраним об’єктом. Рис. 2.11. Загальна архітектура програмного забезпечення
Принцип проектування 3 рекомендує віддавати перевагу композиції перед спадкуванням. Системи, створені на основі композиції володіють значно більшою гнучкістю. Вони дозволяють не тільки інкапсулювати сімейства алгоритмів, але і змінювати поведінку під час виконання – за умови, що об’єкт, підключений засобами композиції, реалізує вірний інтерфейс. Контрольні запитання 1. Опишіть загальну концепцію методу аналізу спільності/змінності. 2. Назвіть основні 2 стратегії для роботи з класами. 3. Перерахуйте найпоширеніші негативні явища в програмному коді. 4. Назвіть типові причини перепроектування програмної системи. 5. Назвіть основні принципи ООП. 6. Що таке програмування на рівні реалізації? 7. Що таке програмування на рівні інтерфейсу? 8. Назвіть механізми повторного використання коду. 9. Що таке делегування? 10. Назвіть негативні явища спадкування.
Поиск по сайту: |
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Студалл.Орг (0.005 сек.) |