Κατέβασμα παρουσίασης
Η παρουσίαση φορτώνεται. Παρακαλείστε να περιμένετε
ΔημοσίευσεPeleus Matis Τροποποιήθηκε πριν 10 χρόνια
1
1 HMMY Τεχνολογία Λογισμικού Διδάσκων Κώστας Κοντογιάννης Αναπλ. Καθηγητής, Ε.Μ.Π
2
2 Ταξινόμηση Κοινών Σ.Μ - 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
3
3 Σχεδιαστικό Μοτίβο Singleton Σκοπός –Ο σκοπός αυτού του σχεδιαστικού μοτίβου είναι να διασφαλίσει ότι σε μια εφαρμογή λογισμικού, από μια κλάση μπορούμε να κατασκευάσουμε μέχρι ένα περιορισμένο αριθμό αντικειμένων (συνήθως μόνο ένα αντικείμενο) και ότι αυτή η κλάση παρέχει ένα σημείο παραπομπής στο μοναδικό αυτό αντικείμενο (ή τα αντικείμενα). Παρόλο που το μοτίβο αυτό χρησιμοποιείται για να διασφαλίσουμε ότι από τη κλάση μπορούμε να κατασκευάσουμε ένα μόνο αντικείμενο, το μοτίβο είναι αρκετά ευέλικτο για να μετατραπεί έτσι ώστε να επιτρέπει τη δημιουργία μέχρι ενός συγκεκριμένου αριθμού αντικειμένων από μια κλάση (δυο, τρία κλπ. αντικείμενα) Εφαρμογή –Χρησιμοποιούμε αυτό το σχεδιαστικό μοτίβο όταν θέλουμε να εγγυηθούμε ότι μια κλάση παράγει μόνο ένα αντικείμενο ανεξάρτητα από το πόσες φορές καλούμε τον κατασκευαστή (constructor) αυτής της κλάσης, και θέλουμε να έχουμε μέσω αυτής της κλάσης ένα μοναδικό και καθολικής εμβέλειας σημείο (global reference) για αυτό το μοναδικό αντικείμενο –Συμπληρωματικά, αυτό το μοτίβο επιτρέπει σε αυτό το μοναδικό αντικείμενο να μπορεί να επεκταθεί με τη χρήση ειδίκευσης (subclassing), χωρίς να χρειάζεται να αλλαχθεί το πρόγραμμα πελάτης που χρησιμοποιεί αυτό το (μοναδικό) αντικείμενο
4
4 Singleton – Διάγραμμα Κλάσης
5
5 Singleton - Σχόλια Επακόλουθα +Απλοποιεί τη δομή του προγράμματος διότι ελαττώνει τη χρήση namespaces +Επιτρέπει τη δημιουργία συγκεκριμένου αριθμού αντικειμένων, πέραν του ενός, εάν αυτό χρειάζεται +Επιτρέπει επέκταση των αντικειμένων με τη χρήση ειδίκευσης –Εάν δεν χρησιμοποιηθεί σωστά, συμπεριφέρεται το αντικείμενο συμπεριφέρεται σαν μια μεταβλητή γενικής εμβέλειας (global) –Η υλοποίηση του μοτίβου έχει περισσότερο λειτουργικό κόστος από το να χρησιμοποιούσαμε μιια μεταβλητή γενικής εμβέλειας (αλλά η υλοποίηση είναι πιο ασφαλής) –Χρειάζεται προσοχή όταν έχουμε παράλληλες διαδικασίες που χρησιμοποιούν το αντικείμενο (πρέπει να προσέχουμε πως οι διαφορετικές διαδικασίες χρησιμοποιούν το αντικείμενο) Σχόλια υλοποίησης –Χρήση της κατασκευής Static –Που και πως καταγράφεται η αναφορά (reference) στο αντικείμενο/αντικείμενα singleton
6
6 Singleton - Παράδειγμα class Singleton { public: static Singleton* Instance(); protected: Singleton(); Singleton(const Singleton&); Singleton& operator= (const Singleton&) private: static Singleton* pinstance; }; Singleton* Singleton::pinstance = 0; // initialize pointer Singleton* Singleton::Instance () { if (pinstance == 0) // is it the first call? { pinstance = new Singleton; // create sole instance } return pinstance; // address of sole instance } Singleton::Singleton() { //... perform necessary instance initializations } Παρόλο που το παραπάνω παράδειγμα επιτρέπει την κατασκευή μόνο ενός αντικειμένου, μπορούμε να αλλάξουμε τη μέθοδο Instance() και να κατασκευάσουμε ένα συγκεκριμένο αριθμό από αντικείμενα. Για παράδειγμα μπορούμε να αλλάξουμε τη μέθοδο Instance() και να κατασκευάσουμε μέχρι δύο, τρία ή περισσότερα αντικείμενα. Σε αυτή τη περίπτωση θα πρέπει το πεδίο pinstance να ορίζει μια δομή αντικειμένων (π.χ. ένα διάνυσμα από αντικείμενα)
7
7 Singleton – Παράδειγμα Πελάτη // Client code Singleton *p1 = Singleton::Instance(); Singleton *p2 = p1->Instance(); Singleton & ref = * Singleton::Instance();
8
8 Σχεδιαστικό Μοτίβο Abstract Factory Σκοπός –Ο σκοπός αυτού του σχεδιαστικού μοτίβου είναι να μας επιτρέπει να κατασκευάζουμε ομάδες συγγενικών αντικειμένων (families of related objects) χωρίς να χρειάζεται να προσδιορίσουμε κατά την κατασκευή τους τα ονόματα των αντίστοιχων κλάσεων αυτών των αντικειμένων. –Η βασική ιδέα είναι να χρησιμοποιήσουμε ένα «εργαστήρι» κατασκευής αντικειμένων. Το «εργαστήρι» που επιλέγουμε κάθε φορά ορίζει και τον τύπο των αντικειμένων που θα κατασκευαστούν. Έτσι ο κώδικας πελάτης δεν χρειάζεται να γνωρίζει τις λεπτομέρειες και τα ονόματα των κλάσεων που κατασκευάζονται. Το πλεονέκτημα είναι ότι μπορούμε να εξελίσσουμε τα «εργαστήρια» κατασκευής αντικειμένων χωρίς να χρειάζεται να μεταβάλλουμε ιδιαίτερα τον κώδικα πελάτη Εφαρμογή –Χρησιμοποιούμε αυτό το σχεδιαστικό μοτίβο όταν στον κώδικα πελάτη δεν γνωρίζουμε απ΄ αρχής για ποιες κλάσεις θα πρέπει να κατασκευάσουμε αντικείμενα. «Κρύβουμε» λοιπόν τη λογική της κατασκευής αυτών των αντικειμένων μέσα σε ένα κατάλληλο «εργαστήρι», και απλά χρησιμοποιούμε αυτό το «εργαστήρι» ανάλογα με τις συνθήκες και απαιτήσεις της εφαρμογής μας
9
9 Abstract Factory – Διάγραμμα Κλάσης «instantiate»
10
10 Abstract Factory - Παράδειγμα public class MazeFactory { public MazeFactory() {...} public Maze makeMaze(){ return new Maze(); } public Room makeRoom(int n) { return new Room(n); } public Wall makeWall() { return new Wall(); } public Door makeDoor(Room r1, Room r2) { return new Door(r1, r2); } }; public class MazeGame { //... public Maze createMaze (MazeFactory factory) { Maze aMaze = factory.makeMaze(); Room r1 = factory.makeRoom(1); Room r2 = factory.makeRoom(2); Door theDoor = factory.makeDoor(r1, r2); aMaze.addRoom(r1); aMaze.addRoom(r2); r1.setSide(MapSite.NORTH, factory.makeWall()); r1.setSide(MapSite.EAST, theDoor); r1.setSide(MapSite.SOUTH, factory.makeWall()); r1.setSide(MapSite.WEST, factory.makeWall()); r2.setSide(MapSite.NORTH, factory.makeWall()); r2.setSide(MapSite.EAST, factory.makeWall()); r2.setSide(MapSite.SOUTH, factory.makeWall(); r2.setSide(MapSite.WEST, theDoor); return aMaze; } }
11
11 Abstract Factory - Παράδειγμα public class EnchantedMazeFactory extends MazeFactory { public EnchantedMazeFactory() {...} public Room makeRoom(int n) { return new EnchantedRoom(n, new Spell()); } public Door makeDoor(Room r1, Room r2) { return new DoorNeedingSpell(r1, r2); } public class BombedMazeFactory extends MazeFactory { public BombedMazeFactory() {...} public Wall makeWall(){ return new BombedWall(); } public Room makeRoom(int n){ return new RoomWithABomb(n); }
12
12 Abstract Factory – Παράδειγμα Πελάτη MazeGame game; // The instance of a game. ………. Maze aMaze; // A reference to a maze. switch(choice) { case ENCHANTED: { EnchantedMazeFactory factory = new EnchantedMazeFactory(); aMaze = game.createMaze(factory); break; } case BOMBED: { BombedMazeFactory factory = new BombedMazeFactory(); aMaze = game.createMaze(factory); break; } }
13
13 Διάγραμμα Κλάσης για το Παράδειγμα
14
14 Abstract Factory - Σχόλια Επακόλουθα +Ευελιξία (Flexibility): καταργεί την εξάρτηση του κώδικα πελάτη από τα ονόματα κλάσεων που θα κατασκευαστούν +Απόκρυψη Πληροφορίας – Αφαίρεση (Abstraction): επιτρέπει την απόκρυψη από τον κώδικα πελάτη τις λεπτομέρειες κατασκευής και οργάνωσης των αντικειμένων που κατασκευάζονται –Γενικά δεν είναι σκόπιμο να επεκτείνουμε τη διαπροσωπία ενός factory αφού αυτή έχει ορισθεί. Για νέες κατασκευές καλό είναι να χρησιμοποιούμε νέα factories
15
15 Σχεδιαστικό Μοτίβο Factory Method Όταν κατασκευάζουμε αντικείμενα από κλάσεις χρησιμοποιούμε τον «κατασκευαστή» της αντίστοιχης κλάσης. Υπάρχουν όμως περιπτώσεις που δεν θέλουμε ο κώδικας πελάτης να γνωρίζει τι είδους αντικείμενα θα κατασκευαστούν. Το σχεδιαστικό μοτίβο έχει σαν σκοπό να μας επιτρέπει να ορίσουμε μια διαπροσωπία (στο παράδειγμα αυτή η διαπροσωπία είναι η μέθοδος FactoryMethod), σε μια κλάση (στο παράδειγμα είναι η κλάση creator) που μπορεί να χρησιμοποιηθεί για να κατασκευάσουμε αντικείμενα. Όμως, το τι είδους αντικείμενα θα κατασκευαστούν τελικά ορίζεται από το είδος των κλάσεων που θα εφαρμόσθεί η διαπροσωπία FactoryMethod. Αυτή η επιλογή μπορεί να γίνει με τρόπο διαφανή στον κώδικα πελάτη, οπότε και ο κώδικας πελάτης δεν χρειάζεται να γνωρίζει από πρίν τα ονόματα των κλάσεων (π.χ. μιας βιβλιοθήκης που δεν θέλουμε να αποκαλύψουμε τις λεπτομέρειές της). Για παράδειγμα ο κώδικας πελάτης μπορεί να γνωρίζει μια συγκεκριμένη κλάση creator (π.χ. ConcreteCtreatorX που είναι υπο-κλάση της abstract κλάσης creator), αλλά η μέθοδος FactoryMethod σε αυτή τη συγκεκριμένη κλάση μπορεί να κατασκευάζει αντικείμενα που ό κώδικας πελάτης δεν χρειάζεται να γνωρίζει τον τύπο τους. Ουσιαστικά το μοτίβο αφήνει στις υπο-κλάσεις της κλάσης creator να αποφασίσουν τι αντικείμενα θα κατασκευαστούν τελικά
16
16 Δομικά Στοιχεία του Σχεδιαστικού Μοτίβου Factory Method Οι κλάσεις που συμμετέχουν σε αυτό το σχεδιαστικό μοτίβο είναι: Η Κλάση Product –Ορίζει την αφηρημένη κλάση (abstract class) ή τη διαπροσωπία (interface) των αντικειμένων που μπορούν να κατασκευαστούν από το FactoryMethod Η Κλάση ConcreteProduct –Υλοποιεί τη διαπροσωπία που ορίζεται από τη κλάση Product Η Κλάση Creator –Ορίζει τη διαπροσωπία FactoryMethod, η οποία κατασκευάζει και επιστρέφει κάποιο αντικείμενο τύπου Product. Η κλάση Creator μπορεί να ορίσει κάποια default υλοποίηση που επιστρέφει κάποιο συγκεκριμένο τύπο αντικειμένου (π.χ. ConcreteProduct), και να καλέσει αυτή την default υλοποίηση της διαπροσωπίας FactoryMethod Η Κλάση ConcreteCreator –Είναι υπο-κλάση της κλάσης Creator και υπερκαλύπτει (overrides) την μέθοδο FactoryMethod με σκοπό η FactoryMethod να κατασκευάζει και να επιστρέφει άνα αντικείμενο (π.χ. ConcreteProduct) για το οποίο ο κώδικας πελάτης δεν γνωρίζει τον τύπο του (απλά γνωρίζει ότι το αντικείμενο που κατασκευάστηκε είναι τύπου Product)
17
17 Factory Method – Διάγραμμα Κλάσης
18
18 Factory Method - Παράδειγμα abstract class Product { } // "ConcreteProductA" class ConcreteProductA : Product { } // "ConcreteProductB" class ConcreteProductB : Product { } // "Creator" abstract class Creator { public abstract Product FactoryMethod(); } // "ConcreteCreator" class ConcreteCreatorA : Creator { public override Product FactoryMethod() { return new ConcreteProductA(); } } // "ConcreteCreator" class ConcreteCreatorB : Creator { public override Product FactoryMethod() { return new ConcreteProductB(); } } }
19
19 Factory Method – Παράδειγμα Πελάτη class MainApp { static void Main() { // An array of creators Creator[] creators = new Creator[2]; creators[0] = new ConcreteCreatorA(); creators[1] = new ConcreteCreatorB(); // Iterate over creators and create products foreach(Creator creator in creators) { Product product = creator.FactoryMethod(); Console.WriteLine("Created {0}", product.GetType().Name); } // Wait for user Console.Read(); } } Αποτέλεσμα: Created ConcreteProductA Created ConcreteProductB
Παρόμοιες παρουσιάσεις
© 2024 SlidePlayer.gr Inc.
All rights reserved.