Η παρουσίαση φορτώνεται. Παρακαλείστε να περιμένετε

Η παρουσίαση φορτώνεται. Παρακαλείστε να περιμένετε

1 HMMY Τεχνολογία Λογισμικού Διδάσκων Κώστας Κοντογιάννης Αναπλ. Καθηγητής, Ε.Μ.Π.

Παρόμοιες παρουσιάσεις


Παρουσίαση με θέμα: "1 HMMY Τεχνολογία Λογισμικού Διδάσκων Κώστας Κοντογιάννης Αναπλ. Καθηγητής, Ε.Μ.Π."— Μεταγράφημα παρουσίασης:

1 1 HMMY Τεχνολογία Λογισμικού Διδάσκων Κώστας Κοντογιάννης Αναπλ. Καθηγητής, Ε.Μ.Π

2 2 Βιβλιογραφία Οι παρακάτω παρουσιάσεις στη περιοχή των Σχεδιαστικών Μοτίβων βασίζονται στο παρακάτω υλικό –John Vlissides, tutorial.pdf –Text © by Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides –Diagrams © 1995 by Addison-Wesley Publishing Company

3 3 Σχεδιαστικά Μοτίβα (Σ.Μ) Ένα σχεδιαστικό μοτίβο στην περιοχή της Τεχνολογίας Λογισμικού ορίζει μια γενική σχεδιαστική λύση για κάποιο επαναλαμβανόμενο κοινό πρόβλημα –Παρέχει μια αφαιρετική σχεδιαστική λύση ή οποία έχει δοκιμαστεί σε κατηγορίες παρόμοιων προβλημάτων –Ορίζεται από κλάσεις (ή αντικείμενα), εξαρτήσεις, εταιρικότητες, δομές, συμβάσεις –Ένα σχεδιαστικό μοτίβο ορίζει τη σχεδίαση με σαφήνεια και περιγράφει σχεδιαστική εμπειρία για την επίλυση συναφών σχεδιαστικών προβλημάτων

4 4 Σχεδιαστικά Μοτίβα Ο ορισμός ενός σχεδιαστικού μοτίβου έχει τέσσερα δομικά μέρη: –1. Το όνομα του σχεδιαστικού μοτίβου –2. Το πρόβλημα που επιχειρεί να επιλύσει –3. Το σχεδιαστικό μέρος που συνήθως ορίζεται με ένα διάγραμμα κλάσεων –4. Αποτελέσματα, επακόλουθα και σύγκριση με άλλα μοτίβα (trade-offs) Τα σχεδιαστικά ορίζονται έτσι ώστε να είναι ανεξάρτητα της γλώσσας προγραμματισμού που χρησιμοποιείται Ένα σχεδιαστικό μοτίβο μπορεί να θεωρηθεί σαν μια “μικρο- αρχιτεκνονική” Η σχεδιαστική λύση που προτείνει ένα σχεδιαστικό μοτίβο θα πρέπει να υλοποιηθεί σε κάποια γλώσσα και σε σχέση με την εφαρμογή από τον προγραμματιστή Μπορούμε λοιπόν να πούμε ότι μια Αρχιτεκτονική Τεχνοτροπία ορίζει τη σχεδιαστική λύση σε επίπεδο αρχιτεκτονικής του συστήματος “μακροσκοπικά” ενώ το Σχεδιαστικό Μοτίβο ορίζει μια σχεδιαστική λύση σε επίπεδο λεπτομερούς σχεδίασης και υλοποίησης (“μικροσκοπικά”)

5 5 Ταξινόμηση Κοινών Σ.Μ - GoF Behavioural (Μοτίβα Συμπεριφοράς) Structural (Δομικά Μοτίβα) Creational (Μοτίβα Δημιουργίας) Visitor Iterator Observer State Template Method Chain of Responsibility Strategy Command Interpreter Mediator Memento Decorator Adapter Bridge Composite Facade Proxy Flyweight Abstract Factory Factory Method Singleton Builder Prototype

6 6 Συνήθης Φόρμα Ορισμού Σχεδιαστικού Μοτίβου Όνομα του Μοτίβου (Name and classification) Σκοπός του Μοτίβου (Intent) Άλλες ονομασίες του Μοτίβου (Also known as) Σενάριο Χρήσης του Μοτίβου (Motivational scenario) Εφαρμογή του Μοτίβου (Applicability) Δομή του Μοτίβου (Structure) Συμμετέχουσες Κλάσεις (Participants) Συνεργασίες / Εταιρικότητες (Collaborations) Επακόλουθα χρήσης του Μοτίβου (Consequences) Σχόλια για την υλοποίηση του Μοτίβου (Implementation issues) Παραδείγματα πηγαίου κώδικα με χρήση του Μοτίβου (Sample code) Γνωστές χρήσεις του Μοτίβου (Known uses) Άλλα σχετικά Μοτίβα (Related patterns)

7 7 Σχεδιαστικό Μοτίβο Visitor Σκοπός –Αυτό το σχεδιαστικό μοτίβο χρησιμοποιείται όταν έχουμε μια δομή τύπου container που περιέχει αντικείμενα και υπάρχουν διαφορετικές λειτουργίες που μπορούμε να επιλέξουμε όταν «επισκεπτόμαστε» αυτά τα αντικείμενα. Για παράδειγμα ένα διάνυσμα στοιχείων μπορεί να έχει μια λειτουργία που να επιτρέπει την εκτύπωση κάθε στοιχείου, ή μια άλλη λειτουργία που να επιτρέπει την πρόσθεση ενός αριθμού σε κάθε στοιχείο. Κάθε μια από αυτές τις λειτουργίες ενθυλακώνονται σε μια κατάλληλη κλάση (Visitor). Η δομή το μόνο που έχει να κάνει είναι να «δέχεται» κάθε φορά τον κατάλληλο Visitor Εφαρμογή –Όταν οι κλάσεις (containers) ορίζουν διαφορετικές λειτουργίες στα στοιχεία τους –Όταν οι σχέσεις ανάμεσα στα αντικείμενα της δομής δεν αλλάζουν συχνά, αλλά οι λειτουργίες σε αυτά τα αντικείμενα είναι διαφορετικές και αυτές μπορεί να αλλάζουν συχνά –Οι λειτουργίες καθώς εφαρμόζονται σε κάθε στοιχείο της δομής μπορεί να αλλάζουν την γενική κατάσταση (state) της δομής

8 8 Visitor – Διάγραμμα Κλάσης Δομή Στοιχεία της Δομής

9 9 Visitor - Παράδειγμα public class SomeContainer implements Container { public void accept (Visitor visitor) { for each Object i in this container{ visitor.visit (i); if (visitor.isDone(this)) break; } } //... } public class PrintingVisitor extends AbstractVisitor { public void visit (Object object) { System.out.println (object); } //... } // // in another class... Container c = new SomeContainer (); //... c.accept (new PrintingVisitor ()); Χρήση του visitor (κώδικας πελάτη) Ορισμός της κλάσης SomeContainer και της μεθόδου accept

10 10 Σχεδιαστικό Μοτίβο Iterator Σκοπός –Προσπέλαση των στοιχείων μιας δομής αντικειμένων χωρίς να χρειάζεται να γνωρίζει ο κώδικας – πελάτης τις λεπτομέρειες υλοποίησης της δομής Εφαρμογή –Όταν πρέπει να χρησιμοποιήσουμε διαφορετικούς τρόπους (αλγόριθμους) για τη προσπέλαση των στοιχείων της δομής –Όταν χρειαζόμαστε να έχουμε μια ομοιόμορφη διαπροσωπία για τη προσπέλαση των στοιχείων –Όταν η δομή ή η λογική προσπέλασης αλλάζει και ο κώδικας πελάτης θα πρέπει να παραμείνει ο ίδιος

11 11 Iterator – Διάγραμμα Κλάσης

12 12 Iterator – Παράδειγμα (1) import java.util.*; class IntSet { private Hashtable ht = new Hashtable(); public static class Iterator { private IntSet set; private Enumeration e; private Integer current; public Iterator( IntSet in ) { set = in; } public void first() { e = set.ht.keys(); next(); } public boolean isDone() { return current == null; } public int currentItem() { return current.intValue(); } public void next() { try { current = (Integer) e.nextElement(); } catch (NoSuchElementException e) { current = null; } } public void add( int in ) { ht.put( new Integer( in ), "null" ); } public boolean isMember( int i ) { return ht.containsKey(new Integer(i)); } public Hashtable getHashtable() { return ht; } public Iterator createIterator() { return new Iterator( this ); } }

13 13 Iterator – Παράδειγμα Πελάτη (2) class IteratorDemo { public static void main( String[] args ) { IntSet set = new IntSet(); ………. // Κώδικας για εισαγωγή στοιχείων στη δομή (σύνολο) // Clients ask the collection object to create many iterator objects IntSet.Iterator it1 = set.createIterator(); IntSet.Iterator it2 = set.createIterator(); // Clients use the first(), isDone(), next(), currentItem() protocol System.out.print( "\nIterator: " ); for ( it1.first(), it2.first(); ! it1.isDone(); it1.next(), it2.next() ) System.out.print( it1.currentItem() + " " + it2.currentItem() + " " ); System.out.print( "\nEnumeration: " ); for (Enumeration e = set.getHashtable().keys(); e.hasMoreElements(); ) System.out.print( e.nextElement() + " " ); System.out.println(); }

14 14 Iterator - Σχόλια Επακόλουθα +Ευελιξία: η δομή και ο κώδικας πελάτης γίνονται πιο ανεξάρτητες οντότητες +Χρήση πολλών διαφορετικών αλγόριθμων για τη προσπέλαση των στοιχείων (διαφορετικοί iterators) –Επιπλέον κόστος επικοινωνίας μεταξύ της δομής και του κώδικα – πελάτη Υλοποίηση –Εσωτερικοί ή εξωτερικοί iterators Γνωστές Χρήσεις –InterViews ListItr –Unidraw Iterator

15 15 Σχεδιαστικό Μοτίβο Observer Σκοπός –Να ορίσουμε μια σχέση εξάρτησης από ένα σε πολλά αντικείμενα έτσι ώστε όταν η κατάσταση ενός αντικειμένου αλλάζει όλα τα άλλα αντικείμενα που συμμετέχουν στη σχέση εξάρτησης να μπορούν να ενημερωθούν (αλλάξουν) αυτόματα Εφαρμογή –Όταν μια έννοια (οντότητα) έχει περισσότερες από μια σκοπιές (views) και που η κάθε σκοπιά εξαρτάται από τη κατάσταση της οντότητας –Όταν η αλλαγή σε ένα αντικείμενο απαιτεί αλλαγές σε άλλα αντικείμενα, αλλά δεν γνωρίζουμε σε ποια και σε πόσα άλλα αντικείμενα –Όταν ένα αντικείμενο θα πρέπει να γνωστοποιήσει κάποια αλλαγή κατάστασης ή άλλο γεγονός σε άλλα αντικείμενα χωρίς να χρειάζεται να γνωρίζει λεπτομέρειες για αυτά τα αντικείμενα

16 16 Observer – Διάγραμμα Κλάσης

17 17 Schematic Observer Example Subject Observers

18 18 Observer - Σχόλια Επακόλουθα +Ευελιξία (flexibility): Το αντικείμενα (subject, observers) μπορούν να αλλάζουν ανεξάρτητα το ένα από τα άλλα +Επεκτασιμότητα (extensibility): Μπορούμε να ορίσουμε όσους observers χρειάζονται +Προσαρμοστικότητα (adaptability): Διαφορετικοί observers υλοποιούν διαφορετικές σκοπιές του υποκειμένου (subject) –Πιθανές απρόβλεπτες ενημερώσεις αντικειμένων (τα αντικείμενα δεν γνωρίζουν το ένα τη ύπαρξη του άλλου –Update overhead: might need hints Υλοποίηση –Λεπτομέρειες υλοποίησης των σχέσεων εξάρτησης μεταξύ των αντικειμένων –Dangling references

19 19 Observer - Παράδειγμα (1) class Subject { public: virtual ~Subject(); virtual void Attach(Observer*); virtual void Detach(Observer*); virtual void Notify(); protected: Subject(); private: List *_observers; }; void Subject::Attach (Observer* o) { _observers->Insert(_observers->end(), o); } void Subject::Detach (Observer* o) { _observers->remove(o); } void Subject::Notify () { ListIterator i(_observers); for (i.First(); !i.IsDone(); i.Next()) { i.CurrentItem()->Update(this); } }}} class Observer { public: virtual ~Observer(); virtual void Update(Subject* theChangeSubject) = 0; protected: Observer(); }; class ClockTimer : public Subject { public: ClockTimer(); virtual int GetHour(); virtual int GetMinute(); virtual int GetSecond(); void Tick(); }; void ClockTimer::Tick() { // update internal time-keeping state //... Notify(); }

20 20 Observer – Παράδειγμα Πελάτη (2) class DigitalClock: public Observer { public: DigitalClock(ClockTimer *); ~DigitalClock(); void Update(Subject *); void Draw(); private: ClockTimer *_subject; }; DigitalClock::DigitalClock (ClockTimer *s) { _subject = s; _subject->Attach(this); } DigitalClock::~DigitalClock () { _subject->Detach(this); } void DigitalClock::Update (Subject *theChangedSubject) { if(theChangedSubject == _subject) draw(); } void DigitalClock::Draw () { int hour = _subject->GetHour(); int minute = _subject->GetMinute(); int second = _subject->GetSecond(); // draw operation } class AnalogClock: public Observer { public: AnalogClock(ClockTimer *); ~AnalogClock(); void Update(Subject *); void Draw(); private: ClockTimer *_subject; }; int main(void) { ClockTimer *timer = new ClockTimer; AnalogClock *analogClock = new AnalogClock(timer); DigitalClock *digitalClock = new DigitalClock(timer); timer->Tick(); return 0; }

21 21 Σχεδιαστικό Μοτίβο State Σκοπός –Επιτρέπει σε ένα αντικείμενο να αλλάζει τη συμπεριφορά του όταν η εσωτερική του κατάσταση αλλάξει. Εξωτερικά θα φαίνεται σαν να έχει αλλάξει το αντικείμενο κλάση Εφαρμογή –Το σχεδιαστικό μοτίβο State είναι χρήσιμο όταν θέλουμε ένα αντικείμενο να παρουσιάζει τη κατάσταση μιας εφαρμογής, και αλλάζοντας το αντικείμενο αλλάζουμε και τη συμπεριφορά της εφαρμογής –Το σχεδιαστικό μοτίβο State παρέχει ένα μηχανισμό που επιτρέπει σε ένα αντικείμενο να αλλάζει τη συμπεριφορά του όταν η εσωτερική του κατάσταση αλλάζει –Το όφελος του μοτίβου State είναι ότι η λογική που είναι σχετική με μια κατάσταση είναι επικεντρωμένη στις κλάσεις που αντιπροσωπεύουν την κατάσταση

22 22 State Δομικά Στοιχεία Τα Δομικά στοιχεία (Κλάσεις) αυτού του μοτίβου είναι: Context –Ορίζει τη διαπροσωπία που ενδιαφέρει τον κώδικα πελάτη για να καλέσει κάποια λειτουργία. Η συγκεκριμένη διαπροσωπία είναι η μέθοδος Request (βλ. επόμενη σελίδα) –Σχετίζεται με μια συγκεκριμένη οντότητα που αναφέρεται σε κάποια κατάσταση (state). Η συγκεκριμένη οντότητα είναι μια υλοποίηση (instance) κάποιας υπο- κλάσης της κλάσης State (δηλ. ConcreteStateΑ, ConcreteStateΒ κλπ. ) State –Ορίζει τη διαπροσωπία που ενθυλακώνει τη συμπεριφορά για κάποια συγκεκριμένη κατάσταση (state) κάποιου Context. Η συγκεκριμένη διαπροσωπία είναι η μέθοδος Handle Concrete State –Η υπο-κλάση που πολυμορφικά υλοποιεί τη συμπεριφορά που σχετίζεται με κάποια κατάσταση ενός Context

23 23 State Διάγραμμα Κλάσης

24 24 State Παράδειγμα // "State" abstract class State { public abstract void Handle(Context context); } // "ConcreteStateA" class ConcreteStateA : State { public override void Handle(Context context) { context.state = new ConcreteStateB(); } } // "ConcreteStateB" class ConcreteStateB : State { public override void Handle(Context context) { context.State = new ConcreteStateA(); } } class Context { private State state; public Context(State Astate) { this.state = Astate; } // Property public State State { get{ return state; } set { state = value; Console.WriteLine("State: " + state.GetType().Name); } } public void Request() { state.Handle(this); } }

25 25 State – Κώδικας Πελάτη static void Main() { // Setup context in a state Context c = new Context(new ConcreteStateA()); // Issue requests, which toggles state c.Request(); c.Request(); c.Request(); c.Request(); // Wait for user Console.Read(); } } Output State: ConcreteStateA State: ConcreteStateB State: ConcreteStateA State: ConcreteStateB State: ConcreteStateA

26 26 Σχεδιαστικό Μοτίβο Template Method Σκοπός –Ορισμός της γενικής δομής (βημάτων) ενός αλγορίθμου με τη δυνατότητα αλλαγής της λογικής κάποιων βημάτων σε συγκεκριμένες υλοποιήσεις ή περιπτώσεις Εφαρμογή –Όταν τα βασικά βήματα ενός αλγόριθμου μπορούν να υλοποιηθούν σε μια κλάση και οι υποκλάσεις μπορούν να υλοποιήσουν παραλλαγές συγκεκριμένων υπο-βημάτων –Όταν θέλουμε να συγκεντρώσουμε τα βασικά βήματα ενός αλγόριθμου σε μια κλάση για να προάγουμε επαναχρησιμοποίηση κώδικα

27 27 Template Method – Διάγραμμα Κλάσης

28 28 Template Method – Παράδειγμα (1)

29 29 Template Method – Παράδειγμα (2) class Account { public: void Transaction(float amount); void virtual TransactionSubpartA(); void virtual TransactionSubpartB(); void virtual TransactionSubpartC(); } void Account::Transaction(float amount) { TransactionSubpartA(); TransactionSubpartB(); TransactionSubpartC(); // EvenMoreCode; } class JuniorAccount : public Account { public: void virtual TransactionSubpartA(); } class SavingsAccount : public Account { public: void virtual TransactionSubpartC(); } // Client code Account* customer; customer = JunionAccount(); customer->Transaction(amount);

30 30 Template Method - Σχόλια Επακόλουθα +Οδηγεί σε αναστροφή ελέγχου (“Hollywood principle”: don't call us – we'll call you) +Επαναχρησιμοποίηση κώδικα –Χρήση υποκλάσεων για ειδίκευση της συμπεριφοράς υποβημάτων του αλγόριθμου Υλοποίηση –Virtual vs. non-virtual template method –Αριθμός υπο-βημάτων Γνωστές Χρήσεις –Σχεδόν σε όλες τις μεγάλες εφαρμογές υλοποιημένες με αντικειμενοστραφή προγραμματιστικές τεχνικές (ειδικά σε frameworks)

31 31 Σχεδιαστικό Μοτίβο Chain of Responsibility Σκοπός –Το μοτίβο Chain of Responsibility χρησιμοποιείται για να προάγει χαμηλή σύζευξη ανάμεσα στον αποστολέα ενός αιτήματος και στα αντικείμενα που διαχειρίζονται το αίτημα. Το μοτίβο δίνει τη δυνατότητα σε ένα ή περισσότερα αντικείμενα να διαχειριστούν το αίτημα Εφαρμογή –Τα αντικείμενα που μπορούν να διαχειριστούν το αίτημα είναι «συνδεδεμένα» με διάταξη αλυσίδας έτσι ώστε το ένα να περνά το αίτημα στο άλλο όταν και όπως χρειάζεται –Το αποτέλεσμα είναι το αίτημα να μπορεί να διαχειριστεί από ένα ή περισσότερα αντικείμενα.

32 32 Chain of Responsibility – Διάγραμμα Κλάσης

33 33 // "Handler" abstract class Handler { protected Handler successor; public void SetSuccessor(Handler successor) { this.successor = successor; } public abstract void HandleRequest(int request); } Chain of Responsibility – Παράδειγμα (1) // "ConcreteHandler1" class ConcreteHandler1 : Handler { public override void HandleRequest(int request) { if (request >= 0 && request < 10) { Console.WriteLine("{0} handled request {1}", this.GetType().Name, request); } else if (successor != null) { successor.HandleRequest(request); } } }

34 34 // "ConcreteHandler2" class ConcreteHandler2 : Handler { public override void HandleRequest(int request) { if (request >= 10 && request < 20) { Console.WriteLine("{0} handled request {1}", this.GetType().Name, request); } else if (successor != null) { successor.HandleRequest(request); } } } Chain of Responsibility – Παράδειγμα (2) // "ConcreteHandler3" class ConcreteHandler3 : Handler { public override void HandleRequest(int request) { if (request >= 20 && request < 30) { Console.WriteLine("{0} handled request {1}", this.GetType().Name, request); } else if (successor != null) { successor.HandleRequest(request); } } }

35 35 class MainApp { static void Main() { // Setup Chain of Responsibility Handler h1 = new ConcreteHandler1(); Handler h2 = new ConcreteHandler2(); Handler h3 = new ConcreteHandler3(); h1.SetSuccessor(h2); h2.SetSuccessor(h3); // Generate and process request int[] requests = {2, 5, 14, 22, 18, 3, 27, 20}; foreach (int request in requests) { h1.HandleRequest(request); } // Wait for user Console.Read(); } } Chain of Responsibility – Κώδικας Πελάτη Output ConcreteHandler1 handled request 2 ConcreteHandler1 handled request 5 ConcreteHandler2 handled request 14 ConcreteHandler3 handled request 22 ConcreteHandler2 handled request 18 ConcreteHandler1 handled request 3 ConcreteHandler3 handled request 27 ConcreteHandler3 handled request 20

36 36 Σχεδιαστικό Μοτίβο Strategy Σκοπός –Να ορίσουμε μια οικογένεια αλγόριθμων που μπορούν να κληθούν μέσω μιας ορισμένης διαπροσωπίας έτσι ώστε τα προγράμματα πελάτη και οι αλγόριθμοι να μπορούν να αλλάξουν ανεξάρτητα Εφαρμογή –Όταν ένα αντικείμενο πρέπει να έχει σχέση με ένα ή περισσότερους αλγόριθμους, και όλοι οι αλγόριθμοι μπορούν να ενθυλακωθούν και μια ενιαία διαπροσωπία μπορεί να χρησιμοποιηθεί για όλες τις ενθυλακώσεις

37 37 Strategy – Διάγραμμα Κλάσης

38 38 Strategy – Διάγραμμα Κλάσης (συγκεκριμένο)

39 39 Strategy – Παράδειγμα (1) class ConcreteContext : public Context{ public: ConcreteContext(); ConcreteContext(Strategy *); ConcreteContext(const ConcreteContext &); int array[10]; Strategy *thisStratergy; Boolean aggregation; void execute(); void attachStrategy(Strategy *s); }; template class Print : public Strategy { public: virtual void doAlgorithm(T* const); Print *clone(); }; template class DecreasePrint : public Strategy { public: virtual void doAlgorithm(T* const cont); void quicksortD(int array[], int l, int r); DecreasePrint *clone(); int array[10]; }; template void IncreasePrint ::doAlgorithm( T* const cont) { for (int i=0; i<10; i++) array[i] = cont->array[i]; quicksortI(array, 0, 9); printf("INCREASING ORDER\n"); for (int i=0; i<10; i++) ::printf("Element no %d = %d\n", i, array[i]); }

40 40 Strategy – Παράδειγμα (2) template void DecreasePrint ::doAlgorithm(T* const cont){ for (int i=0; i<10; i++) array[i] = cont->array[i]; quicksortD(array, 0, 9); ::printf("DECREASING ORDER\n"); for (int i=0; i<10; i++) ::printf("Element no %d = %d\n", i, array[i]); } void Context::execute(){ if(thisStrategy){ thisStrategy->doAlgorithm((T *)this); } else { ::printf("Error: there is no strategy attached to the context\n"); ::printf("An exeception has been thrown\n"); throw "Error: there is no stategy attach to the context"; } void Context::attachStrategy(Strategy * anotherStrategy){ if (aggregation) delete thisStrategy; thisStrategy = anotherStrategy; }

41 41 Strategy – Παράδειγμα (3) Context::Context(const Context &t) { if(t.aggregation){ thisStrategy = t.thisStrategy->clone(); aggregation = true; } else { thisStrategy = t.thisStrategy; aggregation = false; }

42 42 Strategy – Παράδειγμα Πελάτη (4) main(int argc, char **argv){ ConcreteContext * context1 = new ConcreteContext(); context1->attachStrategy((Strategy *)(new Print ())); context1->execute(); ::printf("*****************\n"); ConcreteContext * context2 = new ConcreteContext(*context1); // Copy constructor context1->attachStrategy((Strategy *)(new IncreasePrint ())); context1->execute(); ::printf("*****************\n"); context1->removeStrategy(); context1->attachStrategy((Strategy *)(new DecreasePrint ())); context1->execute(); context1->removeStrategy(); delete context1; ::printf("*****Context2******\n"); context2->execute(); context2->removeStrategy(); delete context2; :: printf("\n Testing Aggregation \n\n"); context1 = new ConcreteContext( (Strategy *)(new IncreasePrint ())); context1->execute(); ::printf("*****************\n"); context2 = new ConcreteContext(*context1); delete context1; context2->execute(); delete context2; }

43 43 Strategy - Σχόλια Επακόλουθα +Ευελιξία, δυνατότητα επαναχρησιμοποίησης κώδικα +Μπορούμε να αλλάζουμε και να προσθέτουμε νέους αλγόριθμους δυναμικά στο κώδικα πελάτη –Κόστος για τη δημιουργία συσχέτισης νέων αλγορίθμων με τα αντικείμενα-περιβάλλοντα (context) και γενικά κόστος επικοινωνίας μεταξύ των στοιχείων του μοτίβου (strategy, context κλπ.) –Σταθερή και αμετάβλητη διαπροσωπία κλήσης των αλγόριθμων (Inflexible strategy interface) Υλοποίηση –Λεπτομέρειες ανταλλαγής δεδομένων ανάμεσα σε ένα αλγόριθμο (strategy) και στο αντίστοιχο περιβάλλον (context) –Χρήση templates για τη στατική επιλογή αλγορίθμου


Κατέβασμα ppt "1 HMMY Τεχνολογία Λογισμικού Διδάσκων Κώστας Κοντογιάννης Αναπλ. Καθηγητής, Ε.Μ.Π."

Παρόμοιες παρουσιάσεις


Διαφημίσεις Google