Die Verwendung des Builder-Musters

1. Anwendung des Builder-Modus

1.1 Einleitung

Trennen Sie die Konstruktion und Darstellung eines komplexen Objekts, sodass mit demselben Konstruktionsprozess unterschiedliche Darstellungen erstellt werden können.

  • Die Konstruktion der Komponenten (verantwortlich durch den Bauherrn) und die Montage (verantwortlich durch den Direktor) sind getrennt . So können komplexe Objekte konstruiert werden. Dieses Muster eignet sich für Situationen, in denen der Konstruktionsprozess eines Objekts komplex ist.
  • Durch die Entkopplung von Konstruktion und Montage . Verschiedene Builder und dieselbe Baugruppe können unterschiedliche Objekte herstellen; derselbe Builder und unterschiedliche Montagesequenzen können auch unterschiedliche Objekte erstellen. Das heißt, die Entkopplung des Konstruktionsalgorithmus und des Assemblierungsalgorithmus wird realisiert , und eine bessere Wiederverwendung wird realisiert.
  • Das Builder-Muster kann Teile aus ihrem Montageprozess trennen und Schritt für Schritt ein komplexes Objekt erstellen. Der Benutzer muss nur den Typ des komplexen Objekts angeben, um das Objekt zu erhalten, ohne die Details seiner internen Konstruktion zu kennen.

1.2 Builder-Musterstruktur

  • Abstrakte Builder-Klasse (Builder): Diese Schnittstelle legt die Erstellung dieser Teile des komplexen Objekts fest und beinhaltet nicht die Erstellung spezifischer Komponentenobjekte.

  • Concrete Builder-Klasse (ConcreteBuilder): Implementiert die Builder-Schnittstelle und vervollständigt die spezifischen Erstellungsmethoden jeder Komponente eines komplexen Produkts. Nach Abschluss des Konstruktionsprozesses wird eine Instanz des Produkts bereitgestellt.

  • Produktklasse (Product): Das zu erstellende komplexe Objekt.

  • Director-Klasse (Director): Rufen Sie den spezifischen Builder auf, um jeden Teil des komplexen Objekts zu erstellen. Der Director bezieht nicht die Informationen des spezifischen Produkts ein und ist nur dafür verantwortlich, sicherzustellen, dass die Teile des Objekts vollständig oder in einer bestimmten Weise erstellt werden Befehl.

1.3 Builder-Musterklassendiagramm

Fügen Sie hier eine Bildbeschreibung ein

1.4 Beispiel für den Zusammenbau eines Fahrrads

Die Herstellung eines Fahrrads ist ein komplexer Prozess, der die Herstellung von Komponenten wie Rahmen und Sattel umfasst. Der Rahmen besteht aus Kohlefaser, Aluminiumlegierung und anderen Materialien, und der Sitz besteht aus Gummi, Leder und anderen Materialien. Für die Herstellung von Fahrrädern kann das Baumuster verwendet werden.

1.4.1 Klassendiagramm des zusammengebauten Fahrradkoffers

Fahrrad ist ein Produkt, das Komponenten wie Rahmen und Sitz umfasst; Builder ist ein abstrakter Builder, während MobikeBuilder und OfoBuilder konkrete Builder sind; Director ist ein Kommandant.

Fügen Sie hier eine Bildbeschreibung ein

1.4.2 Code

/**
 * 产品: Bike
 */
public class Bike {
    
    
    private String frame;//车架
    private String seat;//车座

    public String getFrame() {
    
    
        return frame;
    }

    public void setFrame(String frame) {
    
    
        this.frame = frame;
    }

    public String getSeat() {
    
    
        return seat;
    }

    public void setSeat(String seat) {
    
    
        this.seat = seat;
    }
}

/**
 * 抽象建造者: Builder
 */
public abstract class Builder {
    
    
    //声明Bike类型的变量,并进行赋值
    protected Bike bike = new Bike();
    public abstract void buildFrame();
    public abstract void buildSeat();
    //构建自行车的方法
    public abstract Bike createBike();
}

/**
 * 具体的构建者,用来构建摩拜单车对象
 */
public class MobileBuilder extends Builder {
    
    
    public void buildFrame() {
    
    
        bike.setFrame("碳纤维车架");
    }

    public void buildSeat() {
    
    
        bike.setSeat("真皮车座");
    }

    public Bike createBike() {
    
    
        return bike;
    }
}

/**
 * ofo单车构建者,用来构建ofo单车
 */
public class OfoBuilder extends Builder {
    
    
    public void buildFrame() {
    
    
        bike.setFrame("铝合金车架");
    }

    public void buildSeat() {
    
    
        bike.setSeat("橡胶车座");
    }

    public Bike createBike() {
    
    
        return bike;
    }
}

/**
 * 指挥者
 */
public class Director {
    
    
    //声明builder类型的变量
    private Builder builder;

    public Director(Builder builder) {
    
    
        this.builder = builder;
    }

    //组装自行车的功能
    public Bike construct() {
    
    
        builder.buildFrame();
        builder.buildSeat();
        return builder.createBike();
    }
}

/**
 * 客户: Client
 */
public class Client {
    
    
    public static void main(String[] args) {
    
    
        //创建指挥者对象
        Director director = new Director(new MobileBuilder());
        //让指挥者只会组装自行车
        Bike bike = director.construct();

        System.out.println(bike.getFrame());
        System.out.println(bike.getSeat());
    }
}

1.5 Vor- und Nachteile

Vorteil:

  • Die Kapselung des Builder-Modus ist gut . Durch die Verwendung des Builder-Modus können Änderungen effektiv gekapselt werden. Im Szenario der Verwendung des Builder-Modus sind die allgemeine Produktklasse und die Builder-Klasse relativ stabil. Daher kann durch die Kapselung der Hauptgeschäftslogik in der Commander-Klasse insgesamt eine relativ gute Stabilität erreicht werden .
  • Im Builder-Modus muss der Kunde die Details der internen Zusammensetzung des Produkts nicht kennen, und das Produkt selbst ist vom Produkterstellungsprozess entkoppelt , sodass mit demselben Erstellungsprozess unterschiedliche Produktobjekte erstellt werden können.
  • Der Produktentstehungsprozess kann feiner gesteuert werden . Durch die Aufteilung der Erstellungsschritte komplexer Produkte in verschiedene Methoden wird der Erstellungsprozess klarer und die Verwendung von Programmen zur Steuerung des Erstellungsprozesses bequemer.
  • Das Builder-Muster lässt sich leicht erweitern . Wenn eine neue Anforderung vorliegt, kann diese durch die Implementierung einer neuen Builder-Klasse erfüllt werden, im Wesentlichen ohne Änderung des zuvor getesteten Codes, sodass keine Risiken für die ursprüngliche Funktion entstehen. Beachten Sie das Prinzip des Öffnens und Schließens.

Mangel:

Die im Builder-Modus erstellten Produkte haben im Allgemeinen mehr Gemeinsamkeiten und ihre Komponenten sind ähnlich. Wenn die Produkte sehr unterschiedlich sind, ist die Verwendung des Builder-Modus nicht geeignet, sodass sein Anwendungsbereich begrenzt ist.

1.6 Nutzungsszenarien

Das Builder-Muster (Builder) erstellt komplexe Objekte und die verschiedenen Teile seiner Produkte unterliegen häufig drastischen Änderungen. Der Algorithmus, der sie kombiniert, ist jedoch relativ stabil und wird daher normalerweise in den folgenden Situationen verwendet.

  • Das erstellte Objekt ist komplex und besteht aus mehreren Teilen. Jeder Teil unterliegt komplexen Änderungen, aber die Konstruktionsreihenfolge zwischen den Komponenten ist stabil .
  • Der Algorithmus zum Erstellen eines komplexen Objekts ist unabhängig von den Bestandteilen dieses Objekts und der Art und Weise, wie sie zusammengesetzt werden, d. h. der Konstruktionsprozess und die endgültige Darstellung des Produkts sind unabhängig .

1.7 Schemaerweiterungen

Das Builder-Muster wird auch häufig in der Entwicklung verwendet. Wenn ein Klassenkonstruktor viele Parameter übergeben muss und eine Instanz dieser Klasse erstellt wird, ist die Lesbarkeit des Codes sehr schlecht und es können leicht Fehler auftreten. Zu diesem Zeitpunkt Sie kann das Builder-Muster zum Refactoring verwenden.

1.7.1 Originalcode

Um das Phone-Objekt im Client-Code zu erstellen, werden vier Parameter übergeben. Wenn mehr Parameter vorhanden sind, werden die Lesbarkeit des Codes und die Nutzungskosten höher.

/**
 * Phone的javaBean
 */
public class Phone {
    
    
    private String cpu;
    private String screen;
    private String memory;
    private String mainboard;

    public Phone(String cpu, String screen, String memory, String mainboard) {
    
    
        this.cpu = cpu;
        this.screen = screen;
        this.memory = memory;
        this.mainboard = mainboard;
    }

    public String getCpu() {
    
    
        return cpu;
    }

    public void setCpu(String cpu) {
    
    
        this.cpu = cpu;
    }

    public String getScreen() {
    
    
        return screen;
    }

    public void setScreen(String screen) {
    
    
        this.screen = screen;
    }

    public String getMemory() {
    
    
        return memory;
    }

    public void setMemory(String memory) {
    
    
        this.memory = memory;
    }

    public String getMainboard() {
    
    
        return mainboard;
    }

    public void setMainboard(String mainboard) {
    
    
        this.mainboard = mainboard;
    }

    @Override
    public String toString() {
    
    
        return "Phone{" +
                "cpu='" + cpu + '\'' +
                ", screen='" + screen + '\'' +
                ", memory='" + memory + '\'' +
                ", mainboard='" + mainboard + '\'' +
                '}';
    }
}

/**
 * 客户: Client
 */
public class Client {
    
    
    public static void main(String[] args) {
    
    
        //构建Phone对象
        Phone phone = new Phone("intel","三星屏幕","金士顿","华硕");
        System.out.println(phone);
    }
}

1.7.2 Refactoring-Code

Der überarbeitete Code ist benutzerfreundlicher und kann in gewissem Maße auch die Entwicklungseffizienz verbessern. Aus Sicht des Softwaredesigns sind die Anforderungen an Programmierer relativ hoch.

/**
 * Phone的JavaBean
 */
public class Phone{
    
    
    private String cpu; // 中央处理器
    private String screen; // 屏幕
    private String memory; // 存储器
    private String mainboard; // 主板

    // 构造私有的构造方法防止外界直接声明有参对象
    private Phone(Builder builder){
    
    
        this.cpu = builder.cpu;
        this.screen = builder.screen;
        this.memory = builder.memory;
        this.mainboard = builder.mainboard;
    }
    // 构建静态内部类Builder
    public static final class Builder {
    
    
        private String cpu;
        private String screen;
        private String memory;
        private String mainboard;
        public Builder cpu(String cpu) {
    
    
            this.cpu = cpu;
            return this;
        }
        public Builder screen(String screen) {
    
    
            this.screen = screen;
            return this;
        }
        public Builder memory(String memory) {
    
    
            this.memory = memory;
            return this;
        }
        public Builder mainboard(String mainboard) {
    
    
            this.mainboard = mainboard;
            return this;
        }
        // 使用构建者创建Phone对象
        public Phone build() {
    
    
            return new Phone(this);
        }
    }

    @Override
    public String toString() {
    
    
        return "Phone{" +
                "cpu='" + cpu + '\'' +
                ", screen='" + screen + '\'' +
                ", memory='" + memory + '\'' +
                ", mainboard='" + mainboard + '\'' +
                '}';
    }
}

/**
 * 客户: Client
 */
public class Client {
    
    
    public static void main(String[] args) {
    
    
        // 创建一个Phone对象,通过构建者对象获取Phone对象
        Phone phone = new Phone.Builder()
                .cpu("天玑1000+ 八核")
                .screen("华为屏幕")
                .memory("金士顿内存条")
                .mainboard("华硕ROG MAXIMUS Z790 EXTREME")
                .build();
        System.out.println(phone);
    }
}

记录每一个学习瞬间

Supongo que te gusta

Origin blog.csdn.net/qq_51601665/article/details/131089268
Recomendado
Clasificación