====== Facade Pattern ====== Το Facade Pattern (Μοτίβο Πρόσοψης) ανήκει στα Structural Design Patterns (Δομικά Μοτίβα Σχεδιασμού). Ο κύριος στόχος του είναι να παρέχει μια απλή, ενιαία και εύχρηστη διεπαφή (interface) απέναντι σε ένα περίπλοκο σύστημα από κλάσεις ή API. Φανταστείτε το Facade σαν ένα υπάλληλο υποδοχής ξενοδοχείου, που αντί να μεριμνείτε εσείς για φαγητό, καθαρά σεντόνια ή ταξί, μιλάτε απευθείας μόνο με τον υπάλληλο αυτόν και εκείνος αναλαμβάνει να συντονίσει όλες τις εκκρεμότητες. ===== Παράδειγμα - Home Theater Automation Service ===== Ας υποθέσουμε ότι θέλετε να φτιάξετε ένα Home Theater. Για να δείτε μια ταινία, πρέπει χειροκίνητα να: * Nα χαμηλώσετε τα φώτα. * Να ενεργοποιήσετε τον προβολέα (Projector). * Να ενεργοποιήσετε το ηχοσύστημα (Sound System) και να ρυθμίσετε την ένταση. * Να ξεκινήσετε την αναπαραγωγή της ταινίας. Αντί ο Client να καλεί πολλές διαφορετικές μεθόδους, θα φτιάξουμε ένα HomeTheaterFacade για τη διαχείριση του Home Theater. // 1. Το σύστημα φωτισμού class TheaterLights { public void on() { System.out.println("Τα φώτα του δωματίου άναψαν."); } public void dim(int level) { System.out.println("Τα φώτα χαμήλωσαν στο " + level + "%."); } } // 2. Ο προβολέας class Projector { public void on() { System.out.println("Ο προβολέας ενεργοποιήθηκε."); } public void off() { System.out.println("Ο προβολέας απενεργοποιήθηκε."); } public void wideScreenMode() { System.out.println("Ο προβολέας ρυθμίστηκε σε widescreen (16:9)."); } } // 3. Το ηχοσύστημα class SoundSystem { public void on() { System.out.println("Το ηχοσύστημα ενεργοποιήθηκε."); } public void off() { System.out.println("Το ηχοσύστημα απενεργοποιήθηκε."); } public void setVolume(int level) { System.out.println("Η ένταση του ήχου ρυθμίστηκε στο " + level + "."); } } // 4. Η πηγή της ταινίας (π.χ. Streaming Service) class StreamingPlayer { public void on() { System.out.println("Η συσκευή αναπαραγωγής ενεργοποιήθηκε."); } public void play(String movie) { System.out.println("Αναπαραγωγή της ταινίας: '" + movie + "'"); } public void stop() { System.out.println("Η ταινία σταμάτησε."); } public void off() { System.out.println("Η συσκευή αναπαραγωγής απενεργοποιήθηκε."); } } Θα δημιουργήσουμε την κλάση ''Facade'' που λειτουργεί ως πρόσοψη στο περίπλοκο σύστημα ρυθμίσεων που περιγράψαμε. public class HomeTheaterFacade { private TheaterLights lights; private Projector projector; private SoundSystem sound; private StreamingPlayer player; // Ο Constructor δέχεται τα αντικείμενα του υποσυστήματος public HomeTheaterFacade(TheaterLights lights, Projector projector, SoundSystem sound, StreamingPlayer player) { this.lights = lights; this.projector = projector; this.sound = sound; this.player = player; } // Απλοποιημένη μέθοδος για την εκκίνηση της ταινίας public void watchMovie(String movie) { System.out.println("\n--- Getting ready for the movie... ---"); lights.dim(10); projector.on(); projector.wideScreenMode(); sound.on(); sound.setVolume(20); player.on(); player.play(movie); System.out.println("--- Movie Started! ---\n"); } // Απλοποιημένη μέθοδος για τον τερματισμό public void endMovie() { System.out.println("\n--- Shuttting down Home Theater... ---"); lights.on(); projector.off(); sound.off(); player.stop(); player.off(); System.out.println("--- Done. ---\n"); } } Δείτε πόσο απλός γίνεται ο κώδικας του πελάτη που χρησιμοποιεί την κλάση ''HomeTheaterFacade'', καθώς δε χρειάζται να έχει καμία γνώση για το πως λειτουργεί εσωτερικά το σύστημα. public class HomeTheaterUser { public static void main(String[] args) { // Δημιουργία των εξαρτημάτων του υποσυστήματος TheaterLights lights = new TheaterLights(); Projector projector = new Projector(); SoundSystem sound = new SoundSystem(); StreamingPlayer player = new StreamingPlayer(); // Δημιουργία της πρόσοψης HomeTheaterFacade homeTheater = new HomeTheaterFacade(lights, projector, sound, player); // Ο χρήστης με μία μόνο εντολή ξεκινάει την ταινία homeTheater.watchMovie("Inception"); // ... περνάει η ώρα και τελειώνει η ταινία ... // Ο χρήστης κλείνει τα πάντα με μία εντολή homeTheater.endMovie(); } } ==== Πλεονεκτήματα: ==== * **Μείωση Πολυπλοκότητας:** Απομονώνει τον Client από τα πολύπλοκα υποσυστήματα. * **Χαλαρή Σύζευξη (Loose Coupling):** Αν αύριο αλλάξει ο τρόπος που λειτουργεί το SoundSystem, θα χρειαστεί να αλλάξει μόνο η κλάση Facade και όχι ολόκληρη η εφαρμογή μας. * **Ευκολία στη χρήση:** Ιδανικό όταν ενσωματώνουμε μεγάλες, κακογραμμένες ή παλιές (legacy) βιβλιοθήκες τρίτων. 💡 **Σημείωση:** Το Facade Pattern δεν κρύβει απαγορευτικά το υποσύστημα. Αν ένας Client θέλει να προσπεράσει το HomeTheaterFacade και να ρυθμίσει χειροκίνητα μόνο τα φώτα, έχει τη δυνατότητα να το κάνει.