Sunteți pe pagina 1din 32

Proiectarea aplicațiilor orientate

obiect
J Curs 8 – Composite, decorator
J Acest curs
› Composite
› Decorator
J Composite
› Şablonul Composite compune obiecte în structuri de tip arbore pentru a
reprezenta ierarhii parte-întreg. Şablonul permite clienţilor să trateze
uniform obiecte individuale şi compuneri de obiecte
– Pot fi ignorate diferenţele dintre obiectele compuse şi obiectele elementare
› Compune obiectele intr-o structura arborescenta
› Ofera clientului posibilitatea de a trata obiectele simple si compuse intr-
un mod uniform
› Se utilizeaza acolo unde aplicatia trebuie sa manipuleze o colectie
ierarhica de obiecte primitive si composite.
› Obiectele primitive si composite sunt tratate diferit dar interfata este
aceeasi
› Poate fi parcurs cu un iterator
J Composite - necesitate
› Aplicația trebuie să manipuleze o colecție ierarhică de obiecte
„primitive” și „compozite”. Prelucrarea unui obiect primitiv față de
unul composite se realizează în mod diferit. Nu se dorește
interogarea „tipului” fiecărui obiect înainte de procesare.
J Composite – how to
› Se definește o clasă de bază abstractă (componentă) care
implementează comportamentul ce trebuie exercitat uniform pe toate
obiectele primitive și compuse. Se definesc clasele Primitive și
Compozite ca fiind subclase ale clasei Component. Fiecare obiect
compozit are funcționalitatea ”oferită” doar de tipul abstract
Component.
› Se va utiliza acest șablon de fiecare dată când există componente
care la rândul lor pot avea componente.
› Metodele de gestionare a ”copiilor”: addChild (), removeChild
() ar trebui în mod normal să fie definite în clasa Composite. Totuși
este necesar de a trata uniform primitivele și compozitele motiv
pentru care metode sunt definite în clasa de componente abstracte.
J Composite - structure
› Composite ce conține
componente, fiecare dintre
ele putând fi un composite
› Meniu ce conține elemente
de meniu, fiecare dintre ele
putând fi un menu
› Directoare ce conține
fisiere, fiecare dintre ele
putând fi un director
J Composite - check list
› Se va verifica dacă problema poate fi reprezentată/gestionată într-o
maniera ierarhică
› Se vor împărții conceptele de domeniu în clase containere și clase
elemente
› Se va crea o clasă/interfață ce permite gestiunea/manevrarea atât a
containerelor cât si a elementelor în aceeași manieră
› Se vor declara clasa/clasele container si clasa/clase elemente ca
fiind într-o relație ”is a” cu clasa abstractă/interfața
› Se vor declara clasa/clasele container într-o relație ”has a” cu
interfața interfață/clasa abstractă
› Gestiunea elementelor se va realiza atât la nivel de elemente cât și
de containere.
J Composite - rules
› Composite si decorator au structură similară, ambele se bazează pe
compoziție recursivă
› Composite poate fi parcurs cu un iterator.
› Visitor poate efectua diverse operații asupra unui composite
J abstract public class TreeItem
{
Composite – exemplu 1
protected String name;
protected int level = 0;

public int GetLevel()


{
return level;
}

public void SetLevel(int level)


{
this.level = level;
}

abstract public void List();


}
J Composite – exemplu 1
public class File extends TreeItem
{
public File(String name)
{
this.name = name;
}

public void List()


{
for(int i = 0; i < level; i++)
{
System.out.print(" ");
}
System.out.println(name);
}
}
public class Folder extends TreeItem{
private List<TreeItem> items = new ArrayList();
public Folder(String name)
J {
this.name = name;
Composite – exemplu 1
}
public void Add(TreeItem item)
{
item.SetLevel(this.GetLevel() + 1);
items.add(item);
}
public void List()
{
for(int i = 0; i < level; i++)
{
System.out.print(" ");
}
System.out.println(name);
for (TreeItem item : items)
{
item.List();
}
}
}
public class Main{
public static void main(String[] args){
TreeItem music = InitMusic();
J }
music.List();
Composite – exemplu 1
private static TreeItem InitMusic(){
Folder music = new Folder("MUSIC");
Folder scorpions = new Folder("DIRE STRAITS");
Folder dio = new Folder("ERIC CLAPTON");
File track1 = new File("Beth & Joe - I'd Rather Go Blind.mp3");
File track2 = new File("Chris Rea – Looking for the summer");
File track3 = new File("Brothers In Arms.mp3");
File track4 = new File("Sultans of Swing.mp3");
File track5 = new File("Leyla.mp3");
music.Add(track1);
music.Add(scorpions);
music.Add(track2); MUSIC
scorpions.Add(track3); Beth & Joe - I'd Rather go blind.mp3
scorpions.Add(track4); DIRE STRAITS
scorpions.Add(dio); Brothers In Arms.mp3
dio.Add(track5); Sultans of Swing.mp3
return music; ERIC CLAPTON
} Leyla.mp3
} Chris Rea - Looking for the summer
interface Angajat{
void Detalii();

J }

class Programator implements Angajat{


Composite – exemplu 2
private String nume;
private int id;
private String post;

public Programator(int id, String nume, String post){


this.id = id;
this.nume = nume;
this.post = post;
}

@Override
public void Detalii(){
System.out.println(" " + id + ", " + nume + ", " + post);
}
}
class Asistent implements Angajat{
private String nume;

J private int id;


private String post; Composite – exemplul 2
public Asistent(int id, String nume, String post){
this.id = id;
this.nume = nume;
this.post = post;
}

@Override
public void Detalii(){
System.out.println(" " + id + ", " + nume );
}
}
class Manager implements Angajat{
private String nume;
private int id;
J private String post;
int rank;
Composite – exemplul 2
private List<Angajat> echipa = new ArrayList<Angajat>();
Manager( int id, String nume, String post, int rank){
this.nume = nume;
this.id = id;
this.post = post;
this.rank = rank;
}
public void add(Angajat a){ echipa.add(a); }
@Override
public void Detalii() {
for(int i = 0; i < rank; i++ ) { System.out.print(" "); }
System.out.println(id + ", " + post + ", " + nume + ", " + rank);
for(Angajat a:echipa){
for(int i = 0; i <= rank; i++ ) {
System.out.print(" ");
}
a.Detalii();
}
}
J Composite – exemplu 2
public class Main{
public static void main(String[] args){
Manager ceo = new Manager(100, "Satya Nadella", "Chief Executive Officer", 0);
ceo.add(new Asistent(12, "Julia Weiner", "Asistent manager"));
Manager man = new Manager(200, "Judson Althoff", "Executive Vice President -
Worldwide", 1);
man.add(new Programator(234, "Peggy Scott", ".Net"));
man.add(new Programator(345, "Harry Spencer", "C#"));
ceo.add(man);
man = new Manager(201, "Jean Hood", "Executive Vice President - Cloud", 1);
man.add(new Programator(698, "Kurt Hogan", "Java" ));
man.add(new Programator(356, "Jeff Smith", "Python"));
ceo.add(man);

ceo.Detalii();
}
}
J Composite - exemplu 2

100, Chief Executive Officer, Satya Nadella, 0


12, Julia Weiner, Asistent manager
200, Executive Vice President - Worldwide, Judson Althoff, 1
234, Peggy Scott, .Net
345, Harry Spencer, C#
201, Executive Vice President - Cloud, Jean Hood, 1
698, Kurt Hogan, Java
356, Jeff Smith, Python
J Decorator
› Adauga responsabilitati/functionalitati suplimentare in mod dinamic
› Furnizează o alternativă flexibilă pentru extinderea funcționalității
(alternativă la moștenire)
› ”Decorare” a nucleului obiectului de către client prin impachetare
recursivă
› Moștenirea nu este fezabila deoarece constructia obiectelor este statica
› “Procedeu”:
– Impacheteaza cadoul
– Pune cadoul intr-o cutie
– Impacheteaza cutia
– Pune cutia impachetata intr-o altă cutie etc.
J Decorator – the need
› Se dorește adăugarea unui nou comportament sau noi stări unui
obiect la run-time.
› Moștenirea nu este fezabilă în această situație/caz deoarece este
statică și adaugă aceste lucruri la o întreagă clasă

Window* wnd = new Window_V_H_Scrollbar_Border();


wnd->Draw();
//...
Window* wnd2 = new Window_Vertical_Scrollbar();
Decorare bazată
wnd2->Draw();
pe moștenire
J Decorator – the need
› Șablonul decorator furnizează ”clientului” posibilitatea de a
specifica ce combinații dorește când le dorește

Screen wnd = new Window_Border(


new Window_Horizontal_Scrollbar(
new Window_Vertical_Scrollbar(
new Window(1024, 768))));
wnd.Draw();
J Decorator - structure
› Clientul întotdeauna este interesat de funcționalitatea de bază
ObjectCoreFunctionality.DoTask(); iar în ceea ce privește optiunile
ObjectOptionOne.DoTask() și ObjectOptionTwo.DoTask() poate
sau nu poate fi interesat. Din acest motiv aceste clase deleagă clasa de
bază ”decorator”, iar clasa decorator deleagă la rândul ei layers
(optiunile adaugate).
J Decorator – check list
› Se vor asigura: componentă unică single core (fără alte opțiuni), o serie de
opțiuni ce pot fi adaugate (wrappers – ambalaje), o interfață comună tuturor
› Se va crea interfața comună tuturor
› Se vor crea clasele Core și Decorator având drept clasă de bază interfața
mai sus amintită.
› Clasa Decorator se va afla într-o relație de asociere de compoziție cu
Interfața, membrul fiind inițializat în constructor.
› Clasa decorator delegă (își delegă) funcționalitatea către clasa de bază
(Interfața)
› Se vor defini clase optiuni ce vor extinde clasa Decorator.
› Clasele Opțiuni vor implementa funcționalitatea lor și o vor delega către
clasa de bază
› Clientul are sarcina de a crea obiectul și de a configura nucleul (Core) și
opțiunile de care are nevoie
J Decorator -reguli
› Composite și Decorator au diagrame de structură similare, reflectând
faptul că se bazează pe compoziție recursivă pentru
organizarea/configurarea obiectelor
› Decoratorul poate fi vazut ca un Composite degenerat cu o singură
componentă. Totuși Decoratorul adaugă responsabilități/funcționalități și
nu este destinat agregării
› Decoratorul este proiectat pentru a permite clientului să adauge
responsabilități fără a se folosi de moștenire. Scopul composite este nu
acela de adaugare de responsabilități ci de reprezentare. Aceste lucruri
sunt distincte dar complementare motiv pentru care Composite și
Decorator sunt folosite de multe ori împreună.
J Decorator
J Decorator
interface Screen{
void draw();
}

class Window implements Screen{


String name;
Window(String w){
name = w;
}
@Override
public void draw(){
System.out.println("Based window - " + name);
}
}
J Decorator
abstract class Decorator implements Screen {
private Screen screen;
public Decorator(Screen screen){
this.screen = screen;
}

@Override
public void draw() {
screen.draw();
}
}
class Border extends Decorator{
Border(Screen screen){
J Decorator }
super(screen);

@Override
public void draw(){
super.draw();
System.out.println("\twith border");
}
}

class Titlebar extends Decorator{


Titlebar(Screen screen){
super(screen);
}
@Override
public void draw(){
super.draw();
System.out.println("\twith title bar");
}
}
class Scrollbar extends Decorator{
Scrollbar(Screen screen){
J Decorator }
super(screen);

@Override
public void draw(){
super.draw();
System.out.println("\twith scroll bar");
}
}

class Menu extends Decorator{


Menu(Screen screen){
super(screen);
}
@Override
public void draw(){
super.draw();
System.out.println("\twith menu");
}
}
public class Main {
public static void main(String[] args) {
System.out.println("Base object constrution:");
J Decorator Screen s = new Window("Command");
s.draw();

System.out.println("\nAdd title bar:");


s = new Titlebar(s);
s.draw();

System.out.println("\nAdd border:");
s = new Border(s);
s.draw();

System.out.println("\nAdd scrollbar:");
s = new Scrollbar(s);
s.draw();

System.out.println("\nAdd menu:");
s = new Menu(s);
s.draw();
}
}
Base object constrution:
Based window - Command

J Decorator Add title bar:


Based window - Command
with title bar

Add border:
Based window - Command
with title bar
with border

Add scrollbar:
Based window - Command
with title bar
with border
with scroll bar

Add menu:
Based window - Command
with title bar
with border
with scroll bar
with menu
J Decorator – test 2;
public class Main {
public static void main(String[] args) {
Screen s = new Menu(new Scrollbar(new Border(new Titlebar(new Window("Command")))));
s.draw();
}
}

Based window - Command


with title bar
with border
with scroll bar
with menu
J

S-ar putea să vă placă și