English

Java Design Patterns

JAVA II - Χαροκόπειο Πανεπιστήμιο

https://dit.hua.gr/index.php/el/

 

 

Απαραίτητα Java Design Patterns που πρέπει να γνωρίζεται

 

Σε αυτή την ανάρτηση, θα εξηγήσω τα σχέδια σχεδίασης, την αναγκαιότητά τους και θα εμβαθύνω σε κάποια από τα πιο δημοφιλή, όπως τα Singleton, Strategy, Factory, Abstract Factory και Builder.

Τι είναι τα Design Patterns;

Τα (Design Patterns) σχέδια σχεδίασης είναι επαναχρησιμοποιήσιμες λύσεις σε επαναλαμβανόμενα προβλήματα στην ανάπτυξη λογισμικού. Αντιπροσωπεύουν τις βέλτιστες πρακτικές για την επίλυση ορισμένων τύπων προβλημάτων με έναν συνεκτικό, αποδοτικό και συντηρήσιμο τρόπο, προκειμένου να σχεδιάσουμε ισχυρά συστήματα λογισμικού.

Το διάσημο βιβλίο “Design Patterns: Elements of Reusable Object-Oriented Software”, γνωστό και ως βιβλίο GoF, δημοσιεύθηκε τη δεκαετία του '90. Κατέγραψε 23 σχέδια σχεδίασης και γράφτηκε από τους Erich Gamma, Richard Helm, Ralph Johnson και John Vlissides — τους συγγραφείς της «Συμμορίας των Τεσσάρων» (Gang of Four, GoF).

Τα σχέδια είναι οργανωμένα σε τρεις κύριες κατηγορίες:

Δημιουργικά Σχέδια Σχεδίασης (Creational Design Patterns):

Αυτά παρέχουν τρόπους δημιουργίας αντικειμένων ενώ κρύβουν τις λεπτομέρειες υλοποίησης του πώς δημιουργούνται τα αντικείμενα. Απομονώνουν τη διαδικασία δημιουργίας, κάνοντάς την πιο ευέλικτη και επεκτάσιμη.

Ορισμένα κοινά δημιουργικά σχέδια σχεδίασης είναι: Singleton, Factory, Abstract Factory, Builder και Prototype.

Δομικά Σχέδια Σχεδίασης (Structural Design Patterns):

Αυτά αφορούν τη σύνθεση κλάσεων και αντικειμένων για τη δημιουργία μεγαλύτερων δομών, έτσι ώστε να συνεργάζονται αποτελεσματικά.

Ορισμένα κοινά δομικά σχέδια σχεδίασης είναι: Adapter, Bridge, Composite, Decorator, Facade και Proxy.

Συμπεριφορικά Σχέδια Σχεδίασης (Behavioral Design Patterns):

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

Τα Οφέλη των Σχεδίων Σχεδίασης

  • Επαναχρησιμοποίηση: Παρέχουν λύσεις σε κοινά προβλήματα που μπορούν να επαναχρησιμοποιηθούν σε διάφορα έργα.
  • Ευελιξία: Κάνουν τον κώδικά μας ευέλικτο και προσαρμόσιμο σε αλλαγές. Επιτρέπουν τη μετατροπή του κώδικα με ελάχιστο αντίκτυπο στον υπάρχοντα κώδικα.
  • Συνεργασία: Είναι ευρέως γνωστά στους προγραμματιστές. Μπορούμε να κατανοήσουμε και να συνεισφέρουμε στον κώδικα εύκολα.
  • Επίλυση Προβλημάτων: Μας βοηθούν να λύσουμε επαναλαμβανόμενα προβλήματα σχεδίασης χρησιμοποιώντας τις καλύτερες λύσεις.

Αυτό συμβαδίζει πλήρως με την αρχή του Solid, την αρχή ανοιχτής-κλειστής: ανοιχτό για επέκταση, αλλά κλειστό για τροποποίηση.

 

Singleton Pattern:

Χρησιμοποιούμε το σχέδιο Singleton όταν χρειαζόμαστε να έχουμε μόνο μία παρουσία της κλάσης μας και να παρέχουμε ένα παγκόσμιο σημείο πρόσβασης σε αυτήν.

Υπάρχουν δύο μορφές του σχεδίου Singleton:

  1. Πρόωρη δημιουργία (Early instantiation): Δημιουργούμε την παρουσία κατά τη φόρτωση της εφαρμογής.
  2. Καθυστερημένη δημιουργία (Lazy instantiation): Δημιουργούμε την παρουσία όταν απαιτείται.

Για να δημιουργήσουμε την κλάση Singleton, πρέπει να έχουμε τα εξής:

  • Στατικό μέλος της κλάσης: Ένα στατικό πεδίο για να αποθηκεύσουμε τη μοναδική παρουσία της κλάσης.
  • Ιδιωτικός κατασκευαστής (private constructor): Ο κατασκευαστής πρέπει να είναι ιδιωτικός για να αποτρέψει τη δημιουργία νέων αντιγράφων της κλάσης από έξω.
  • Στατική μέθοδος εργοστασίου (static factory method): Παρέχει το παγκόσμιο σημείο πρόσβασης για το αντικείμενο Singleton και επιστρέφει την παρουσία στην κλάση πελάτη.

Εδώ είναι ένα παράδειγμα υλοποίησης του σχεδίου Singleton με πρόωρη δημιουργία (eager loading):

public class NotificationService {

    // Can also be initialized in a static block
    private static final NotificationService instance = new NotificationService();

    private NotificationService() {
    }

    public static NotificationService getInstance() {
        return instance;
    }

    public void sendNotification(String message) {
        // Logic to send notification
        System.out.println("Notification sent " + message);
    }
}


Factory Pattern

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

Για να το υλοποιήσουμε, πρέπει να δημιουργήσουμε μια διεπαφή (interface) για τη δημιουργία αντικειμένων, και να έχουμε συγκεκριμένες κλάσεις που υλοποιούν αυτή την διεπαφή για να δημιουργούν αντικείμενα συγκεκριμένων τύπων.

Εδώ είναι ένα παράδειγμα για τη δημιουργία διαφορετικών μεθόδων πληρωμής:

// Payment interface
public interface Payment {
    void processPayment();
}

// Implementations of Payment interface
public class CreditCardPayment implements Payment {

    @Override
    public void processPayment() {
        System.out.println("Processing payment using Credit Card...");
    }
}

public class PayPalPayment implements Payment {

    @Override
    public void processPayment() {
        System.out.println("Processing payment using PayPal...");
    }
}


public class PaymentFactory {

    public static Payment createPayment(PayMethod payMethod) {
      if (payMethod == PayMethod.CREDIT_CARD) {
        return new CreditCardPayment();
      } else if (payMethod == PayMethod.PayPal) {
        return new PayPalPayment();
      }
    }
  }

public class FactoryClient {

    public static void main(String[] args) {
        // Using the factory to create Credit Card and PayPal payments
        Payment creditCardPayment = PaymentFactory.createPayment(PayMethod.CREDIT_CARD);
        creditCardPayment.processPayment();

        Payment payPalPayment = PaymentFactory.createPayment(PayMethod.PayPal);;
        payPalPayment.processPayment();
    }
}


Επεξήγηση:

  1. PaymentMethod: Είναι η διεπαφή που καθορίζει τη μέθοδο processPayment, την οποία θα υλοποιούν οι κλάσεις πληρωμών.
  2. CreditCardPayment και PayPalPayment: Είναι οι συγκεκριμένες υλοποιήσεις της διεπαφής PaymentMethod, που καθορίζουν πώς να επεξεργαστούμε τις πληρωμές μέσω πιστωτικής κάρτας και PayPal αντίστοιχα.
  3. PaymentFactory: Παρέχει τη μέθοδο getPaymentMethod, η οποία δημιουργεί το κατάλληλο αντικείμενο πληρωμής βάσει του τύπου πληρωμής που δίνεται ως παράμετρος.
  4. PaymentDemo: Το κύριο πρόγραμμα που δείχνει πώς να χρησιμοποιούμε το εργοστάσιο για να δημιουργήσουμε και να επεξεργαστούμε τις πληρωμές.

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

Leave a Reply