Σε αυτήν τη σειρά μοτίβων σχεδίασης, θα επιθεωρήσουμε το Μοτίβο Σχεδίασης Δόμησης. Θα συνεχίσουμε να μαθαίνουμε τα μοτίβα σχεδίασης και θα καλύψουμε το Μοτίβο Δόμησης.
Μοτίβο σχεδίασης οικοδόμων
ο Μοτίβο σχεδίασης οικοδόμων αποτελεί μέρος της οικογένειας μοτίβων σχεδίασης δημιουργίας και μας βοηθά να δημιουργήσουμε σύνθετα αντικείμενα Java με εύκολο και ευανάγνωστο τρόπο. Μπορούμε να το ορίσουμε ως ένα μοτίβο που διαχωρίζει την κατασκευή ενός αντικειμένου από την αναπαράστασή του. Η υλοποίηση είναι σχετικά απλή για αυτό το μοτίβο. Αυτό το μοτίβο είναι αρκετά παρόμοιο με τα μοτίβα Factory/Abstract Factory. Ωστόσο, η διαφορά είναι ότι το μοτίβο Builder παρέχει περισσότερο έλεγχο πως δημιουργούμε τα πολύπλοκα αντικείμενα.
Μπορούμε να το δούμε στην εργασία και στην πραγματική ζωή. Πάρτε ένα παράδειγμα υπολογιστή, αυτοκινήτου ή ακόμα και μπιφτέκι. Τα κατασκευάζουμε όλα χρησιμοποιώντας το μοτίβο Builder. Ξεκινάμε με τις απαιτούμενες ιδιότητες (ιδιότητες, που είναι απαραίτητα για όλα τα αυτοκίνητα, π.χ. τροχός, φρένο, προβολέας) και προσθέτουμε προαιρετικές ιδιότητες ανάλογα με τις ανάγκες του πελάτη (ιδιότητες όπως ηλιοροφή, δερμάτινα καλύμματα κ.λπ.).
Γιατί χρειαζόμαστε το μοτίβο σχεδίασης κατασκευαστή;
Το μοτίβο σχεδίασης Builder μας επιτρέπει να δημιουργήσουμε αμετάβλητα αντικείμενα με ένα μεγάλο σύνολο χαρακτηριστικών κατάστασης. Ας δούμε μερικούς ακόμη λόγους για τους οποίους χρειαζόμαστε αυτό το μοτίβο:
1. Δεν θέλουμε να δημιουργήσουμε μια αλυσίδα εργολάβων.
2. Δεν θέλουμε να δημιουργήσουμε τον κατασκευαστή με πάρα πολλές παραμέτρους, καθώς θα είναι δύσκολο να το διαχειριστούμε από τον κώδικα πελάτη και δημιουργεί σύγχυση όπως η σειρά των ορισμάτων.
3. Δεν θέλουμε να περάσουμε με προαιρετικά ορίσματα στους κατασκευαστές ως NULL.
Δεν θέλουμε να φτιάξουμε ένα τόσο σύνθετο αντικείμενο χρησιμοποιώντας ένα εργοστασιακό μοτίβο.
1. Πώς λειτουργεί το μοτίβο δόμησης;
Υπάρχουν 3 κύρια μέρη στην υλοποίηση του μοτίβου σχεδιασμού του Builder.
- Προϊόν: Αυτό είναι το πραγματικό αντικείμενο που προσπαθούμε να κατασκευάσουμε, π.χ. ένα αυτοκίνητο, ένας υπολογιστής κ.λπ.
- Οικοδόμος: Αυτή είναι η κύρια μηχανή που κατασκευάζει πολύπλοκα αντικείμενα.
- Εκτελεστής διαθήκης: Αυτός είναι ο κώδικας πελάτη που καλεί τον δημιουργό να δημιουργήσει τα σύνθετα αντικείμενα σύμφωνα με τις ανάγκες του πελάτη.
2. Μοτίβο σχεδίασης Builder σε Java
Ας κατανοήσουμε το μοτίβο σχεδιασμού του builder χρησιμοποιώντας ένα παράδειγμα στην Java. Θα χρησιμοποιήσουμε τον προσωπικό μας υπολογιστή ως προϊόν και θα τον κατασκευάσουμε χρησιμοποιώντας υποχρεωτικές ιδιότητες όπως:
- HDD
- ΕΜΒΟΛΟ
- Μέγεθος οθόνης
Και με ορισμένες προαιρετικές ιδιότητες όπως
- Ενεργοποιημένη κάρτα γραφικών (boolean).
- Ενεργοποιημένο Bluetooth (boolean)
- Ενεργοποιημένη οθόνη αφής (boolean)
- Ενεργοποιημένη κάμερα web (boolean)
Η κλάση builder θα είναι μια στατική ένθετη κλάση εντός της κλάσης υπολογιστών. Ωστόσο, για απλότητα, το κρατάω έξω για να το καταλάβετε καλύτερα.
2.1. Προϊόν
Αυτό είναι το πραγματικό προϊόν που θέλουμε να φτιάξουμε. Όπως αναφέρθηκε παραπάνω, θα έχουμε υποχρεωτικές ιδιότητες που θα υπάρχουν πάντα και προαιρετικές ιδιότητες που μπορεί να αποτελούν ή να μην αποτελούν μέρος όλων των υπολογιστών.
package main.com.kunwar.designpatterns.creational.builder;
/**
* @author Kunwar
* Product Class
* Builder Pattern Class
*/
public class Computer {
//required parameters
private String HDD;
private String RAM;
private String screenSize;
//optional parameters
private boolean isGraphicsCardEnabled;
private boolean isBluetoothEnabled;
private boolean isWebCamEnabled;
private boolean isTouchScreenEnabled;
public String getHDD() {
return HDD;
}
public String getRAM() {
return RAM;
}
public String getScreenSize() {
return screenSize;
}
public boolean isGraphicsCardEnabled() {
return isGraphicsCardEnabled;
}
public boolean isBluetoothEnabled() {
return isBluetoothEnabled;
}
public boolean isWebCamEnabled() {
return isWebCamEnabled;
}
public boolean isTouchScreenEnabled() {
return isTouchScreenEnabled;
}
private Computer(ComputerBuilder builder) {
this.HDD = builder.HDD;
this.RAM = builder.RAM;
this.screenSize = builder.screenSize;
this.isGraphicsCardEnabled = builder.isGraphicsCardEnabled;
this.isBluetoothEnabled = builder.isBluetoothEnabled;
this.isTouchScreenEnabled = builder.isTouchScreenEnabled;
this.isWebCamEnabled = builder.isWebCamEnabled;
this.isWebCamEnabled = builder.isWebCamEnabled;
}
@Override
public String toString() {
return "Computer{" +
"HDD='" + HDD + '\'' +
", RAM='" + RAM + '\'' +
", screenSize='" + screenSize + '\'' +
", isGraphicsCardEnabled=" + isGraphicsCardEnabled +
", isBluetoothEnabled=" + isBluetoothEnabled +
", isWebCamEnabled=" + isWebCamEnabled +
", isTouchScreenEnabled=" + isTouchScreenEnabled +
'}';
}
}
2.2. Οικοδόμος
Το Lombok παρέχει λίγους σχολιασμούς για την εφαρμογή του μοτίβου δημιουργίας χωρίς να γράψει αυτόν τον κώδικα λέβητα.
Αυτή είναι η στατική ένθετη κλάση. θα δημιουργήσει τα αντικείμενα του υπολογιστή σύμφωνα με τις απαιτήσεις του πελάτη. Όπως μπορείτε να δείτε παρακάτω, θα έχει έναν κατασκευαστή που θα λαμβάνει μόνο τις απαιτούμενες παραμέτρους και θα χρησιμοποιεί μεθόδους άλλων ρυθμιστών για την προσθήκη τυχόν προαιρετικών παραμέτρων. Με αυτό, η δημιουργία οποιουδήποτε συμπλέγματος είναι εξαιρετικά εύκολη και καθαρή.
//Builder Class
public static class ComputerBuilder {
// required parameters
private String HDD;
private String RAM;
private String screenSize;
// optional parameters
private boolean isGraphicsCardEnabled;
private boolean isBluetoothEnabled;
private boolean isWebCamEnabled;
private boolean isTouchScreenEnabled;
public ComputerBuilder(String hdd, String ram, String screenSize) {
this.HDD = hdd;
this.RAM = ram;
this.screenSize = screenSize;
}
public ComputerBuilder setGraphicsCardEnabled(boolean isGraphicsCardEnabled) {
this.isGraphicsCardEnabled = isGraphicsCardEnabled;
return this;
}
public ComputerBuilder setBluetoothEnabled(boolean isBluetoothEnabled) {
this.isBluetoothEnabled = isBluetoothEnabled;
return this;
}
public ComputerBuilder setWebCamEnabled(boolean webCamEnabled) {
isWebCamEnabled = webCamEnabled;
return this;
}
public ComputerBuilder setTouchScreenEnabled(boolean touchScreenEnabled) {
isTouchScreenEnabled = touchScreenEnabled;
return this;
}
public Computer build() {
return new Computer(this);
}
}
2.3. Κατηγορία Πελατών
Τέλος, στην κλάση επίδειξης, όπου θα δημιουργήσουμε τρία διαφορετικά μοντέλα υπολογιστών χρησιμοποιώντας το μοτίβο δημιουργίας.
package main.com.kunwar.designpatterns.creational.builder;
/**
* @author Kunwar
* Builder Pattern Client Class
* Create Computer object with mandatory and optional properties
*/
public class BuilderPatternDemo {
public static void main(String[] args) {
Computer model1 = new Computer.ComputerBuilder(
"1 TB", "16 GB", "15.6").setBluetoothEnabled(true)
.setGraphicsCardEnabled(true).setTouchScreenEnabled(true).setWebCamEnabled(true).build();
System.out.println("model1: " + model1.toString());
Computer model2 = new Computer.ComputerBuilder(
"256 GB", "8 GB", "14.6").setBluetoothEnabled(true)
.setGraphicsCardEnabled(true).build();
System.out.println("model2: " + model2.toString());
Computer model3 = new Computer.ComputerBuilder(
"128 GB", "4 GB", "13.6").build();
System.out.println("model3: " + model3.toString());
}
}
2.4. Παραγωγή
model1: Computer {
HDD = '1 TB', RAM = '16 GB', screenSize = '15.6', isGraphicsCardEnabled = true, isBluetoothEnabled = true, isWebCamEnabled = true, isTouchScreenEnabled = true
}
model2: Computer {
HDD = '256 GB', RAM = '8 GB', screenSize = '14.6', isGraphicsCardEnabled = true, isBluetoothEnabled = true, isWebCamEnabled = false, isTouchScreenEnabled = false
}
model3: Computer {
HDD = '128 GB', RAM = '4 GB', screenSize = '13.6', isGraphicsCardEnabled = false, isBluetoothEnabled = false, isWebCamEnabled = false, isTouchScreenEnabled = false
}
Το μεγαλύτερο μέρος του IDE (π.χ IntelliJ IDEA, Eclipse κ.λπ.) παρέχουν πρόσθετο για τη δημιουργία κλάσης builder για την εφαρμογή σας. Μπορείτε πάντα να τα χρησιμοποιήσετε, με την προϋπόθεση ότι κατανοούμε ξεκάθαρα το μοτίβο σχεδίασης του κατασκευαστή.
Ακολουθεί το διάγραμμα τάξης για να σας παρέχει καλύτερη κατανόηση του μοτίβου του builder.

3. Πλεονεκτήματα και μειονεκτήματα
Ας μιλήσουμε για μερικά από τα σημαντικότερα πλεονεκτήματα και μειονεκτήματα της χρήσης του μοτίβου σχεδίασης κατασκευαστή.
3.1. Πλεονεκτήματα
- Αυτό το μοτίβο ενσωματώνει τον κώδικα για την κατασκευή αντικειμένων από τον πελάτη.
- Αυτό το μοτίβο παρέχει μεγάλο έλεγχο στη διαδικασία κατασκευής του αντικειμένου.
- Αυτό το μοτίβο επιτρέπει τη δημιουργία σύνθετων αντικειμένων με εύκολο και τακτοποιημένο τρόπο.
- Αυτό το μοτίβο απαλλάσσεται από μια αλυσίδα κατασκευαστών για την κατασκευή πολύπλοκων αντικειμένων. Επίσης, χρειαζόμαστε έναν κατασκευαστή μόνο για υποχρεωτικά ορίσματα που τον καθιστούν λιγότερο περίπλοκο.
- Αυτό το μοτίβο παρέχει μεγάλη ευελιξία και αναγνωσιμότητα, αν και αυξάνει τον αριθμό των γραμμών (ευτυχώς μπορεί επίσης να μειωθεί χρησιμοποιώντας τη βιβλιοθήκη Lombok).
- Αυτό το μοτίβο μας επιτρέπει να κατασκευάζουμε αμετάβλητα αντικείμενα με μικρή πολύπλοκη λογική.
3.2. Μειονεκτήματα
- Αυξημένος αριθμός γραμμών.
- Δεν είναι εγγυημένη η αρχικοποίηση όλων των μελών δεδομένων.
- Πρόκληση για την υποστήριξη της ένεσης εξάρτησης.
Συνοπτικά, το αφηρημένο εργοστασιακό μοτίβο είναι η απάντηση
"WHAT"
και το μοτίβο οικοδόμου να"HOW"
.
4. Πότε να χρησιμοποιήσετε το Μοτίβο δόμησης
Υπάρχουν πολλές περιπτώσεις χρήσης όπου η χρήση του μοτίβου σχεδίασης builder θα σας προσφέρει οφέλη.
- Θα πρέπει να χρησιμοποιούμε αυτό το μοτίβο όταν χρειάζεται να δημιουργήσουμε ένα σύνθετο αντικείμενο με κάποιες απαιτούμενες και μερικές προαιρετικές ιδιότητες.
- Θα πρέπει να χρησιμοποιούμε αυτό το μοτίβο όταν η κατασκευή των αντικειμένων εξαρτάται από τις τιμές χρόνου εκτέλεσης.
- Θα πρέπει να χρησιμοποιούμε αυτό το μοτίβο όταν ο πελάτης δεν ενδιαφέρεται για την πραγματική υλοποίηση του αντικειμένου.
Περίληψη
Σε αυτό το άρθρο, μιλήσαμε για το μοτίβο σχεδιασμού του οικοδόμου. Καλύψαμε τα βασικά χαρακτηριστικά του μαζί με λεπτομέρειες σχετικά με το πότε να χρησιμοποιήσετε αυτό το μοτίβο στην εφαρμογή σας. Όπως πάντα, ο πηγαίος κώδικας για τα άρθρα μας είναι διαθέσιμος στο δικό μας Αποθετήριο GitHub.
Ακολουθούν μερικά από τα υπάρχοντα παραδείγματα από το JDK χρησιμοποιώντας αυτό το μοτίβο:
- java.lang.Appendable
- java.lang.StringBuilder#append() [Unsynchronized class]
- java.lang.StringBuffer#append() [Synchronized class]