Kompozicija (projektni uzorak)

S Vikipedije, slobodne enciklopedije

Kompozicija ili Sastav (engl. Composite) je objektno-orijentisani projektni uzorak. Pripada kategoriji objektnih uzoraka strukture.[1] Komponuje objekte u strukturu stabla (hijerarhija celina-deo) i omogućava klijentima da uniformno tretiraju individualne objekte i njihove kompozicije.[1] To se postiže time što se jasno definišu delovi, dok se celine (sastavi) predastavljaju kao delovi, ali imaju ulogu kontejnera tih delova.[2]

Česte upotrebe[uredi | uredi izvor]

Sastav ima veliku primenu kada je potrebno predstavljati hijerarhije celina-deo, što se postiže formiranjem strukture u obliku stabla.[1][2][3] Posebno je koristan kada je potrebno da korisnici ignorišu razlike između celina i delova, odnosno da ih tretiraju uniformno,[1] čime se korisničke klase podjednostavljuju i olakšavaju izmene, testiranja i nadogradnje.[2]

Učesnici[uredi | uredi izvor]

Postoje četiri učesnika za ovaj projektni uzorak.[1][2][3]

Komponenta[uredi | uredi izvor]

Deklariše zajedničko ponašanje za sve čvorove objektnog stabla. To znači da deklariše zajednički interfejs, ali moguće je deklarisati ili implementirati i pristup deci, kao i roditeljima, ako ih komponenta ima.[1]

List[uredi | uredi izvor]

Implementira ponašanje komponente i predstavlja primitivan objekat u kompoziciji.[1] On je zapravo list objektnog stabla što znači da nema decu.[1]

Sastav (Kompozicija)[uredi | uredi izvor]

Predstavlja objekat koji implementira onaj deo interfejsa za komponente, koji je vezan za decu, jer se ne radi o listu.[1] Sadrži decu komponente, što znači da je moguće i da jedan sastav bude dete drugog sastava.[1]

Korisnik[uredi | uredi izvor]

Preko interfejsa komponente, manipuliše objektima stabla.[1]

Dijagram klasa[uredi | uredi izvor]

Dijagram klasa projektnog uzorka Kompozicija, kao i primer objektnog stabla koje se može formirati.[2]

Dijagram klasa i primer objektnog stabla za projektni uzorak kompozicija se nalazi na slici desno. Prikazan je preko Objedinjenog jezika za modeliranje.

Prednosti i mane[uredi | uredi izvor]

Kao što je već rečeno, korišćenje ovog projektnog uzorka podjednostavljuje klase korisnika, i omogućava lako dodavanje novih komponenata što uključuje i nove sastave, ne samo čvorove.[1][2] Zbog toga je moguća dinamična izgradnja i menjanje kompleksnih struktura u vreme prevođenja.[2] Ipak, mogući problem sa sastavom jeste upravo u komponenti - teže je onemogućiti dodavanje određenih komponenata stablu, koje ne želimo da vidimo u njemu.[1] Takođe, jedan od mogućih problema delimično vezan za prethodni jeste vezan za pojavu u implementaciji da se može doći do oblika Component.addComponent() kada je Component zapravo list, što predstavlja grešku, jer ne želimo listu da dodajemo decu.[3]

Implementacija[uredi | uredi izvor]

Prilikom implementacije ovog projektnog uzorka, treba voditi računa mnogim stvarima, pogotovu onih koji se tiču stabla kao takvog. Treba implementirati operacije vezane za decu ili, opciono i roditelje, ali voditi računa prilikom slučajeva kada se određene komponente mogu deliti između drugih komponenata. Takođe, treba težiti ka maksimalnom interfejsu za komponentu - poželjno je da klijent bude rasterećen toga da li koristi sastav ili list. Zbog toga treba što više operacija deklarisati u interfejsu za komponentu. Prilikom odabira strukture za komponente da bi skladištile decu, moguće je koristiti veoma raznovrsne strukture - od ulančanih listi, preko stabala, nizova i heš tabela.[1]

Ispod je dat primer implementacije graditelja na programskom jeziku Java, preuzet sa sajta koji se može naći na spoljašnjim linkovima.[2] Klase su, naravno, posebni fajlovi i potrebno je uključiti odgovarajuće pakete, ali su ovde prikazani na jednom mestu.

//Klasa koja predstavlja Komponentu objektnog stabla
public abstract class Component { 
      private String name;
      public Component(String name) { 
          this.name = name;
      } 
      public abstract String operation();     
      public String getName() { 
          return name;
      } 
      //Default implementacija za operacije koje barataju decom
      public boolean add(Component child) {  //Po default-u, vraca false
          return false;
      } 
      public Iterator<Component> iterator() {  // null iterator
          return Collections.<Component>emptyIterator();
      } 
} 

//Klasa koja predstavlja List
public class Leaf extends Component { 
      public Leaf(String name) { 
          super(name);
      } 
      public String operation() { 
          return getName();
      } 
} 

//Klasa koja predstavlja Kompoziciju
public class Composite extends Component { 
      private List<Component> children = new ArrayList<Component>();
     
      public Composite(String name) { 
          super(name);
      }

      public String operation() { 
          Iterator<Component> it = children.iterator();
          String str = getName();
          Component child;
          while (it.hasNext()) { 
              child = it.next();
              str += child.operation();
          } 
          return str;
      } 

      //Treba "pregaziti" (override) default operacije
      @Override
      public boolean add(Component child) { 
          return children.add(child);
      } 
      @Override
      public Iterator<Component> iterator() { 
          return children.iterator();
      } 
}

Literatura[uredi | uredi izvor]

Reference[uredi | uredi izvor]

  1. ^ a b v g d đ e ž z i j k l lj Johnson, Ralph; Gamma, Erich; Vlissides, John; Helm, Richard (1995). Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley. str. 163-173. 
  2. ^ a b v g d đ e ž „Composite”. w3sDesign. Pristupljeno 04. 01. 2019. 
  3. ^ a b v „Composite”. JavaWorld from IDG. Arhivirano iz originala 05. 01. 2019. g. Pristupljeno 04. 01. 2019. 

Spoljašnje veze[uredi | uredi izvor]