Композиція - це коли клас пропонує певну функціональність, інстанціюючи (можливо, внутрішній) клас, який вже реалізує цю функціональність, а не успадковуючи цей клас.
Так, наприклад, якщо у вас є клас, який моделює судно, і вам зараз кажуть, що ваш корабель повинен запропонувати вертоліт, не природним є виведення вашого корабля з вертольота, (так!) Замість цього, ви повинні мати ваш корабель містить клас вертольотів і виставляє його деяким Ship.getHelipad()
методом.
У роки (десять років тому) люди звикли сприймати спадщину як швидкий і простий спосіб об'єднання функціональних можливостей, тому було багато прикладів "судна, що успадковували з вертолітної майданчика", які, звичайно, були дуже кульгавими.
Але вираз «Склади прихильності над успадкуванням» був ретельно сформульований, щоб зрозуміти, що це лише пропозиція, а не правило. Автор видання був досить обережним, щоб утриматися від того, щоб сказати щось на кшталт "ти ніколи не будеш використовувати спадщину, лише склад". Це, в основному, доводить до відома спільноти інженерних програмних послуг той факт, що надбання надмірно використовувалося, в той час як у багатьох випадках композиція створює більш чіткі, елегантні та бездоганний дизайн, ніж спадкування.
Отже, по суті, висловлювання «Улюблений склад над спадщиною» говорить про те, що кожного разу, коли ви зіткнетесь із «спадкувати чи складати»? Питання, вам варто задуматися над тим, яка стратегія є найбільш підходящою, і що найбільш шанси на те, що найбільш підходяща стратегія виявиться складом, а не спадщиною.
Але оскільки це не правило, слід також пам’ятати, що є багато випадків, коли успадкування є більш природним. Якщо ви використовуєте склад там, де вам слід було скористатися спадщиною, на ваш код потрапить багато зла.
Щоб повернутися до прикладу корабля, якщо вашому кораблю потрібно запропонувати інтерфейс для взаємодії з a FloatingMachine
, то більш природним є його отримання від абстрактного FloatingMachine
класу, який, можливо, в свою чергу може бути похідним від іншого абстрактного Machine
класу.
Ось головне правило для відповіді на питання про склад та спадщину:
Чи є у мого класу відношення «є» до інтерфейсу, який він повинен виставити? Якщо так, використовуйте спадщину. Якщо ні, використовуйте склад.
Корабель "- це" плаваюча машина, а плаваюча машина "-" машина. Отже, успадкування цілком чудово для них. Але корабель - це, звичайно, не вертоліт. Тож краще скласти функціональність вертольота.