Összetétel programtervezési minta
A számítógépes programozásban az összetétel programtervezési minta vagy összetétel tervezési minta  egy strukturális programtervezési minta. Az összetétel minta az írja le, hogy az objektumok egy csoportját ugyanúgy kell kezelni, mint egy adott objektum példányait külön-külön. Az összetétel itt arra utal, hogy fa struktúrába szervezzünk objektumokat így reprezentálva a rész-egész hierarchiákat. Az összetétel minta lehetővé teszi, hogy a kliensek az önálló objektumokat és összetételeket egységes módon kezeljék.

Motiváció 
Amikor fa struktúrájú adatokkal foglalkozunk, a fejlesztőnek gyakran különbséget kell tudni tennie a levél elemeket az egyéb csomópontoktól. Ez a kódot még komplexebbé és hibára hajlamossá teszi. A megoldás egy interfész, amely lehetővé teszi a komplex és primitív objektumok egységes kezelését. Az objektumorientált programozásban az összetétel egy objektum tervezési mód, hasonló objektumok 1 vagy több kapcsolata, mindegyik hasonló funkcionalitással ellátva. Ezt úgy hívják, hogy "has-a" kapcsolat objektumok között. A kulcs fogalom az, hogy hogyan lehet manipulálni az objektum egy példányát ugyanúgy, mintha az objektum egy egész csoportját manipulálnánk. Azoknak a műveleteknek, melyeket végre lehet hajtani az összes összetett objektumon gyakran van egy legkisebb közös nevező kapcsolata. Például  ha a képernyőn egy rendszert definiálunk csoportosított alakzatok képeihez, hasznos lenne, ha definiálnánk átméretezését az alakzatok egy csoportjára, úgy hogy ugyanaz a hatásuk (bizonyos értelemben) legyen mintha csak egy alakzatot kellett volna átméretezni.

Használata 
Az összetételt akkor célszerű használni, ha a kliensek figyelmen kívül hagyják a különbséget az objektumok összetétele és az önálló objektumok között. Ha fejlesztők úgy találják, hogy több objektumot akarnak azonos módon használni és gyakran van majdnem azonos kódjuk az egyes elemek kezelésére, akkor az összetétel egy jó választás; kevésbé komplex ebben az esetben kezelni az egyszerű és összetett objektumokat homogén módon.

Struktúra

Komponens
 absztrakció az összes összetevőhöz, beleértve az összetettet is
 az objektumok számára meghatározza az interfészt az összetételben
 (nem kötelező) meghatározza az interfészt egy komponens szülőjének eléréséhez a rekurzív struktúrában, és megvalósítja azt, amennyiben szükséges

Levél elem
 reprezentálja a levél objektumokat az összetételben
 megvalósítja az összes komponens metódust

Összetétel
 reprezentál egy összetett komponenst (gyerekekkel rendelkező komponens)
 megvalósítja a gyerekek kezeléséhez szükséges metódusokat
 megvalósítja az összes komponens metódust, általában  a gyerekekhez való delegálással

Variációk 
Mint ahogy azt leírtuk a tervezési mintákban a minta szintén magába foglalja a gyerek kezeléséhez szükséges metódusokat a fő komponens interfészében, nem csak az összetétel alosztályaiban. Újabb leírásokban néha kihagyják ezeket a metódusokat.

Példák 
A következő példa Java nyelven íródott, amely egy grafikus osztályt implementál, amely lehet egy ellipszis vagy a más grafikus elemek összetétele. Minden grafika nyomtatható. A Backus-Naur-formával:
        Graphic = ellipse | GraphicList
        GraphicList = empty | Graphic GraphicList

Ki lehet terjeszteni, hogy számos más alakot (négyzet stb.) ill. metódust (forgatást stb.) implementáljon.

Java 
/** "Component" */
interface Graphic {

    //Prints the graphic.
    public void print();
}

/** "Composite" */
import java.util.List;
import java.util.ArrayList;
class CompositeGraphic implements Graphic {

    //Collection of child graphics.
    private List<Graphic> childGraphics = new ArrayList<Graphic>();

    //Prints the graphic.
    public void print() {
        for (Graphic graphic : childGraphics) {
            graphic.print();
        }
    }

    //Adds the graphic to the composition.
    public void add(Graphic graphic) {
        childGraphics.add(graphic);
    }

    //Removes the graphic from the composition.
    public void remove(Graphic graphic) {
        childGraphics.remove(graphic);
    }
}

/** "Leaf" */
class Ellipse implements Graphic {

    //Prints the graphic.
    public void print() {
        System.out.println("Ellipse");
    }
}

/** Client */
public class Program {

    public static void main(String[] args) {
        //Initialize four ellipses
        Ellipse ellipse1 = new Ellipse();
        Ellipse ellipse2 = new Ellipse();
        Ellipse ellipse3 = new Ellipse();
        Ellipse ellipse4 = new Ellipse();

        //Initialize three composite graphics
        CompositeGraphic graphic = new CompositeGraphic();
        CompositeGraphic graphic1 = new CompositeGraphic();
        CompositeGraphic graphic2 = new CompositeGraphic();

        //Composes the graphics
        graphic1.add(ellipse1);
        graphic1.add(ellipse2);
        graphic1.add(ellipse3);

        graphic2.add(ellipse4);

        graphic.add(graphic1);
        graphic.add(graphic2);

        //Prints the complete graphic (four times the string "Ellipse").
        graphic.print();
    }
}

C# 
A következő grafikai példa C#-en íródott.
namespace CompositePattern
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    //Client
    class Program
    {
        static void Main(string[] args)
        {
            // initialize variables
            var compositeGraphic = new CompositeGraphic();
            var compositeGraphic1 = new CompositeGraphic();
            var compositeGraphic2 = new CompositeGraphic();

            //Add 1 Graphic to compositeGraphic1
            compositeGraphic1.Add(new Ellipse());

            //Add 2 Graphic to compositeGraphic2
            compositeGraphic2.AddRange(new Ellipse(), 
                new Ellipse());

            /*Add 1 Graphic, compositeGraphic1, and 
              compositeGraphic2 to compositeGraphic */
            compositeGraphic.AddRange(new Ellipse(), 
                compositeGraphic1, 
                compositeGraphic2);

            /*Prints the complete graphic 
            (four times the string "Ellipse").*/
            compositeGraphic.Print();
            Console.ReadLine();
        }
    }
    //Component
    public interface IGraphic
    {
        void Print();
    }
    //Leaf
    public class Ellipse : IGraphic
    {
        //Prints the graphic
        public void Print()
        {
            Console.WriteLine("Ellipse");
        }
    }
    //Composite
    public class CompositeGraphic : IGraphic
    {
        //Collection of Graphics.
        private readonly List<IGraphic> graphics;

        //Constructor 
        public CompositeGraphic()
        {
            //initialize generic Collection(Composition)
            graphics = new List<IGraphic>();
        }
        //Adds the graphic to the composition
        public void Add(IGraphic graphic)
        {
            graphics.Add(graphic);
        }
        //Adds multiple graphics to the composition
        public void AddRange(params IGraphic[] graphic)
        {
            graphics.AddRange(graphic);
        }
        //Removes the graphic from the composition
        public void Delete(IGraphic graphic)
        {
            graphics.Remove(graphic);
        }
        //Prints the graphic.
        public void Print()
        {
            foreach (var childGraphic in graphics)
            {
                childGraphic.Print();
            }
        }
    }
}

Egy egyszerű példa 
    //IVSR: Composite example
    /// Treats elements as composition of one or more elements, so that components 
    /// can be separated between one another
    public interface IComposite
    {
        void CompositeMethod();
    }

    public class LeafComposite :IComposite 
    {

        #region IComposite Members

        public void CompositeMethod()
        {
            //To Do something
        }

        #endregion
    }

    /// Elements from IComposite can be separated from others 
    public class NormalComposite : IComposite
    {

        #region IComposite Members

        public void CompositeMethod()
        {
            //To Do Something
        }

        #endregion

        public void DoSomethingMore()
        {
            //Do Something more .
        }
    }

Kapcsolódó szócikkek
Perl Tervezési minták könyv
Mixin
Demeter törvénye

További információk 

Composite pattern description from the Portland Pattern Repository
Composite pattern in UML and in LePUS3, a formal modelling language
Class::Delegation on CPAN
"The End of Inheritance: Automatic Run-time Interface Building for Aggregated Objects" by Paul Baranowski
PerfectJPattern Open Source Project, Provides componentized implementation of the Composite Pattern in Java
 A persistent Java-based implementation
Composite Design Pattern
Composite Design Pattern implementation example

Jegyzetek

Fordítás

Programtervezési minták
Java-kódpéldák
C Sharp-kódpéldák
A számítógépes programozásban az összetétel programtervezési minta vagy összetétel tervezési minta egy strukturális programtervezési minta . Az összetétel minta az írja le , hogy az objektumok egy csoportját ugyanúgy kell kezelni , mint egy adott objektum példányait külön-külön . Az összetétel itt arra utal , hogy fa struktúrába szervezzünk objektumokat így reprezentálva a rész-egész hierarchiákat . Az összetétel minta lehetővé teszi , hogy a kliensek az önálló objektumokat és összetételeket egységes módon kezeljék . Motiváció Amikor fa struktúrájú adatokkal foglalkozunk , a fejlesztőnek gyakran különbséget kell tudni tennie a levél elemeket az egyéb csomópontoktól . Ez a kódot még komplexebbé és hibára hajlamossá teszi . A megoldás egy interfész , amely lehetővé teszi a komplex és primitív objektumok egységes kezelését . Az objektumorientált programozásban az összetétel egy objektum tervezési mód , hasonló objektumokvagy több kapcsolata , mindegyik hasonló funkcionalitással ellátva . Ezt úgy hívják , hogy " has-a " kapcsolat objektumok között . A kulcs fogalom az , hogy hogyan lehet manipulálni az objektum egy példányát ugyanúgy , mintha az objektum egy egész csoportját manipulálnánk . Azoknak a műveleteknek , melyeket végre lehet hajtani az összes összetett objektumon gyakran van egy legkisebb közös nevező kapcsolata . Például ha a képernyőn egy rendszert definiálunk csoportosított alakzatok képeihez , hasznos lenne , ha definiálnánk átméretezését az alakzatok egy csoportjára , úgy hogy ugyanaz a hatásuk ( bizonyos értelemben ) legyen mintha csak egy alakzatot kellett volna átméretezni . Használata Az összetételt akkor célszerű használni , ha a kliensek figyelmen kívül hagyják a különbséget az objektumok összetétele és az önálló objektumok között . Ha fejlesztők úgy találják , hogy több objektumot akarnak azonos módon használni és gyakran van majdnem azonos kódjuk az egyes elemek kezelésére , akkor az összetétel egy jó választás ; kevésbé komplex ebben az esetben kezelni az egyszerű és összetett objektumokat homogén módon . Struktúra Komponens absztrakció az összes összetevőhöz , beleértve az összetettet is az objektumok számára meghatározza az interfészt az összetételben ( nem kötelező ) meghatározza az interfészt egy komponens szülőjének eléréséhez a rekurzív struktúrában , és megvalósítja azt , amennyiben szükséges Levél elem reprezentálja a levél objektumokat az összetételben megvalósítja az összes komponens metódust Összetétel reprezentál egy összetett komponenst ( gyerekekkel rendelkező komponens ) megvalósítja a gyerekek kezeléséhez szükséges metódusokat megvalósítja az összes komponens metódust , általában a gyerekekhez való delegálással Variációk Mint ahogy azt leírtuk a tervezési mintákban a minta szintén magába foglalja a gyerek kezeléséhez szükséges metódusokat a fő komponens interfészében , nem csak az összetétel alosztályaiban . Újabb leírásokban néha kihagyják ezeket a metódusokat . Példák A következő példa Java nyelven íródott , amely egy grafikus osztályt implementál , amely lehet egy ellipszis vagy a más grafikus elemek összetétele . Minden grafika nyomtatható . A Backus-Naur-formával : Graphic = ellipse | GraphicList GraphicList = empty | Graphic GraphicList Ki lehet terjeszteni , hogy számos más alakot ( négyzet stb. ) ill. metódust ( forgatást stb. ) implementáljon . Java / * * " Component " * / interface Graphic { //Prints the graphic . public void print ( ) ; } / * * " Composite " * / import java.util.List ; import java.util.ArrayList ; class CompositeGraphic implements Graphic { / /Collection of child graphics . private List<Graphic> childGraphics = new ArrayList<Graphic> ( ) ; //Prints the graphic . public void print ( ) { for ( Graphic graphic \ : childGraphics ) { graphic.print ( ) ; } } //Adds the graphic to the composition . public void add( Graphic graphic ) { childGraphics.add ( graphic ) ; } //Removes the graphic from the composition . public void remove( Graphic graphic ) { childGraphics.remove ( graphic ) ; } } / * * " Leaf " * / class Ellipse implements Graphic { //Prints the graphic . public void print ( ) { System.out.println ( " Ellipse " ) ; } } / * * Client * / public class Program { public static void main( String [ ] args ) { //Initialize four ellipses Ellipse ellipse1 = new Ellipse ( ) ; Ellipse ellipse2 = new Ellipse ( ) ; Ellipse ellipse3 = new Ellipse ( ) ; Ellipse ellipse4 = new Ellipse ( ) ; //Initialize three composite graphics CompositeGraphic graphic = new CompositeGraphic ( ) ; CompositeGraphic graphic1 = new CompositeGraphic ( ) ; CompositeGraphic graphic2 = new CompositeGraphic ( ) ; / /Composes the graphics graphic1.add ( ellipse1 ) ; graphic1.add ( ellipse2 ) ; graphic1.add ( ellipse3 ) ; graphic2.add ( ellipse4 ) ; graphic.add ( graphic1 ) ; graphic.add ( graphic2) ; //Prints the complete graphic ( four times the string " Ellipse " ) . graphic.print ( ) ; } } C # A következő grafikai példa C#-en íródott. namespace CompositePattern { using System ; using System.Collections.Generic ; using System.Linq ; / /Client class Program { static void Main( string [ ] args ) { / / initialize variables var compositeGraphic = new CompositeGraphic ( ) ; var compositeGraphic1 = new CompositeGraphic ( ) ; var compositeGraphic2 = new CompositeGraphic ( ) ; / /AddGraphic to compositeGraphic1 compositeGraphic1.Add ( new Ellipse ( ) ) ; / /AddGraphic to compositeGraphic2 compositeGraphic2.AddRange ( new Ellipse ( ) , new Ellipse ( ) ) ; / *AddGraphic , compositeGraphic1 , and compositeGraphic2 to compositeGraphic * / compositeGraphic.AddRange ( new Ellipse ( ) , compositeGraphic1 , compositeGraphic2 ) ; /*Prints the complete graphic ( four times the string " Ellipse " ) . * / compositeGraphic.Print ( ) ; Console.ReadLine ( ) ; } } / /Component public interface IGraphic { void Print ( ) ; } //Leaf public class Ellipse \ : IGraphic { //Prints the graphic public void Print ( ) { Console.WriteLine ( " Ellipse " ) ; } } / /Composite public class CompositeGraphic \ : IGraphic { / /Collection of Graphics . private readonly List<IGraphic> graphics ; / /Constructor public CompositeGraphic ( ) { //initialize generic Collection ( Composition ) graphics = new List<IGraphic> ( ) ; } //Adds the graphic to the composition public void Add( IGraphic graphic ) { graphics.Add ( graphic ) ; } //Adds multiple graphics to the composition public void AddRange( params IGraphic [ ] graphic ) { graphics.AddRange ( graphic ) ; } //Removes the graphic from the composition public void Delete( IGraphic graphic ) { graphics.Remove ( graphic ) ; } //Prints the graphic . public void Print ( ) { foreach ( var childGraphic in graphics ) { childGraphic.Print ( ) ; } } } } Egy egyszerű példa //IVSR: Composite example / / / Treats elements as composition of one or more elements , so that components / / / can be separated between one another public interface IComposite { void CompositeMethod ( ) ; } public class LeafComposite\: IComposite { # region IComposite Members public void CompositeMethod ( ) { //To Do something } # endregion } / / / Elements from IComposite can be separated from others public class NormalComposite \ : IComposite { # region IComposite Members public void CompositeMethod ( ) { //To Do Something } # endregion public void DoSomethingMore ( ) { //Do Something more \ . } } Kapcsolódó szócikkek Perl Tervezési minták könyv Mixin Demeter törvénye További információk Composite pattern description from the Portland Pattern Repository Composite pattern in UML and in LePUS3 , a formal modelling language Class : : Delegation on CPAN " The End of Inheritance : Automatic Run-time Interface Building for Aggregated Objects " by Paul Baranowski PerfectJPattern Open Source Project , Provides componentized implementation of the Composite Pattern in Java A persistent Java-based implementation Composite Design Pattern Composite Design Pattern implementation example Jegyzetek Fordítás Programtervezési minták Java-kódpéldák C Sharp-kódpéldák