Kompositmønster - Composite pattern

I software engineering er det sammensatte mønster et opdelende designmønster . Det sammensatte mønster beskriver en gruppe objekter, der behandles på samme måde som en enkelt forekomst af den samme objekttype. Hensigten med en sammensat er at "komponere" objekter i træstrukturer for at repræsentere delhele hierarkier. Implementering af det sammensatte mønster lader klienter behandle individuelle objekter og sammensætninger ensartet.

Oversigt

Det sammensatte designmønster er et af de tre velkendte GoF-designmønstre, der beskriver, hvordan man løser tilbagevendende designproblemer til at designe fleksibel og genanvendelig objektorienteret software, det vil sige objekter, der er lettere at implementere, ændre, teste og genbruge.

Hvilke problemer kan det sammensatte designmønster løse?

  • Et del-hele hierarki bør repræsenteres, så klienter kan behandle dele og hele objekter ensartet.
  • Et del-hele hierarki bør repræsenteres som træstruktur.

Ved definition af (1) Partobjekter og (2) Wholeobjekter, der fungerer som containere til Partobjekter, skal klienter behandle dem separat, hvilket komplicerer klientkode.

Hvilken løsning beskriver det sammensatte designmønster?

  • Definer en samlet Componentgrænseflade for både del ( Leaf) objekter og hele ( Composite) objekter.
  • Individuelle Leafobjekter implementerer Componentgrænsefladen direkte, og Compositeobjekter videresender anmodninger til deres underordnede komponenter.

Dette gør det muligt for klienter at arbejde gennem Componentgrænsefladen for at behandle Leafog Compositeobjekter ensartet: Leafobjekter udfører en anmodning direkte, og Compositeobjekter videresender anmodningen til deres underordnede komponenter rekursivt nedad i træstrukturen. Dette gør klientklasser lettere at implementere, ændre, teste og genbruge.

Se også UML -klassen og objektdiagrammet herunder.

Motivering

Når man beskæftiger sig med træstrukturerede data, er programmører ofte nødt til at skelne mellem en bladknude og en gren. Dette gør koden mere kompleks og derfor mere tilbøjelig til fejl. Løsningen er en grænseflade, der gør det muligt at behandle komplekse og primitive objekter ensartet. I objektorienteret programmering er en komposit et objekt designet som en sammensætning af et eller flere lignende objekter, der alle udviser lignende funktionalitet. Dette er kendt som et " har-et " forhold mellem objekter. Nøglebegrebet er, at du kan manipulere en enkelt forekomst af objektet, ligesom du ville manipulere en gruppe af dem. De operationer, du kan udføre på alle de sammensatte objekter, har ofte et mindst fællesnævnerforhold . For eksempel, hvis du definerer et system til at skildre grupperede former på en skærm, ville det være nyttigt at definere størrelsen på en gruppe af former for at have den samme effekt (i en vis forstand) som at ændre størrelsen på en enkelt form.

Hvornår skal man bruge

Composite bør bruges, når klienter ignorerer forskellen mellem sammensætninger af objekter og individuelle objekter. Hvis programmører finder ud af, at de bruger flere objekter på samme måde og ofte har næsten identisk kode til at håndtere hver af dem, så er komposit et godt valg; det er mindre komplekst i denne situation at behandle primitiver og kompositter som homogene.

Struktur

UML klasse og objektdiagram

En prøve UML klasse og objektdiagram for det sammensatte designmønster.

I den ovennævnte UML klasse diagram , det Clientbetyder klasse ikke henvise til Leafog Compositeklasser direkte (separat). I stedet Clienthenviser den til den fælles Componentgrænseflade og kan behandles Leafog Compositeensartet.
Den Leafklasse har ingen børn og redskaber den Componentgrænseflade direkte.
Den Compositeklasse opretholder en beholder med underordnede Componentobjekter ( children) og videresender anmodninger til disse children( for each child in children: child.operation()).

Objektsamarbejdsdiagrammet viser interaktioner i løbetid: I dette eksempel Clientsender objektet en anmodning til Compositeobjektet på øverste niveau (af typen Component) i træstrukturen. Anmodningen videresendes til (udføres på) alle underordnede Componentobjekter ( Leafog Compositeobjekter) nedad i træstrukturen.

Definere børnerelaterede operationer
Definere børnerelaterede operationer i det sammensatte designmønster.

Der er to designvarianter til at definere og implementere børnerelaterede operationer som tilføjelse/fjernelse af en underordnet komponent til/fra containeren ( add(child)/remove(child)) og adgang til en underordnet komponent ( getChild()):

  • Design for ensartethed: Børnerelaterede operationer er defineret i Componentgrænsefladen. Dette gør det muligt for klienter at behandle Leafog Compositegenstande ensartet. Men typesikkerhed går tabt, fordi klienter kan udføre børnerelaterede operationer på Leafobjekter.
  • Design til typesikkerhed: Børnerelaterede operationer defineres kun i Compositeklassen. Klienter skal behandle Leafog Compositegenstande anderledes. Men typesikkerhed opnås, fordi klienter ikke kan udføre børnelaterede operationer på Leafobjekter.

Det sammensatte designmønster understreger ensartethed over typesikkerhed .

UML klassediagram

Kompositmønster i UML .
Komponent
  • er abstraktionen for alle komponenter, herunder sammensatte
  • erklærer grænsefladen for objekter i sammensætningen
  • (valgfrit) definerer en grænseflade til adgang til en komponents forælder i den rekursive struktur og implementerer den, hvis det er passende
Blad
  • repræsenterer bladobjekter i sammensætningen
  • implementerer alle komponentmetoder
Sammensatte
  • repræsenterer en sammensat komponent (komponent der får børn)
  • implementerer metoder til manipulation af børn
  • implementerer alle komponentmetoder, generelt ved at delegere dem til sine børn
Kompositmønster i LePUS3 .

Variation

Som det er beskrevet i Design Patterns , involverer mønsteret også at inkludere børnemanipuleringsmetoder i hovedkomponentgrænsefladen, ikke kun den sammensatte underklasse. Nyere beskrivelser udelader undertiden disse metoder.

Eksempel

Følgende eksempel, skrevet i Java , implementerer en grafisk klasse, som enten kan være en ellipse eller en sammensætning af flere grafik. Hver grafik kan udskrives. I Backus-Naur-form ,

       Graphic ::= ellipse | GraphicList
       GraphicList ::= empty | Graphic GraphicList

Det kan udvides til at implementere flere andre former (rektangel osv.) Og metoder ( oversætte osv.).

Java

import java.util.List;
import java.util.ArrayList;

/** "Component" */
interface Graphic {
    //Prints the graphic.
    public void print();
}

/** "Composite" */
class CompositeGraphic implements Graphic {
    //Collection of child graphics.
    private final List<Graphic> childGraphics = new ArrayList<>();

    //Adds the graphic to the composition.
    public void add(Graphic graphic) {
        childGraphics.add(graphic);
    }
    
    //Prints the graphic.
    @Override
    public void print() {
        for (Graphic graphic : childGraphics) {
            graphic.print();  //Delegation
        }
    }
}

/** "Leaf" */
class Ellipse implements Graphic {
    //Prints the graphic.
    @Override
    public void print() {
        System.out.println("Ellipse");
    }
}

/** Client */
class CompositeDemo {
    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();

        //Creates two composites containing the ellipses
        CompositeGraphic compositGraphic2 = new CompositeGraphic();
        compositGraphic2.add(ellipse1);
        compositGraphic2.add(ellipse2);
        compositGraphic2.add(ellipse3);
        
        CompositeGraphic compositGraphic3 = new CompositeGraphic();
        compositGraphic3.add(ellipse4);
        
        //Create another graphics that contains two graphics
        CompositeGraphic compositGraphic = new CompositeGraphic();
        compositGraphic.add(compositGraphic2);
        compositGraphic.add(compositGraphic3);

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

Se også

Referencer

eksterne links