Curs 7 - Alexandru Ioan Cuza Universityogh/files/ip/curs-07.pdf · deveni familiar şi îl vor...

Post on 03-Mar-2020

5 views 0 download

transcript

Ingineria Program ării

Curs 7Curs 7

Ovidiu Gheorghieş, ogh@infoiasi.ro

Adriana Gheorghieş, adrianaa@infoiasi.ro

Design Patterns, I

Modele de proiectare, I

IP7

Design Patterns(Modele de proiectare)

• de·sign n.– 1.a. A drawing or sketch. – b. A graphic representation, especially a detailed plan for

construction or manufacture.– 2. The purposeful or inventive arrangement of parts or

details.– 3. The art or practice of designing or making designs.

• pat·tern n.– 1.a. A model or an original used as an archetype.– b. A person or thing considered worthy of imitation.– 2. A plan, diagram, or model to be followed in making things

IP7 MotivaŃii

• Proiectarea sistemelor (orientate-obiect) este dificilă

• Proiectarea sistemelor (orientate-obiect) extensibile este foarte dificilă

• Proiectarea sistemelor (orientate-obiect) refolosibile este şi mai dificilă

• Scopuri în proiectare– Rezolvarea problemei concrete– Crearea unei structuri flexibile, ce poate evolua– Evitarea re-proiectării

IP7 Proiectare bună

• Este greu (pentru începători) să creeze un proiect bun de prima dată

• ProiectanŃii experŃi reuşesc repede deoarece:– Refolosesc soluŃii folosite în proiecte anterioare– [ ExperienŃa crează experŃii ]

• Apar modalităŃi standard de a rezolva probleme concrete. Familiaritatea cu acestea poate duce la crearea unui proiect flexibil, elegant şi reutilizabil într-un timp scurt.

IP7 Surse de inspiraŃie

•Antropologie culturală“antropologie = ştiinŃă care se ocupă cu studiul originii, evoluŃiei şi variabilităŃii biologice a omului, în corelaŃie cu condiŃiile naturale şi socio-culturale.” (DEX)

•Arhitectură“ştiinŃa şi arta de a proiecta şi construi clădiri” (DEX)

IP7 Antropologia culturală

• FrumuseŃea stă în ochii celui care priveşte sau oamenii admit (acceptă) faptul că anumite lucruri sunt frumoase iar altele nu?

• Într-o cultură indivizii cad de acord, în mare parte, asupra a ceea ce este considerat frumos.

• Cultura transcende credinŃele individuale.

IP7 Arhitectură

Cristopher Alexander (arhitect american):• “Este calitatea obiectivă?”

• Calitatea unei construcŃii poate fi măsurată în mod obiectiv, ea nu este numai o chestiune de gust.

• Pattern = soluŃie la o problemă într-un anumit context.

IP7 Design bun, design prost…

• Cum ne dăm seama că un anumit design este bun?

– Ce este prezent într-un design bun şi nu se regăseşte într-un design prost?

– Ce este prezent intr-un design prost şi nu se regaseşte într-un design bun?

IP7 Exemplu: curtea unei case

• Curtea unei case ajută oamenii să trăiască în ea.• Oamenii doresc să aibă un spaŃiu propriu în aer liber

în care să poată admira cerul şi stelele, să se bucure de soare şi, poate, să planteze flori.

• Dar mai sunt şi alte lucruri de luat în considerare. De exemplu, atunci când o curte are ziduri care nu permit vederea în exterior oamenii nu se simt bine şi tind să stea deoparte... ei au nevoie să vadă în exterior, ei au nevoie de spaŃii largi.

• Pe de altă parte oamenii îşi creează obişnuinŃe. Dacă ei trec zilnic încoace şi încolo prin curte locul le va deveni familiar şi îl vor folosi.

nume scop

desc

riere

a pr

oble

mei

IP7 Bibliografie

Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides.Design Patterns. Elements of Reusable Object-Oriented Software.Addison-Wesley, 1995

Pe scurt GOF = Gang of Four

În română:

Şabloane de proiectare. Elemente de software reutilizabil orientat pe obiect

Editura Teora, 2002

IP7

“Design patterns capture solutions that have developed and evolved over time”

GOF

IP7

Elementele unui model de proiectare

• Numele– Mod de a referi o problemă de proiectare, soluŃiile ei şi

consecinŃele acestora.– ÎmbogăŃeşte limbajul proiectantului– Găsirea numelui: cea mai dificilă problemă

• Problema– Descrie problema şi contextul în care apare

• SoluŃia– Descrie elementele modelului, relaŃiile, resposabilităŃile şi modul de colaborare.

– Nu este o soluŃie concretă, ci una abstractă

• ConsecinŃele

IP7 Modele de proiectare - clasificare

• modele structurale: se preocupă de modul în care clasele şi obiectele sunt compuse pentru a forma structuri mai mari

(adapter, bridge, composite, decorator, façade, flyweight, proxy)

• modele comportamentale: se preocupă de algoritmi şi de asignarea responsabilităŃilor între obiecte

(chain of responsibility, command, interpreter, iterator, mediator, memento, observer, state, strategy, template method, visitor)

• modele creaŃionale: abstractizează procesul de instanŃiere

(abstract factory, builder, factory method, prototype, singleton)

IP7 În acest curs

• Singleton: garantează existenŃa unei singure instanŃe a unei clase. Se asigură o modalitate de a accesa instanŃa respectivă.

• Factory Method: defineşte o interfaŃă pentru crearea unui obiect, dar lasă în sarcina subclaselor alegerea tipului acestuia.

• Strategy: defineşte o familie de algoritmi

• Decorator: asignare de responsabilităŃi în mod dinamic

• Composite: obiecte şi grupuri tratate uniform

• Iterator: oferă o modalitate de a accesa obiecte agregate în mod secvenŃial fără a cunoaşte modul de agregare

• Template Method: se defineşte scheletul unui algoritm într-o metodă, lăsând implementarea paşilor algoritmului în seama subclaselor

IP7 Singleton / Unicat

• Scop: Garantarea existenŃei unei singure instanŃe a unei clase. Se asigură o modalitate de a accesa instanŃa respectivă.

• MotivaŃie– Un singur spooler– Un singur sistem de fişiere– Un singur gestionar de ferestre

• Aplicabilitate– InstanŃa unică a unei clase trebuie să fie accesibilă clienŃilor într-

un punct cunoscut– InstanŃa unică trebuie să fie extensibilă; clienŃii nu trebuie să îşi

modifice codul

IP7 Singleton (2)

• Structura

Singleton

-static uniqueInstance:-singletonData

+static Instance()+SingletonOperation()+GetSingletonData()

return uniqueInstance

IP7 Singleton (java)

public class Singleton { private static Singleton instance = null; private Singleton() {…}public static Singleton getInstance () {

if( instance == null ) { instance = new Singleton();

} return instance;

} public void operation() { … }

}

public class Client { public static void main( String arg[] ) {

try { Singleton instance = Singleton. getInstance (); instance.operation();

} catch( Exception e ) { e.printStackTrace();

}

} }

IP7 Singleton (C++)

class Singleton { private:

static Singleton* singleton;Singleton () {…}

public: static Singleton* instance() {

if( singleton == 0 ) { singleton = new Singleton();

} return singleton;

}; void operation() {…}

};

Singleton* Singleton::singleton = 0;

int main() { Singleton* singleton = Singleton::instance(); singleton->operation();return 0;

}

IP7 Singleton (C++)

Singleton Pattern: A review and analysis of existing C++ implementations

http://www.codeproject.com/cpp/singleton.asp

IP7 Factory Method / Metodă fabrică

• Scop: Defineşte o interfaŃă pentru crearea unui obiect, dar lasă în sarcina subclaselor alegerea tipului acestuia.

• MotivaŃie– O bibliotecă foloseşte clase abstracte pentru a defini şi

menŃine relaŃii între obiecte.– Un tip de responsabilitate este crearea de astfel de

obiecte.– Biblioteca ştie când trebuie creat un obiect, dar nu şi

ce tip de obiect trebuie creat (acesta este specific aplicaŃiei care foloseşte biblioteca)

IP7 Factory Method (2)

• MotivaŃie - exemplu

Framework

Application

Document

Application

+CreateDocument()+NewDocument()

MyDocument

MyApplication

+CreateDocument()

Document* doc =CreateDocument();

// add doc to container

return newMyDocument()

IP7 Factory Method (3)

• Aplicabilitate– Când o clasă nu poate anticipa tipul obiectelor care

trebuie să le creeze– Când o clasă vrea ca subclasele să specifice tipul

obiectelor de creat

• Structura

ProductCreator

+FactoryMethod()+AnOperation()

ConcreteCreator

+FactoryMethod()ConcreteProduct

product =FactoryMethod()

return newConcreteProduct

IP7 Factory Method (java)

public interface Product { … }

public abstract class Creator { public void anOperation() {

Product product = factoryMethod(); } protected abstract Product factoryMethod();

}

public class ConcreteProduct implements Product { … }

public class ConcreteCreator extends Creator { protected Product factoryMethod() {

return new ConcreteProduct(); }

}

public class Client { public static void main( String arg[] ) {

Creator creator = new ConcreteCreator(); creator.anOperation();

}}

IP7 Factory Method (C++)

class Product { };

class Creator { protected:

virtual Product* factoryMethod() = 0; public:

void anOperation() { Product* product = factoryMethod(); /** * Do some things with the Product object. */ delete product;

}; };

class ConcreteProduct: public Product { };

class ConcreteCreator: public Creator { protected:

virtual Product* factoryMethod() { return new ConcreteProduct();

}; };

IP7 Factory Method (C++)

int main() {

/** * Instantiate a Creator object. */

Creator* creator = new ConcreteCreator();

/** * Call the operation which uses a factory metho d. */ creator -> anOperation();

/** * Clean-up. */

delete creator;

};

IP7 Strategy / Strategie

• Scop: Se defineşte o familie de algoritmi; se încapsulează fiecare mebru; algoritmii se facinterschimbabili.

• MotivaŃie

Sorter

+MethodWithSort()

Sort

+Sort()

QuickSort NaiveSortHeapSortsort->Sort()

IP7 Strategy (2)

• Aplicabilitate– Multe clase înrudite diferă doar prin comportament– Se folosesc diverse variante ale unui algoritm– Algoritmii folosesc date irelevante pentru client– O clasă defineşte comportamente multiple, definite de

condiŃii gardă la începutul metodelor.

• Structură

Context

+ContextInterface()

Strategy

+AlgorithmInterface()

ConcreteStrategyA ConcreteStrategyB

IP7 Strategy (java)

// Abstract Strategy

class abstract class Strategy{

public abstract void algorithmInterface();

}

// ConcreteStrategyA

class class ConcreteStrategyA extends Strategy{

public void algorithmInterface(){

System.out.println("ConcreteStrategyA algorithm is used now");

}

}

// ConcreteStrategyB class

class ConcreteStrategyB extends Strategy{

public void algorithmInterface(){

System.out.println("ConcreteStrategyB algorithm is used now");

}

}

IP7 Strategy (java)

class Context{ //Default Algorithm private Strategy strategy = new ConcreteStrategyA(); public void changeStrategy(Strategy newStrategy){

strategy=newStrategy; } public void getResult(){

strategy. algorithmInterface(); }

} //Client class public class Client{

public static void main(String args[]){ Context context=new Context(); context.getResult(); context.changeStrategy(new ConcreteStrategyB()); context.getResult();

} }

IP7 Decorator

• Scop– Obiectelor li se pot ataşa respnsabilităŃi în mod dinamic.– Alternativă flexibilă la derivare pentru extinderea funcŃionalităŃii

• MotivaŃie

IP7 Decorator (2)

• Aplicabilitate– Adăugarea responsabilităŃilor în mod dinamic şi transparent– Retragerea responsabilităŃilor– Atunci când derivarea devine nepractică

• Structura

Component

+Operation()

ConcreteComponent Decorator

+Operation()

ConcreteDecoratorA

-addedState

+Operation()

ConcreteDecoratorB

+Operation()+AddedBehavior()

component->Operation()

Decorator::Operation();AddedBehavior();

IP7 Decorator (java)

//VisualComponent

class class VisualComponent{

public VisualComponent(){};

public void draw(){};

public void resize(){};

}

//Decorator abstract

class Decorator extends VisualComponent{

private VisualComponent comp;

Decorator(){};

Decorator(VisualComponent comp){ this.comp=comp; }

public void draw(){

comp.draw();

//Implement your code here

}

public void resize(){ //Implement your code here }

}

IP7 Decorator (java)

//BorderDecoratorclass BorderDecorator extends Decorator{

private int width;

BorderDecorator(VisualComponent comp, int borderWidth ){ //Implement your code here width=borderWidth;

}

public void draw(){ super.draw(); drawBorder(width);

}

public void drawBorder(int width){ System.out.println("This is an example of Decorator design

pattern"); //Implement code here

} }

IP7 Decorator (java)

public class Client{

public static void main(String args[]){

//Create an instance of VisualComponentVisualComponent comp=new VisualComponent();

//Pass this instance to BorderDecoratorcomp=new BorderDecorator(comp,5);

comp.draw();

}

}

Alternativ:VisualComponent comp=

new BorderDecorator(new VisualComponent(),5)

IP7 Composite / Amestec

• Scop– Se doreşte gruparea obiectelor în structuri arborescente

pentru a reprezenta relaŃii de tip parte-întreg.– Obiectele şi grupurile de obiecte sunt tratate uniform.

• MotivaŃie

IP7 Composite (2)

• Aplicabilitate– Reprezentarea relaŃiei parte-întreg– Ignorarea diferenŃei dintre obiecte individuale şi grupurile de

obiecte

• StructuraClient Component

+Operation()+Add(c:Component)

+Remove(c:Component)+GetChild(i:int)

Leaf

+Operation()

Composite

+Operation()

for all c:child c->Operation()

child

IP7 Composite (java)

public interface Component {

void operation();

void add( Component component );

boolean remove( Component component );

Component getChild( int index );

}

public class Leaf implements Component {

public void operation() { }

public void add( Component component ) { }

public boolean remove( Component component ) {

return false;

}

public Component getChild( int index ) {

return null;

}

}

IP7 Composite (java)

public class Composite implements Component {

private Vector children = new Vector();

public void operation() {

int i;

for( i = 0; i < children.size(); ++i ) {

Component component = (Component)children.elementAt(i ); component.operation();

}

}

public void add( Component component ) { children.addElement( component );

}

public boolean remove( Component component ) {

return children.removeElement( component );

}

public Component getChild( int index ) {

return (Component) children.elementAt(index);

}

}

IP7 Composite (java)

public class Client {

public static void main( String arg[] ) {

Component composite = new Composite();

Component leaf1 = new Leaf();

Component leaf2 = new Leaf();

composite.add( leaf1 );

composite.add( leaf2 );

composite.operation();

}

}

IP7 Iterator

• Scop: Oferă o modalitate de a accesa obiecte agregate în mod secvenŃial fără a cunoaşte modul de agregare.

• MotivaŃie

List

ListIterator

+First()+Next()

+IsDone()+CurrentItem()

IP7 Iterator (2)

• MotivaŃie (2)

Container

+CreateIterator()+Append(i:Item)

List Vector

Iterator

+First()+Next()

+IsDone()+CurrentItem()

ListIterator

+First()+Next()

+IsDone()+CurrentItem()

VectorIterator

Client

IP7 Iterator (3)

• Structura

Aggregate

+CreateIterator()

ConcreteAggregate

+CreateIterator()

return newConcreteIterator(this)

ConcreteIterator

Iterator

+First()+Next()

+IsDone()+CurrentItem()

Client

IP7 Iterator (java)

public interface Iterator {

Object first() throws IndexOutOfBoundsException;

Object next() throws IndexOutOfBoundsException;

boolean isDone();

Object currentItem() throws IndexOutOfBoundsExcepti on;

}

public interface Aggregate {

Iterator createIterator();

}

public class ConcreteAggregate implements Aggregate {

public Vector storage = new Vector();

public Iterator createIterator() {

return new ConcreteIterator( this );

}

}

IP7 Iterator (java)

public class ConcreteIterator implements Iterator { private ConcreteAggregate aggregate; private int index = 0;

public ConcreteIterator( ConcreteAggregate aggregate ) { this.aggregate = aggregate;

}

public Object first() throws IndexOutOfBoundsExcept ion { Object object = null; if( !aggregate.storage.isEmpty() ) {

index = 0; object = aggregate.storage.firstElement();

} else { throw new IndexOutOfBoundsException();

} return object;

}

IP7 Iterator (java)

public Object next() throws IndexOutOfBoundsExcepti on {

Object object = null;

if( index + 1 < aggregate.storage.size() ) {

index += 1;

object = aggregate.storage.elementAt(index);

} else {

throw new IndexOutOfBoundsException();

}

return object;

}

IP7 Iterator (java)

public boolean isDone() { boolean result = false; if( aggregate.storage.isEmpty() ||

index == aggregate.storage.size() - 1 ) { result = true;

} return result;

}

public Object currentItem() throws IndexOutOfBounds Exception { Object object = null; if( index < aggregate.storage.size() ) {

object = aggregate.storage.elementAt( index ); } el se {

throw new IndexOutOfBoundsException(); } return object;

} }//class

IP7 Iterator (java)

public class Client {

public static void main( String arg[] ) {

Aggregate aggregate = new ConcreteAggregate();

Iterator iterator = aggregate.createIterator();

for(iterator.first(); !iterator.isDone(); iterator.next()) {

Object currentItem = iterator. currentItem();

/** * Process currentItem */

}

}

}

IP7 Template Method / Metodă şablon

• Scop: Se defineşte scheletul unui algoritm într-o metodă, lăsând implementarea paşilor algoritmului în seama subclaselor.

• MotivaŃie

void Application::OpenDocument(string& name){

if (!CanOpenDocument(name))return;

Document* pDoc = CreateDocument();if (pDoc == 0)

return;m_docs.add(pDoc);InitializeOpenDocument(pDoc);pDoc->Read();

}

Document

+Read()

Application

+CreateDocument()+CanOpenDocument()

+InitializeOpenDocument()+OpenDocument()

MyApplication

+CanOpenDocument()+InitializeOpenDocument()

+CreateDocument()

MyDocument

+Read()

IP7 Template Method (2)

• Aplicabilitate– Implementarea structurii fixe a unui algoritm, lăsând

clasele derivate să implementeze funcŃionalitatea care variază

– Când funcŃionalitatea comună a unor clase este relocată într-o clasă de bază

• Structură AbstractClass

+TemplateMethod()+PrimitiveOperation1()+PrimitiveOperation2()

ConcreteClass

+PrimitiveOperation1()+PrimitiveOperation2()

PrimitiveOperation1()...PrimitiveOperation2()

IP7 Template Method

public abstract class AbstractClass {

public void templateMethod() {

primitiveOperation1();

primitiveOperation2();

}

protected abstract void primitiveOperation1();

protected abstract void primitiveOperation2();

}

public class ConcreteClass extends AbstractClass {

protected void primitiveOperation1() { }

protected void primitiveOperation2() { }

}