Μεθοδολογίες Προγραμματισμού ΙΙ Σχεδιαστικά Πρότυπα...

33
Μεθοδολογίες Προγραμματισμού ΙΙ Μεθοδολογίες Προγραμματισμού ΙΙ Σχεδιαστικά Πρότυπα (2) Σχεδιαστικά Πρότυπα (2) Παναγιώτης Σφέτσος, PhD http://aetos.it.teithe.gr/~sfetsos/ [email protected]

description

Μεθοδολογίες Προγραμματισμού ΙΙ Σχεδιαστικά Πρότυπα (2). Παναγιώτης Σφέτσος , PhD http://aetos.it.teithe.gr/~sfetsos/ [email protected]. Ταξινόμηση Σχεδιαστικών Προτύπων. ΥπερΚλάσεις – Αφηρημένες και Διεπαφές (1/11). Σχεδιασμός ενός ηλεκτρονικού παιχνιδιού με πάπιες που…. - PowerPoint PPT Presentation

Transcript of Μεθοδολογίες Προγραμματισμού ΙΙ Σχεδιαστικά Πρότυπα...

Page 1: Μεθοδολογίες Προγραμματισμού ΙΙ Σχεδιαστικά Πρότυπα (2)

Μεθοδολογίες Προγραμματισμού ΙΙΜεθοδολογίες Προγραμματισμού ΙΙ

Σχεδιαστικά Πρότυπα (2)Σχεδιαστικά Πρότυπα (2)

Παναγιώτης Σφέτσος, PhD

http://aetos.it.teithe.gr/~sfetsos/

[email protected]

Page 2: Μεθοδολογίες Προγραμματισμού ΙΙ Σχεδιαστικά Πρότυπα (2)

Παναγιώτης Σφέτσος, Μεθοδολογίες Προγραμματισμού ΙΙ 2

Ταξινόμηση Σχεδιαστικών ΠροτύπωνΤαξινόμηση Σχεδιαστικών Προτύπων

ΣκοπόςΣκοπόςCreationalCreational Structural Structural BehavioralBehavioral

ΠεδίοΠεδίο

ΚλάσηΚλάση Factory Method Adapter Interpreter

Template Method

ΑντικείμενοΑντικείμενο Abstract FactoryBuilderPrototypeSingleton

AdapterBridgeCompositeDecoratorFacadeProxy

Chain of ResponsibilityCommandIteratorMediatorMementoFlyweightObserverStateStrategyVisitor

Page 3: Μεθοδολογίες Προγραμματισμού ΙΙ Σχεδιαστικά Πρότυπα (2)

Σχεδιασμός ενός ηλεκτρονικού παιχνιδιού με πάπιες που….Σχεδιασμός ενός ηλεκτρονικού παιχνιδιού με πάπιες που….

Παναγιώτης Σφέτσος, Μεθοδολογίες Προγραμματισμού ΙΙ 3

ΥπερΚλάσεις – Αφηρημένες και Διεπαφές (1/11) ΥπερΚλάσεις – Αφηρημένες και Διεπαφές (1/11)

Κάθε υποκλάση υλοποιεί διαφορετικά την αφηρημένη μέθοδο display() (διαφορετικές πάπιες) Κάθε νέα υποκλάση κληρονομεί από την κλάση Duck… Τι θα συμβεί αν θέλουμε να προσθέσουμε μια νέα μέθοδο fly();

Page 4: Μεθοδολογίες Προγραμματισμού ΙΙ Σχεδιαστικά Πρότυπα (2)

Όλες οι υποκλάσεις κληρονομούν την fly(). Όλες οι πάπιες πετούν; Τι θα γίνει αν προστεθείμια νέα υποκλάση από πάπιες που δεν πετούν;

Όλες οι υποκλάσεις κληρονομούν την fly(). Όλες οι πάπιες πετούν; Τι θα γίνει αν προστεθείμια νέα υποκλάση από πάπιες που δεν πετούν;

Παναγιώτης Σφέτσος, Μεθοδολογίες Προγραμματισμού ΙΙ 4

ΥπερΚλάσεις – Αφηρημένες και Διεπαφές (ΥπερΚλάσεις – Αφηρημένες και Διεπαφές (22/11) /11)

Φορτώσαμε συμπεριφορά (fly()) που δεν μπορούν να υλοποιήσουν όλες οι υποκλάσεις (διαφορετικές πάπιες). Προσθέτοντας μια νέα υποκλάση την RubberDuck, αυτές οι πάπιες δεν κάνουν quack(). Μία λύση να υπερσκελίσουμε (override) την quack() σε squeak(). Το ίδιο με την fly(), με υπερσκέλιση να μην κάνει τίποτε. ΚΑΚΗ ΣΧΕΔΙΑΣΗ !!!!!

Page 5: Μεθοδολογίες Προγραμματισμού ΙΙ Σχεδιαστικά Πρότυπα (2)

Μια λύση να ξεχωρίσουμε συμπεριφορές κάνοντας τες διεπαφές, εδώ τις συμπεριφορές fly και quack. Οι διεπαφές Flyable και Quackable έχουν αντίστοιχα μια μέθοδο fly() και μια μέθοδο quack() για να υλοποιούνται από τις υποκλάσεις που τις χρειάζονται. Μερική λύση αλλά καταστρέφεται η επαναχρησιμοποίηση του κώδικα (reuse) για αυτές τις συμπεριφορές. Κάποιο σχεδιαστικό πρότυπο; (αφήστε το για μετά).

Ας πάρουμε την 1η καλή σχεδιαστική αρχή της αντκειμενοστρέφειας: Πάρε όλη την συμπεριφορά που μεταβάλλεται και ενθυλάκωσέ την Πάρε όλη την συμπεριφορά που μεταβάλλεται και ενθυλάκωσέ την ((encapsulate), encapsulate), έτσι δεν θα επηρεάζει τον υπόλοιπο κώδικα σου.έτσι δεν θα επηρεάζει τον υπόλοιπο κώδικα σου.

Μια λύση να ξεχωρίσουμε συμπεριφορές κάνοντας τες διεπαφές, εδώ τις συμπεριφορές fly και quack. Οι διεπαφές Flyable και Quackable έχουν αντίστοιχα μια μέθοδο fly() και μια μέθοδο quack() για να υλοποιούνται από τις υποκλάσεις που τις χρειάζονται. Μερική λύση αλλά καταστρέφεται η επαναχρησιμοποίηση του κώδικα (reuse) για αυτές τις συμπεριφορές. Κάποιο σχεδιαστικό πρότυπο; (αφήστε το για μετά).

Ας πάρουμε την 1η καλή σχεδιαστική αρχή της αντκειμενοστρέφειας: Πάρε όλη την συμπεριφορά που μεταβάλλεται και ενθυλάκωσέ την Πάρε όλη την συμπεριφορά που μεταβάλλεται και ενθυλάκωσέ την ((encapsulate), encapsulate), έτσι δεν θα επηρεάζει τον υπόλοιπο κώδικα σου.έτσι δεν θα επηρεάζει τον υπόλοιπο κώδικα σου.

Παναγιώτης Σφέτσος, Μεθοδολογίες Προγραμματισμού ΙΙ 5

ΥπερΚλάσεις – Αφηρημένες και Διεπαφές (3/11) ΥπερΚλάσεις – Αφηρημένες και Διεπαφές (3/11)

Page 6: Μεθοδολογίες Προγραμματισμού ΙΙ Σχεδιαστικά Πρότυπα (2)

Ορίζουμε δύο διεπαφές τις FlyBehavior και QuackBehavior με τις αντίστοιχες υποκλάσεις να υλοποιούν συγκεκριμένες συμπεριφορές.

Έτσι: α) και άλλες υποκλάσεις μπορούν να χρησιμοποιήσουν αυτές τις συμπεριφορές, δεν είναι κρυμμένες πλέον στην κλάση Duck.

β) μπορούμε να προσθέσουμε οποιαδήποτε άλλη συμπεριφορά χωρίς αλλαγές στην κλάση Duck ή στις κλάσεις συμπεριφορών.

Αρκεί στην κλάση Duck να προσθέσουμε δύο μεταβλητές που να αναφέρονται στις δύο συμπεριφορές:

Ορίζουμε δύο διεπαφές τις FlyBehavior και QuackBehavior με τις αντίστοιχες υποκλάσεις να υλοποιούν συγκεκριμένες συμπεριφορές.

Έτσι: α) και άλλες υποκλάσεις μπορούν να χρησιμοποιήσουν αυτές τις συμπεριφορές, δεν είναι κρυμμένες πλέον στην κλάση Duck.

β) μπορούμε να προσθέσουμε οποιαδήποτε άλλη συμπεριφορά χωρίς αλλαγές στην κλάση Duck ή στις κλάσεις συμπεριφορών.

Αρκεί στην κλάση Duck να προσθέσουμε δύο μεταβλητές που να αναφέρονται στις δύο συμπεριφορές:

Παναγιώτης Σφέτσος, Μεθοδολογίες Προγραμματισμού ΙΙ 6

ΥπερΚλάσεις – Αφηρημένες και Διεπαφές (4/11) ΥπερΚλάσεις – Αφηρημένες και Διεπαφές (4/11)

Page 7: Μεθοδολογίες Προγραμματισμού ΙΙ Σχεδιαστικά Πρότυπα (2)

public abstract class Duck { FlyBehavior flyBehavior; QuackBehavior quackBehavior;

public Duck() {}

abstract void display();

public void performFly() {flyBehavior.fly();} public void performQuack() {quackBehavior.quack();} public void swim() {System.out.println("Kolympa....");}}

public class MallardDuck extends Duck {public class MallardDuck extends Duck { public MallardDuck() {public MallardDuck() { quackBehaviorquackBehavior = new Quack(); = new Quack(); flyBehavior flyBehavior = new FlyWithWings();}= new FlyWithWings();} public void display() public void display() {System.out.println("Agriohina....");{System.out.println("Agriohina....");}}}}

public abstract class Duck { FlyBehavior flyBehavior; QuackBehavior quackBehavior;

public Duck() {}

abstract void display();

public void performFly() {flyBehavior.fly();} public void performQuack() {quackBehavior.quack();} public void swim() {System.out.println("Kolympa....");}}

public class MallardDuck extends Duck {public class MallardDuck extends Duck { public MallardDuck() {public MallardDuck() { quackBehaviorquackBehavior = new Quack(); = new Quack(); flyBehavior flyBehavior = new FlyWithWings();}= new FlyWithWings();} public void display() public void display() {System.out.println("Agriohina....");{System.out.println("Agriohina....");}}}}

Παναγιώτης Σφέτσος, Μεθοδολογίες Προγραμματισμού ΙΙ 7

ΥπερΚλάσεις – Αφηρημένες και Διεπαφές (ΥπερΚλάσεις – Αφηρημένες και Διεπαφές (55/11) /11)

Page 8: Μεθοδολογίες Προγραμματισμού ΙΙ Σχεδιαστικά Πρότυπα (2)

public interface FlyBehavior {public void fly();}

public class FlyWithWings implements FlyBehavior { public void fly(){System.out.println("Petaei...");}}

public class FlyNoWay implements FlyBehavior { public void fly(){System.out.println("den petaei...");}}

public interface QuackBehavior {public void quack();}

public class Quack implements QuackBehavior { public void quack(){System.out.println("quack..quack");}}

public class MuteQuack implements QuackBehavior { public void quack(){System.out.println("siopi..tipote");}}

public class Squeak implements QuackBehavior { public void quack(){System.out.println("tsirida...");}}

public interface FlyBehavior {public void fly();}

public class FlyWithWings implements FlyBehavior { public void fly(){System.out.println("Petaei...");}}

public class FlyNoWay implements FlyBehavior { public void fly(){System.out.println("den petaei...");}}

public interface QuackBehavior {public void quack();}

public class Quack implements QuackBehavior { public void quack(){System.out.println("quack..quack");}}

public class MuteQuack implements QuackBehavior { public void quack(){System.out.println("siopi..tipote");}}

public class Squeak implements QuackBehavior { public void quack(){System.out.println("tsirida...");}}

Παναγιώτης Σφέτσος, Μεθοδολογίες Προγραμματισμού ΙΙ 8

ΥπερΚλάσεις – Αφηρημένες και Διεπαφές (ΥπερΚλάσεις – Αφηρημένες και Διεπαφές (66/11) /11)

Page 9: Μεθοδολογίες Προγραμματισμού ΙΙ Σχεδιαστικά Πρότυπα (2)

class MiniDuckSimulator { public static void main(String[] args) {

Duck mallard = new MallardDuck(); mallard.performQuack(); mallard.performFly();}}

class MiniDuckSimulator { public static void main(String[] args) {

Duck mallard = new MallardDuck(); mallard.performQuack(); mallard.performFly();}}

Παναγιώτης Σφέτσος, Μεθοδολογίες Προγραμματισμού ΙΙ 9

ΥπερΚλάσεις – Αφηρημένες και Διεπαφές (ΥπερΚλάσεις – Αφηρημένες και Διεπαφές (77/11) /11)

Page 10: Μεθοδολογίες Προγραμματισμού ΙΙ Σχεδιαστικά Πρότυπα (2)

Αν προσθέσουμε δύο μεθόδους setter στην κλάση Duck για τις συμπεριφορές fly και quak τις:

public void setFlyBehavior(FlyBehavior fb) {flyBehavior = fb;} public void setQuackBehavior(QuackBehavior qb) {QuackBehavior = qb;}

Αν προσθέσουμε δύο μεθόδους setter στην κλάση Duck για τις συμπεριφορές fly και quak τις:

public void setFlyBehavior(FlyBehavior fb) {flyBehavior = fb;} public void setQuackBehavior(QuackBehavior qb) {QuackBehavior = qb;}

Παναγιώτης Σφέτσος, Μεθοδολογίες Προγραμματισμού ΙΙ 10

ΥπερΚλάσεις – Αφηρημένες και Διεπαφές (ΥπερΚλάσεις – Αφηρημένες και Διεπαφές (88/11) /11)

Τότε μπορούμε να αλλάξουμε δυναμικά μια συμπεριφορά (on the fly).Αρκεί να κάνουμε τις παρακάτω αλλαγές:

Page 11: Μεθοδολογίες Προγραμματισμού ΙΙ Σχεδιαστικά Πρότυπα (2)

1) Προσθέσουμε μια νέα κλάση πάπιας την ModelDuck:

public class ModelDuck extends Duck {public class ModelDuck extends Duck { public ModelDuck() {public ModelDuck() { quackBehaviorquackBehavior = new Quack(); = new Quack(); flyBehavior flyBehavior = new FlyNoWay();}= new FlyNoWay();} public void display() public void display() {System.out.println(“Model papia....");{System.out.println(“Model papia....");}}}}

2) Και μια νέα συμπεριφορά την FlyRocketPowered :

public class FlyRocketPowered implements FlyBehavior { public void fly(){System.out.println(“petaei san piravlos..");}}

1) Προσθέσουμε μια νέα κλάση πάπιας την ModelDuck:

public class ModelDuck extends Duck {public class ModelDuck extends Duck { public ModelDuck() {public ModelDuck() { quackBehaviorquackBehavior = new Quack(); = new Quack(); flyBehavior flyBehavior = new FlyNoWay();}= new FlyNoWay();} public void display() public void display() {System.out.println(“Model papia....");{System.out.println(“Model papia....");}}}}

2) Και μια νέα συμπεριφορά την FlyRocketPowered :

public class FlyRocketPowered implements FlyBehavior { public void fly(){System.out.println(“petaei san piravlos..");}}

Παναγιώτης Σφέτσος, Μεθοδολογίες Προγραμματισμού ΙΙ 11

ΥπερΚλάσεις – Αφηρημένες και Διεπαφές (ΥπερΚλάσεις – Αφηρημένες και Διεπαφές (99/11) /11)

Page 12: Μεθοδολογίες Προγραμματισμού ΙΙ Σχεδιαστικά Πρότυπα (2)

Αλλάζουμε την εκτέλεση:

class MiniDuckSimulator { public static void main(String[] args) {

Duck mallard = new MallardDuck(); mallard.performQuack(); mallard.performFly();

Duck model = new ModelDuck(); model.performFly(); model.setFlyBehavior(new FlyRocketPowered()); model.performFly();}}

Αλλάζουμε την εκτέλεση:

class MiniDuckSimulator { public static void main(String[] args) {

Duck mallard = new MallardDuck(); mallard.performQuack(); mallard.performFly();

Duck model = new ModelDuck(); model.performFly(); model.setFlyBehavior(new FlyRocketPowered()); model.performFly();}}

Παναγιώτης Σφέτσος, Μεθοδολογίες Προγραμματισμού ΙΙ 12

ΥπερΚλάσεις – Αφηρημένες και Διεπαφές (ΥπερΚλάσεις – Αφηρημένες και Διεπαφές (1010/11) /11)

Αλλάζει δυναμικά ησυμπεριφορά:

Page 13: Μεθοδολογίες Προγραμματισμού ΙΙ Σχεδιαστικά Πρότυπα (2)

Τελικά εκτελέσαμε το σχεδιαστικό πρότυπο Strategy (Στρατηγική) : Διαφορετικοί αλγόριθμοι υλοποιούνται σαν συγκεκριμένες υποκλάσεις της διασύνδεσης – διεπαφής.

Τελικά εκτελέσαμε το σχεδιαστικό πρότυπο Strategy (Στρατηγική) : Διαφορετικοί αλγόριθμοι υλοποιούνται σαν συγκεκριμένες υποκλάσεις της διασύνδεσης – διεπαφής.

Παναγιώτης Σφέτσος, Μεθοδολογίες Προγραμματισμού ΙΙ 13

Ενθυλακωμένες Συμπεριφορές (Ενθυλακωμένες Συμπεριφορές (encapsulated) encapsulated) ((111/11) 1/11)

Page 14: Μεθοδολογίες Προγραμματισμού ΙΙ Σχεδιαστικά Πρότυπα (2)

Παναγιώτης Σφέτσος, Μεθοδολογίες Προγραμματισμού ΙΙ 14

Factory Method (Factory Method (Εργοστάσιο) (1/7) Εργοστάσιο) (1/7)

Κατηγορία: Creational

Σκοπός: Δημιουργία στιγμιοτύπων κλάσεων με τις υποκλάσεις να αποφασίζουν για το ποια θα χρησιμοποιηθεί για τη δημιουργία του στιγμιοτύπου. Ο πελάτης δεν γνωρίζει και δεν ασχολείται με την δημιουργία των στιγμιοτύπων.

Συνώνυμα: virtual constructor

Page 15: Μεθοδολογίες Προγραμματισμού ΙΙ Σχεδιαστικά Πρότυπα (2)

Παναγιώτης Σφέτσος, Μεθοδολογίες Προγραμματισμού ΙΙ 15

Factory Method (Factory Method (Εργοστάσιο) (2/7) Εργοστάσιο) (2/7)

Λειτουργία:Ο πελάτης (client) ζητά από τo Factory την δημιουργία ενός στιγμιότυπου τύπου product. Το Factory το δημιουργεί και το επιστρέφει στον πελάτη. Ο πελάτης δεν γνωρίζει και δενασχολείται με τον τρόπο δημιουργίας και αρχικοποίησης του στιγμιοτύπου.

Η κλάση xx με τις υποκλάσεις xyxy και xzxz. Η Factory αποφασίζει ποια υποκλάση (στιγμιότυπο) θα επιστρέψει ανάλογα με τις παραμέτρους που ορίζονται. Η μέθοδος

getClass() με παράμετρο abc επιστρέφει μια υποκλάση της x.

Page 16: Μεθοδολογίες Προγραμματισμού ΙΙ Σχεδιαστικά Πρότυπα (2)

Παναγιώτης Σφέτσος, Μεθοδολογίες Προγραμματισμού ΙΙ 16

Factory Method (Factory Method (Εργοστάσιο) (Εργοστάσιο) (33/7) /7)

Γιατί όχι η χρήση του τελεστή Γιατί όχι η χρήση του τελεστή new;new; π.χ. Pelatis pelatis = new Pelatis(code, AKM,…,);

οποιαδήποτε αλλαγή στην κλάση Pelatis, θα επιφέρει αλλαγές και στις κλάσεις που εξαρτώνται από αυτήν (δομητής, κώδικας, κλπ.). Παραβίαση της αρχής της Αντιστροφής των Εξαρτήσεων (όχι πάντα, π.χ. μια μόνο κλάση).

κώδικας με χρήση πολλών if else ή switch – εντολών για την δημιουργία των αντικειμένων, στοιχεία που υποδηλώνουν κακή εφαρμογή των αρχών του αντικειμενοστρεφούς προγραμματισμού, καθώς δυσχεραίνουν τη συντήρηση του λογισμικού.

υλοποιούμε αφηρημένες κλάσεις ή διεπαφές. Δεν εξαρτόμαστε από συγκεκριμένες κλάσεις.

Page 17: Μεθοδολογίες Προγραμματισμού ΙΙ Σχεδιαστικά Πρότυπα (2)

Παναγιώτης Σφέτσος, Μεθοδολογίες Προγραμματισμού ΙΙ 17

Factory Method (Factory Method (Εργοστάσιο) (4/7) Εργοστάσιο) (4/7)

Δύο παραλλαγές:

11ηη Η Η Factory Factory είναι απλή κλάσηείναι απλή κλάση.. 22ηη Η Η Factory Factory είναι είναι abstract abstract ή ή interface.interface.

Page 18: Μεθοδολογίες Προγραμματισμού ΙΙ Σχεδιαστικά Πρότυπα (2)

Παναγιώτης Σφέτσος, Μεθοδολογίες Προγραμματισμού ΙΙ 18

Factory Method (Factory Method (Εργοστάσιο) (5/7) Εργοστάσιο) (5/7) Η Factory είναι απλή κλάσηabstract class Mammals { public abstract String VgazoVolta(); }

class Cat extends Mammals { public String VgazoVolta() { return "Tha pav volta tin gata“; }}

class Dog extends Mammals { public String VgazoVolta() { return "Tha pav volta ton skylo"; }}

class MammalsFactory { public static Mammals getMammalObject(String name) { if (name.equalsIgnoreCase("gata")){ return new Cat(); } else { return new Dog(); } }}

class FactoryClient { public static void main(String args[]) { MammalsFactory mf = new MammalsFactory(); System.out.println(mf.getMammalObject("skylos").VgazoVolta()); }}

Page 19: Μεθοδολογίες Προγραμματισμού ΙΙ Σχεδιαστικά Πρότυπα (2)

Παναγιώτης Σφέτσος, Μεθοδολογίες Προγραμματισμού ΙΙ 19

Factory Method (Factory Method (Εργοστάσιο) (6/7) Εργοστάσιο) (6/7) Η Factory είναι κλάση abstract - ή interface – (1/2):

interface Product { }

class ConcreteProduct implements Product { }

abstract class Factory { public void anOperation() { Product product = factoryMethod(); System.out.println("3-dimiourgia antik. product kalontas tin factoryMethod() tis ConcreteFactory-> "); System.out.println("Product product = factoryMethod();"); System.out.println("To antikeimeno product dimiourgithike"); }

protected abstract Product factoryMethod(); }

class ConcreteFactory extends Factory { protected Product factoryMethod() { return new ConcreteProduct(); }}

Page 20: Μεθοδολογίες Προγραμματισμού ΙΙ Σχεδιαστικά Πρότυπα (2)

Παναγιώτης Σφέτσος, Μεθοδολογίες Προγραμματισμού ΙΙ 20

Factory Method (Factory Method (Εργοστάσιο) (7/7) Εργοστάσιο) (7/7) Η Factory είναι abstract - ή interface κλάση – (2/2):

class Client { public static void main( String arg[] ) { System.out.println("1- dimiourgia antik. tis ConcreteFactory->"); System.out.println("Factory creator = new ConcreteFactory();"); System.out.println(); System.out.println(); Factory Factory = new ConcreteFactory(); System.out.println("2- klisi tis anOperation(), tis Factory, gia dhmiourgia antik. typou product-> "); System.out.println("Factory.anOperation();"); System.out.println(); System.out.println(); Factory.anOperation(); }}

Page 21: Μεθοδολογίες Προγραμματισμού ΙΙ Σχεδιαστικά Πρότυπα (2)

Παναγιώτης Σφέτσος, Μεθοδολογίες Προγραμματισμού ΙΙ 21

Abstract FactoryAbstract Factory ((Αφηρημένο Εργοστάσιο) (1/6) Αφηρημένο Εργοστάσιο) (1/6)

Κατηγορία: Creational

Σκοπός: Η παροχή μιας διασύνδεσης για τη δημιουργία οικογενειών συσχετιζόμενων ή εξαρτημένων αντικειμένων χωρίς να προσδιορίζεται η συγκεκριμένη κλάση τους.

Συνώνυμα: super factory, factory of factories

Page 22: Μεθοδολογίες Προγραμματισμού ΙΙ Σχεδιαστικά Πρότυπα (2)

Παναγιώτης Σφέτσος, Μεθοδολογίες Προγραμματισμού ΙΙ 22

Abstract FactoryAbstract Factory ((Αφηρημένο Εργοστάσιο) (Αφηρημένο Εργοστάσιο) (22/6) /6)

Το πρότυπο αυτό αποτελεί ένα υψηλότερο επίπεδο αφαίρεσης από το Factory.

Επιστρέφει μια από πολλές συσχετιζόμενες κλάσεις, κάθε μια από τις οποίες μπορεί να επιστρέψει ένα ή περισσότερα αντικείμενα, ανάλογα με την απαίτηση του πελάτη. Δηλαδή το Abstract Factory είναι ένα Factory- αντικείμενο που επιστρέφει ένα ή περισσότερα Factories.

Τα ονόματα των κλάσεων είναι κρυμμένα από τον πελάτη (από το Factory). Αυτό οδηγεί στην εύκολη αλλαγή ή ανταλλαγή των οικογενειών των αντικειμένων.

Είναι δυνατή η προσθήκη επί πλέον μεθόδων σε κάποιες από τις υποκλάσεις.

Page 23: Μεθοδολογίες Προγραμματισμού ΙΙ Σχεδιαστικά Πρότυπα (2)

Παναγιώτης Σφέτσος, Μεθοδολογίες Προγραμματισμού ΙΙ 23

Abstract FactoryAbstract Factory ((Αφηρημένο Εργοστάσιο) (3/6) Αφηρημένο Εργοστάσιο) (3/6)

AbstractFactory - διασύνδεση για λειτουργίες δημιουργίας αφηρημένων - products. ConcreteFactory - υλοποιεί λειτουργίες για την δημιουργία συγκεκριμένων - products. AbstractProduct - διασύνδεση για τον τύπο των αντικειμένων - product. Product - το product που θα δημιουργηθεί από το αντίστοιχο ConcreteFactory. Υλοποιεί την διασύνδεση AbstractProduct. Client - χρησιμοποιεί τις διασυνδέσεις που ορίζουν οι κλάσεις AbstractFactory και AbstractProduct.

Page 24: Μεθοδολογίες Προγραμματισμού ΙΙ Σχεδιαστικά Πρότυπα (2)

Παναγιώτης Σφέτσος, Μεθοδολογίες Προγραμματισμού ΙΙ 24

Abstract FactoryAbstract Factory ((Αφηρημένο Εργοστάσιο) (4/6) Αφηρημένο Εργοστάσιο) (4/6)

Η κλάση AbstractFactory καθορίζει το προς δημιουργία αντικείμενο, το δημιουργεί, καιεπιστρέφει ένα αφηρημένο δείκτη σε αυτό το αντικείμενο. Ο πελάτης δεν γνωρίζει τίποτε για τον τύπο του αντικειμένου. Το αντικείμενο δημιουργείται από το Factory και ο πελάτης έχει πρόσβαση μόνο μέσω της αφηρημένης διασύνδεσης:

abstract class AbstractProductA{public abstract void operationA1();public abstract void operationA2();}

class ProductA1 extends AbstractProductA{ProductA1(String arg){ System.out.println("To product einai: "+arg);}

public void operationA1() { };public void operationA2() { };}

class ProductA2 extends AbstractProductA{ProductA2(String arg){ System.out.println("To product einai: "+arg);}

public void operationA1() { };public void operationA2() { };}

Page 25: Μεθοδολογίες Προγραμματισμού ΙΙ Σχεδιαστικά Πρότυπα (2)

Παναγιώτης Σφέτσος, Μεθοδολογίες Προγραμματισμού ΙΙ 25

Abstract FactoryAbstract Factory ((Αφηρημένο Εργοστάσιο) (Αφηρημένο Εργοστάσιο) (55/6) /6)

abstract class AbstractFactory{ abstract AbstractProductA createProductA(); abstract AbstractProductB createProductB();}

class ConcreteFactory1 extends AbstractFactory{ AbstractProductA createProductA() { return new ProductA1("ProductA1");} AbstractProductB createProductB() { return new ProductB1("ProductB1");}}

class ConcreteFactory2 extends AbstractFactory{AbstractProductA createProductA(){ return new ProductA2("ProductA2");}AbstractProductB createProductB(){ return new ProductB2("ProductB2");}}

//Dimiourgia toy Factoryclass FactoryMaker{ private static AbstractFactory pf=null; static AbstractFactory getFactory(String choice){ if(choice.equals("a")){

pf=new ConcreteFactory1(); }else if(choice.equals("b")){

pf=new ConcreteFactory2(); } return pf; }}

Page 26: Μεθοδολογίες Προγραμματισμού ΙΙ Σχεδιαστικά Πρότυπα (2)

Παναγιώτης Σφέτσος, Μεθοδολογίες Προγραμματισμού ΙΙ 26

Abstract FactoryAbstract Factory ((Αφηρημένο Εργοστάσιο) (Αφηρημένο Εργοστάσιο) (66/6) /6)

class AbstactFactoryClient{ public static void main(String args[]){

AbstractFactory pf=FactoryMaker.getFactory("a");AbstractProductA product=pf.createProductA();AbstractProductB product1=pf.createProductB();

System.out. println();AbstractFactory pf2=FactoryMaker.getFactory("b");

AbstractProductA product2=pf2.createProductA(); AbstractProductB product3=pf2.createProductB();}}

Page 27: Μεθοδολογίες Προγραμματισμού ΙΙ Σχεδιαστικά Πρότυπα (2)

Παναγιώτης Σφέτσος, Μεθοδολογίες Προγραμματισμού ΙΙ 27

““Μέθοδος ΥπόδειγμαΜέθοδος Υπόδειγμα”” ( (Template MethodTemplate Method) (1/7) ) (1/7)

Κατηγορία: Behavioral

Σκοπός: Ορίζει τον σκελετό ενός αλγορίθμου σε μια λειτουργία, αφήνοντας διαφορετικές υλοποιήσεις στις παράγωγες κλάσεις. Δηλαδή, το πρότυπο επιτρέπει στις παράγωγες κλάσεις να επαναορίσουν ορισμένα βήματα του αλγορίθμου χωρίς να αλλάξουν τη δομή του.

Συνώνυμα:-

Page 28: Μεθοδολογίες Προγραμματισμού ΙΙ Σχεδιαστικά Πρότυπα (2)

Παναγιώτης Σφέτσος, Μεθοδολογίες Προγραμματισμού ΙΙ 28

““Μέθοδος ΥπόδειγμαΜέθοδος Υπόδειγμα”” ( (Template MethodTemplate Method) (2/7) ) (2/7)

Επιλύει ένα παρόμοιο πρόβλημα με αυτό του προτύπου "Στρατηγική". Στόχος: ο διαχωρισμός ενός γενικού αλγορίθμου από συγκεκριμένες υλοποιήσεις.

Χρησιμοποιείται για τον ορισμό των αμεταβλήτων τμημάτων και τη μετάθεση της υλοποίησης των μεταβλητών τμημάτων του αλγορίθμου σε παράγωγες κλάσεις.

Στο πρότυπο “Μέθοδος Υπόδειγμα” εφαρμόζεται ο μηχανισμός της κληρονομικότητας και πολυμορφισμού, ενώ στη “Στρατηγική” η μεταφορά αρμοδιότητας σε ένα άλλο αντικείμενο μέσω της διαβίβασης μηνυμάτων (delegation),.

Πολύ συχνά οι σχεδιαστές και προγραμματιστές αντικειμενοστρεφούς λογισμικού χρησιμοποιούν το πρότυπο, ακόμα και αν δεν γίνεται αντιληπτό ως ξεχωριστή τεχνική.

Page 29: Μεθοδολογίες Προγραμματισμού ΙΙ Σχεδιαστικά Πρότυπα (2)

Παναγιώτης Σφέτσος, Μεθοδολογίες Προγραμματισμού ΙΙ 29

““Μέθοδος ΥπόδειγμαΜέθοδος Υπόδειγμα” ” ( (Template MethodTemplate Method) (3/7) ) (3/7)

Παράδειγμα 1Παράδειγμα 1οο::Για να δώσει ένα δάνειο μια τράπεζα σε ένα πελάτη θα κάνει πολλούς ελέγχους για να διαπιστώσει αν ο πελάτης είναι αξιόπιστος, π.χ. checkBank(), checkCredit(), checkLoan(), checkStock(), checkIncome(), κλπ. Θα χρησιμοποιήσουμε ένα πρότυπο “Μέθοδος Υπόδειγμα” για τους ελέγχους αυτούς στην αφηρημένη κλάση CheckBackground και την υλοποίηση στις υποκλάσεις.

abstract class CheckBackground {abstract class CheckBackground { public abstract void checkBank(); public abstract void checkCredit(); public abstract void checkLoan(); public abstract void checkStock(); public abstract void checkIncome();

//template method public void check() {public void check() { checkBank(); checkCredit(); checkLoan(); checkStock(); checkIncome();}}

Page 30: Μεθοδολογίες Προγραμματισμού ΙΙ Σχεδιαστικά Πρότυπα (2)

Παναγιώτης Σφέτσος, Μεθοδολογίες Προγραμματισμού ΙΙ 30

““Μέθοδος ΥπόδειγμαΜέθοδος Υπόδειγμα” ” ( (Template MethodTemplate Method) () (44/7) /7)

class LoanApp extends CheckBackground { private String name; public LoanApp(String name) {this.name = name;} public String getName() {return name;} public void checkBank() {System.out.println("check bank..."); } public void checkCredit(){System.out.println("check credit..."); } public void checkLoan() {System.out.println("check loan..."); } public void checkStock() {System.out.println("check stock values..."); } public void checkIncome(){System.out.println("check family income..."); }}

class TestTemplateMethod { public static void main(String[] args) { LoanApp mortgageClient = new LoanApp("Nikas Nikos"); System.out.println("\nAxiopistia pelati: " + mortgageClient.getName()); mortgageClient.check(); LoanApp equityloanClient = new LoanApp("Vasileiou Vasilis"); System.out.println("\nAxiopistia pelati: " + equityloanClient.getName()); equityloanClient.check(); }}

Page 31: Μεθοδολογίες Προγραμματισμού ΙΙ Σχεδιαστικά Πρότυπα (2)

Παναγιώτης Σφέτσος, Μεθοδολογίες Προγραμματισμού ΙΙ 31

““Μέθοδος ΥπόδειγμαΜέθοδος Υπόδειγμα” ” ( (Template MethodTemplate Method) () (55/7) /7)

Η υλοποίηση γίνεται στην παραγόμενη κλάση LoanApp.

Page 32: Μεθοδολογίες Προγραμματισμού ΙΙ Σχεδιαστικά Πρότυπα (2)

Παναγιώτης Σφέτσος, Μεθοδολογίες Προγραμματισμού ΙΙ 32

““Μέθοδος ΥπόδειγμαΜέθοδος Υπόδειγμα” ” ((Template MethodTemplate Method) () (66/7) /7)

Παράδειγμα Παράδειγμα 2 2οο ( (Πολυμορφισμός)Πολυμορφισμός)::Πρόσθεση διαφορετικού τύπου αριθμών π.χ. int, double, κλπ. Προσοχή πρέπει να χρησιμοποιηθεί casting για να πάρουμε σωστά αποτελέσματα.

abstract class Prosthesi { public abstract double prosthesi(double d1, double d2); //template method}

class ProsthesiAnyTypeNumber extends Prosthesi { public double prosthesi(double d1, double d2) { return d1 + d2; }}

Page 33: Μεθοδολογίες Προγραμματισμού ΙΙ Σχεδιαστικά Πρότυπα (2)

Παναγιώτης Σφέτσος, Μεθοδολογίες Προγραμματισμού ΙΙ 33

““Μέθοδος ΥπόδειγμαΜέθοδος Υπόδειγμα” ” ((Template MethodTemplate Method) (7/7) ) (7/7)

class TestAdd { public static void main(String[] args) { double d1 = 10.5, d2 = 9.5; float f1 = 11.5f, f2 = 12.5f; long l1 = 1, l2 = 2; int i1 = 3, i2 = 4; short s1 = 7, s2 = 8; byte b1 = 5, b2 = 6; ProsthesiAnyTypeNumber addNumber = new ProsthesiAnyTypeNumber(); System.out.println(addNumber.prosthesi(d1,d2)); System.out.println((float)addNumber.prosthesi(f1,f2)); System.out.println((long)addNumber.prosthesi(l1,l2)); System.out.println((int)addNumber.prosthesi(i1,i2)); System.out.println((short)addNumber.prosthesi(s1,s2)); System.out.println((byte)addNumber.prosthesi(b1,b2)); }}