Heim  >  Artikel  >  Java  >  Einführung in Builder Pattern und Prototype Pattern in Java Design Patterns (Codebeispiel)

Einführung in Builder Pattern und Prototype Pattern in Java Design Patterns (Codebeispiel)

不言
不言Original
2018-09-12 15:58:442099Durchsuche

Der Inhalt dieses Artikels ist eine Einführung in das Builder-Muster und das Prototyp-Muster in Java-Designmustern (Codebeispiele). Ich hoffe, dass es für Sie hilfreich ist. helfen.

Vorwort

Im vorherigen Artikel haben wir etwas über das Fabrikmuster gelernt und das einfache Fabrikmuster, die Fabrikmethode und das abstrakte Fabrikmuster vorgestellt. In diesem Artikel werden das Builder-Muster und das Prototyp-Muster vorgestellt, bei denen es sich um kreative Muster in Entwurfsmustern handelt.

Builder-Modus

Einführung

Builder-Modus ist ein Kreativmodus. Das Builder-Muster verwendet mehrere einfache Objekte, um Schritt für Schritt ein komplexes Objekt zu erstellen. Bei dieser Art von Entwurfsmuster handelt es sich um ein Erstellungsmuster, das eine optimale Möglichkeit zum Erstellen von Objekten bietet.
Einfach ausgedrückt geht es darum, eine komplexe Sache zu extrahieren und einen einfachen Aufruf an die Außenwelt bereitzustellen, der im selben Konstruktionsprozess unterschiedliche Darstellungen erstellen kann. Er ist dem Werksmodus sehr ähnlich, legt jedoch mehr Wert auf die Montage der Komponenten.

Hier ist ein Beispiel zur Veranschaulichung.
Zu den Lebensmitteln, die wir täglich essen, gehören Pfannkuchen, Lunchboxen, Ramen, Sojamilch, Milch und Saft. Es ist in drei Mahlzeiten unterteilt: Frühstück, Mittagessen und Abendessen. Die Mahlzeiten umfassen hauptsächlich Essen (allgemein bekannt als Reis) und Getränke (Sojamilch, Saft usw.), dann können wir Pfannkuchen und Sojamilch zum Frühstück und ein Lunchpaket essen und Saft als Mittagessen, damit wir genau wissen, was wir zum Frühstück und Mittagessen essen sollen.

Zuerst definieren wir eine Lebensmittelkategorie mit zwei Attributen, Essen und Trinken.

class Meal{
    private String food;
    private String drinks;
    
    public String getFood() {
        return food;
    }
    public void setFood(String food) {
        this.food = food;
    }
    
    public String getDrinks() {
        return drinks;
    }
    public void setDrinks(String drinks) {
        this.drinks = drinks;
    }
}

Wenn wir Lebensmittel definieren, definieren wir eine Standardschnittstelle für Lebensmittel. Was enthält ein Lebensmittel tatsächlich?

interface IBuilderFood{
    void buildFood();
    void buildDrinks();
    Meal createMeal();
}

Die Lebensmittelschnittstelle definiert eine Ess- und eine Trinkkomponente und gibt dann die Lebensmittel, die wir benötigen, über die Methode createMeal() zurück.
Jetzt können wir ein Frühstück und ein Mittagessen definieren.
Codebeispiel:

class Breakfast implements IBuilderFood{
    Meal meal;

    public Breakfast(){
        meal=new Meal();
    }
    
    @Override
    public void buildFood() {
        meal.setFood("煎饼");
    }

    @Override
    public void buildDrinks() {
        meal.setDrinks("豆浆");   
    }
    
    @Override
    public Meal createMeal() {
        return meal;
    }
}

class Lunch implements IBuilderFood{
    Meal meal;

    public Lunch(){
        meal=new Meal();
    }
    
    @Override
    public void buildFood() {
        meal.setFood("盒饭");
    }

    @Override
    public void buildDrinks() {
        meal.setDrinks("果汁");   
    }
    
    @Override
    public Meal createMeal() {
        return meal;
    }
}

Nach der Definition ist der Prozess der Erstellung von Frühstück und Mittagessen abgeschlossen. Dies ist jedoch nicht der Builder-Modus. Er verfügt über einen Kerndirektor, der dazu dient, Teile komplexer Objekte zu erstellen, die Teile vollständig zu erstellen oder sie nach bestimmten Regeln zu erstellen. Hier können wir also einen Regisseur erstellen, der eine Mahlzeit kreiert. Um welche Mahlzeit es sich handelt, muss er nicht wissen, dies entscheidet der Anrufer.

Hier können wir ein Restaurant definieren und eine Mahlzeit kreieren. Der Kunde entscheidet, welche Mahlzeit er kreiert.
Codebeispiel:

class FoodStore{
    public Meal createBreakfast(IBuilderFood bf){
        bf.buildDrinks();
        bf.buildFood();
        return bf.createMeal();
    }
}

Nachdem wir diesen Director erstellt haben, führen wir den Anruftest durch.

Codebeispiel:

public class BuilderTest {

    public static void main(String[] args) {
        FoodStore foodStore=new FoodStore();
        Meal meal=foodStore.createBreakfast(new Breakfast());
        Meal meal2=foodStore.createBreakfast(new Lunch());
        System.out.println("小明早上吃的是:"+meal.getFood()+",喝的饮料是:"+meal.getDrinks());
        System.out.println("小明中午吃的是:"+meal2.getFood()+",喝的饮料是:"+meal2.getDrinks()); 
    }

}

Ausgabeergebnis:

小明早上吃的是:煎饼,喝的饮料是:豆浆
小明中午吃的是:盒饭,喝的饮料是:果汁

Eine kurze Einführung in das Funktionsprinzip des Builder-Modus. Es lässt sich wie folgt zusammenfassen:

  1. Builder: spezifiziert eine abstrakte Schnittstelle, legt die Erstellung der für das Produkt erforderlichen Komponenten fest und beinhaltet nicht die Erstellung spezifischer Objektkomponenten.

  2. ConcreteBuilder: Es ist notwendig, die Builder-Schnittstelle zu implementieren, verschiedene Methoden für unterschiedliche Logiken zu erstellen und schließlich eine Instanz des Produkts bereitzustellen.

  3. Direktor: Wird verwendet, um den Teil komplexer Objekte zu erstellen, die Erstellung dieses Teils abzuschließen oder ihn nach bestimmten Regeln zu erstellen.

  4. Produkt: Gibt das konstruierte komplexe Objekt an.

Verwendungsszenarien:
Anwendbar, wenn einige Grundkomponenten unbequem sind, sich die Kombination jedoch häufig ändert. Zum Beispiel ein Werbegeschenkpaket für einen Supermarkt.

Vorteile:

  1. Builder ist unabhängig und leicht erweiterbar.

  2. Einfache detaillierte Risikokontrolle.

Nachteile

  1. Die interne Struktur ist kompliziert und nicht leicht zu verstehen.

  2. Die Produkte müssen direkt etwas gemeinsam haben und der Umfang sollte kontrolliert werden.

Prototype Pattern

Prototype Pattern wird verwendet, um wiederholte Objekte zu erstellen und gleichzeitig die Leistung sicherzustellen. Bei dieser Art von Entwurfsmuster handelt es sich um ein Erstellungsmuster, das eine optimale Möglichkeit zum Erstellen von Objekten bietet.

Wenn wir ein Objekt erstellen, erstellen wir es im Allgemeinen direkt. Wenn die Kosten für die Erstellung des Objekts jedoch hoch sind, ist eine wiederholte Erstellung nicht kosteneffektiv. In diesem Fall können wir den Prototypenmodus verwenden .
Zum Beispiel haben wir alle E-Mails mit Segenswünschen verschickt, bis auf die Namen. Zu diesem Zeitpunkt können wir diesen Modus verwenden, um entsprechend zu erstellen.

Hier ist ein einfaches Beispiel zur Veranschaulichung.
Xiao Ming und Xiao Hong haben am selben Tag Geburtstag, also müssen wir ihnen E-Mails schicken, um ihnen alles Gute zu wünschen, aber weil wir faul sind, sind die Segensworte bis auf ihre Namen dieselben. Zu diesem Zeitpunkt können wir zunächst das Schreiben des Segens abschließen, dann den Segen klonen und ihn schließlich unter verschiedenen Namen senden. Aber ich werde es hier einfach halten, einfach ausdrucken.

Codebeispiel:

public class PrototypeTest {

    public static void main(String[] args) {
        Mail mail=new Mail();
        mail.setMsg("生日快乐!");
        Mail mail2=(Mail) mail.clone();
        mail.setName("小明");
        mail2.setName("小红");
        System.out.println(mail.toString());
        System.out.println(mail2.toString());
    }
}

 class Mail implements Cloneable {
    private String name;
    private String msg;
    
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
    public Object clone() {
        Object clone = null;
        try {
            clone = super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return clone;
    }

    @Override
    public String toString() {
        return name + ":" + msg ;
    }
    
}

Ausgabeergebnis:

小明:生日快乐!
小红:生日快乐!

看完原型模式的创建,是不是感觉就是和Java中克隆即为类似呢?
实际上它的核心也就是克隆。
克隆有两种,浅克隆和深克隆,本文主要介绍的是浅克隆。
浅克隆:

在浅克隆中,如果原型对象的成员变量是值类型,将复制一份给克隆对象;如果原型对象的成员变量是引用类型,则将引用对象的地址复制一份给克隆对象,也就是说原型对象和克隆对象的成员变量指向相同的内存地址。
简单来说,在浅克隆中,当对象被复制时只复制它本身和其中包含的值类型的成员变量,而引用类型的成员对象并没有复制。
实现Cloneable接口并重写Object类中的clone()方法;

深克隆:

在深克隆中,无论原型对象的成员变量是值类型还是引用类型,都将复制一份给克隆对象,深克隆将原型对象的所有引用对象也复制一份给克隆对象。

简单来说,在深克隆中,除了对象本身被复制外,对象所包含的所有成员变量也将复制。
实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆。

使用场景:

  1. 类初始化的时候需要消耗大量资源的时候;

  2. 获取数据库连接繁琐的时候;

  3. 一个对象,有很多个修改者的时候;

优点:
1.可以提升性能;

缺点:
1.因为必须实现Cloneable 接口,所以用起来可能不太方便。

相关推荐:

Java设计模式中工厂模式的介绍(代码示例)

Java设计模式是什么?Java设计模式中单例模式的介绍

Das obige ist der detaillierte Inhalt vonEinführung in Builder Pattern und Prototype Pattern in Java Design Patterns (Codebeispiel). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn