Compoziție în loc de moștenire

De la Wikipedia, enciclopedia liberă.
Salt la navigare Salt la căutare
Diagrama arată cum zborul și comportamentul sonor al unui animal pot fi concepute într-un mod flexibil prin utilizarea principiului de proiectare a compoziției în loc de moștenire. [1]

Compoziția în loc de moștenire (sau principiul reutilizării compusului) în programarea orientată pe obiecte este principiul conform căruia clasele ar trebui să obțină un comportament polimorf și reutilizarea codului prin compunere (conțin alte clase care implementează funcționalitatea dorită), în loc de prin moștenire (fiind o subclasă) . [2] Adesea acesta este un principiu declarat al POO, cum ar fi în modelele de design influente: „preferă compoziția obiectelor în locul moștenirii clasei”. [3]

Unele limbi, în special Go , folosesc exclusiv acest tip de compoziție.

Cele elementare

O implementare a compoziției în loc de moștenire începe de obicei cu crearea mai multor interfețe care reprezintă comportamentele pe care sistemul trebuie să le prezinte. Utilizarea interfețelor permite acestei tehnici să susțină comportamentul polimorf care este atât de important în programarea orientată pe obiecte. Clasele care implementează interfețele identificate sunt dezvoltate și adăugate la clasele de domeniu ale aplicației după cum este necesar. Astfel, comportamentele sistemului se realizează fără moștenire. În realitate, clasele de domeniu ale aplicației pot fi toate clase de bază, fără moștenire. Implementarea alternativă a comportamentelor sistemului este realizată prin furnizarea unei alte clase care implementează interfața cu comportamentul dorit. Orice clasă de domeniu de aplicație care conține o referință de interfață poate suporta cu ușurință orice implementare a acelei interfețe, iar alegerea poate fi întârziată până la timpul de execuție.

Moştenire

Următorul este un exemplu în C ++ 11 :

 clasa GameObject {
    public :
        virtual ~ GameObject () {}
        actualizare virtuală nulă () {}
        extragere nulă virtuală () {}
        virtuale void ciocnească (obiecte GameObject []) {}
};

clasa Vizibil : public GameObject {
    public :
        void draw () override { / * desenează modelul la poziția acestui obiect * / };
    privat :
        Model * model ;
};

clasa Solid : public GameObject {
    public :
        void collide ( GameObject objects []) override { / * verifică și reacționează la coliziuni cu obiecte * / };
};

clasa Movable : public GameObject {
    public :
        void update () override { / * actualizare poziție * / };
};

Beneficii

Favorizarea compoziției față de moștenire este un principiu de proiectare care oferă proiectantului mai multă flexibilitate, rezultând clase de domenii de aplicații pe termen mai lung și un domeniu de aplicație mai stabil. Cu alte cuvinte, o relație de tip „HA-UN” poate fi mai bună decât una de tip „IS-A”. [1]

Proiectarea inițială este simplificată prin identificarea comportamentelor sistemului în interfețe separate în loc de crearea unei relații ierarhice pentru a distribui comportamente între clasele de domenii ale aplicației cu moștenire. Această abordare poate găzdui mai ușor modificările viitoare ale cerințelor care altfel ar necesita o restructurare completă a claselor de domenii ale aplicației în modelul de moștenire. De asemenea, evită problemele asociate adesea cu modificări relativ minore ale unui model bazat pe moștenire care se întinde pe mai multe generații de clase.

Dezavantaje

Un dezavantaj al utilizării compoziției în loc de moștenire este că toate metodele furnizate de clasele compuse trebuie implementate în clasa derivată, chiar dacă există doar metode de redirecționare . În schimb, moștenirea nu necesită ca toate metodele unei clase de bază să fie re-implementate în cadrul clasei derivate. Mai degrabă, clasa derivată trebuie doar să implementeze ( suprascrie ) metode care au un comportament diferit de metodele clasei de bază. Acest lucru poate necesita un efort de programare semnificativ mai mic dacă clasa de bază conține multe metode care furnizează un comportament implicit și doar câteva dintre ele trebuie să fie suprascrise în clasa derivată.

Acest dezavantaj poate fi evitat prin utilizarea trăsăturii sau a mixinului . Unele limbi, cum ar fi Perl 6, oferă un cuvânt cheie de gestionare pentru a facilita trimiterea metodei. În Java , proiectul Lombok vă permite să implementați delegarea utilizând o singură adnotare @Delegate pe câmp în loc să copiați și să mențineți numele și tipurile tuturor metodelor din câmpul delegat.

Notă

  1. ^ a b Eric Freeman, Elisabeth Freeman, Kathy Sierra și Bert Bates, Head First Design Patterns (broșură), editat de Hendrickson și Mike Loukides, vol. 1, O'Reilly, 2004, p. 23, ISBN 978-0-596-00712-6 .
  2. ^ Kirk Knoernschild, Java Design - Objects, UML și Process: 1.1.5 Composite Reuse Principle (CRP) , Addison-Wesley Inc., 2002. Accesat la 23 mai 2015 .
  3. ^ Erich Gamma, Richard Helm, Ralph Johnson și John Vlissides, Design Patterns , 1994, p. 20.