[GO] Verstehen Sie das Decorator-Muster, indem Sie JavaScript und Java-Code vergleichen

Einführung

Details und andere Muster werden in ** Grundlegendes zu Entwurfsmustern durch Vergleichen von Implementierungen in JavaScript und Java ** geschrieben. Ich habe ein Beispiel für JavaScript geschrieben, indem ich mir Java angesehen habe. Unterschiede in Funktionen wie Klassentyp / Prototyp, Typstärke und Zugriffsmodifikatoren werden nicht genutzt. Bitte beachten Sie.

Decorator Es gibt einen Biskuitkuchen. Wenn Sie Sahne auftragen, ist dies ein kurzer Kuchen. Wenn Sie Erdbeere darauf legen, handelt es sich um einen kurzen Erdbeerkuchen Wenn Sie Schokolade anwenden, wird es ein Schokoladenkuchen Die Objekte sind ähnlich, in der Mitte befindet sich ein Objekt wie ein Biskuitkuchen, und die Dekorationsfunktion wird mit jeder Haut abgedeckt, um es als Objekt zu gestalten, das dem Zweck entspricht. Ein solches Designmuster, das Objekte immer mehr schmückt Dekorateur bedeutet "dekorieren"

ファイル 2017-01-29 .png

Implementierung in Java

Klassen Diagramm

Decorator2.png

Code

Main.java


public class Main {
    public static void main(String[] args) {
        Display b1 = new StringDisplay("Hello, world.");
        Display b2 = new SideBorder(b1, '#');
        Display b3 = new FullBorder(b2);
        b1.show();
        b2.show();
        b3.show();
        Display b4 = 
            new SideBorder(
                new FullBorder(
                    new FullBorder(
                        new SideBorder(
                            new FullBorder(
                                new StringDisplay("Hallo.")
                            )
                        , '*')
                    )
                )
            , '/');
        b4.show();
    }
}

Deisplay.java


public abstract class Display {
    public abstract int getColumns();
    public abstract int getRows();
    public abstract String getRowText(int row);
    public final void show() {
        for (int i = 0; i < getRows(); i++) {
            System.out.println(getRowText(i));
        }
    }
}

StringDisplay.java


public class StringDisplay extends Display {
    private String string;
    public StringDisplay(String string) {
        this.string = string;
    }
    public int getColumns() {
        return string.getBytes().length;
    }
    public int getRows() {
        return 1;
    }
    public String getRowText(int row) {
        if (row == 0) {
            return string;
        } else {
            return null;
        }
    }
}

Border.java


public abstract class Border extends Display{
    protected Display display;
    protected Border(Display display) {
        this.display = display;
    }
}

SideBorder.java


public class SideBorder extends Border {
    private char borderChar;
    public SideBorder(Display display, char ch) {
        super(display);
        this.borderChar = ch;
    }
    public int getColumns() {
        return 1 + display.getColumns() + 1;
    }
    public int getRows() {
        return display.getRows();
    }
    public String getRowText(int row) {
        return borderChar + display.getRowText(row) + borderChar;
    }
}

FullBorder.java


public class FullBorder extends Border {
    public FullBorder(Display display) {
        super(display);
    }
    public int getColumns() {
        return 1 + display.getColumns() + 1;
    }
    public int getRows() {
        return 1 + display.getRows() + 1;
    }
    public String getRowText(int row) {
        if (row == 0) {
            return "+" + makeLine('-', display.getColumns()) + "+";
        } else if (row == display.getRows() + 1) {
            return "+" + makeLine('-', display.getColumns()) + "+";
        } else {
            return "|" + display.getRowText(row - 1) + "|";
        }
    }
    private String makeLine(char ch, int count) {
        StringBuffer buf = new StringBuffer();
        for (int i = 0; i < count; i++) {
            buf.append(ch);
        }
        return buf.toString();
    }
}

JavaScript ** * Ich weiß nicht, ob es sich um eine Konsolenspezifikation handelt, aber wenn Sie eine 2-Byte-Spezifikation einfügen, wird das Layout reduziert **

Code

index.html


<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Decorator</title>
</head>
<body>
    <script src="Main.js"></script>
    <script src="StringDisplay.js"></script>
    <script src="SideBorder.js"></script>
    <Script src="FullBorder.js"></script>
    <script src="Display.js"></script>
</body>
</html>

Main.js


MAIN = {};
MAIN.init = function() {
    var b1 = new StringDisplay("Hello world.");
    var b2 = new SideBorder(b1, '#');
    var b3 = new FullBorder(b2);
    b1.show();
    b2.show();
    b3.show();
    var b4 = 
        new SideBorder(
            new FullBorder(
                new FullBorder(
                    new SideBorder(
                        new FullBorder(
                            new StringDisplay("Hello")
                        ), '*'
                    )
                )
            ), '/'
        );
    b4.show();
};


window.addEventListener("load", MAIN.init);

StringDisplay.js


var StringDisplay = function(string) {
    this.string = string;
};


StringDisplay.prototype = {
    constructor: "StringDisplay",

    getColumns: function() {
        return this.getBytes(this.string);
    },
    getRows: function() {
        return 1;
    },
    getRowText: function(row) {
        if (row == 0) {
            return this.string;
        } else {
            return null;
        }
    },
    getBytes: function(str) {
        var len = 0;
        str = escape(str);
        for (i = 0; i < str.length; i++, len++) {
            if (str.charAt(i) == "%") {
                if (str.charAt(++i) == "u") {
                    i += 3;
                    len++
                }
                i++;
            }
        }
        return len;
    }
};

SideBorder.js


var SideBorder = function(display, ch) {
    this.display = display;
    this.borderChar = ch;
};

SideBorder.prototype = {
    constructor: "SideBorder",

    getColumns: function() {
        return 1 + this.display.getColumns() + 1;
    },
    getRows: function() {
        return this.display.getRows();
    },
    getRowText(row) {
        return this.borderChar + this.display.getRowText(row) + this.borderChar;
    }
}

FullBorder.js


var FullBorder = function(display) {
    this.display = display;
};

FullBorder.prototype = {
    constructor: "FullBorder",

    getColumns: function() {
        return 1 + this.display.getColumns() + 1;
    },
    getRows: function() {
        return 1 + this.display.getRows() + 1;
    },
    getRowText: function(row) {
        if (row == 0) {
            return "+" + this.makeLine('-', this.display.getColumns()) + "+";
        } else if (row == this.display.getRows() + 1) {
            return "+" + this.makeLine('-', this.display.getColumns()) + "+";
        } else {
            return "|" + this.display.getRowText(row - 1) + "|";
        }
    },
    makeLine: function(ch, count) {
        var stringBuffer = "";
        for (var i = 0; i < count; i++) {
            stringBuffer += '-';
        }
        return stringBuffer;
    }
}

Display.js


StringDisplay.prototype.show = 
SideBorder.prototype.show = 
FullBorder.prototype.show = function() {
    for (var i = 0; i < this.getRows(); i++) {
        console.log(this.getRowText(i));
    }
};

Zeichen im Dekorationsmuster

** Rolle der Komponente **

Kernrolle beim Hinzufügen von Funktionen Definieren Sie nur die Schnittstelle (API) Beispielprogramm ⇒ Anzeige (Klasse)

** Die Rolle von ConcreateComponent **

Implementiert die Schnittstelle (API) für die Komponentenrolle Beispielprogramm ⇒ StringDisplay (Klasse)

** Die Rolle des Dekorateurs **

Implementiert die Schnittstelle (API) für die Komponentenrolle Und eine Komponentenrolle haben Beispielprogramm ⇒ Rand (Klasse)

** Die Rolle von Concreate Decorator **

Spezifische Rolle des Dekorateurs Beispielprogramm ⇒ SideBorder (Klasse)           FullBorder(class)

Klassendiagramm für Dekorationsmuster

Decorator.png

Notwendigkeit für Dekorateur Muster

Mithilfe des Decorator-Musters können Sie viele konkrete Concreate Decorator-Rollen erstellen und diese kombinieren, um verschiedene Arten von Objekten zu erstellen. Außerdem können Funktionen hinzugefügt werden, ohne den Inhalt zu ändern, und Funktionen können dynamisch hinzugefügt werden.

Bei Verwendung des Decorator-Musters

Es ähnelt Composite darin, dass es rekursive Strukturen verarbeiten und identifiziert werden kann, aber der Zweck ist unterschiedlich. Composite hat eine rekursive Struktur im Inneren Der Dekorateur hat außen eine rekursive Struktur

Compositeと比較.PNG

Verwandte Muster

Referenz

[Einführung in Entwurfsmuster, die in der erweiterten und überarbeiteten Java-Sprache gelernt wurden](https://www.amazon.co.jp/%E5%A2%97%E8%A3%9C%E6%94%B9%E8%A8%82% E7% 89% 88Java% E8% A8% 80% E8% AA% 9E% E3% 81% A7% E5% AD% A6% E3% 81% B6% E3% 83% 87% E3% 82% B6% E3% 82% A4% E3% 83% B3% E3% 83% 91% E3% 82% BF% E3% 83% BC% E3% 83% B3% E5% 85% A5% E9% 96% 80-% E7% B5 % 90% E5% 9F% 8E-% E6% B5% A9 / dp / 4797327030)

Recommended Posts

Verstehen Sie das Decorator-Muster, indem Sie JavaScript und Java-Code vergleichen
Verstehen Sie das Strategiemuster, indem Sie JavaScript und Java-Code vergleichen
Verstehen Sie das Statusmuster, indem Sie JavaScript und Java-Code vergleichen
Verstehen Sie das zusammengesetzte Muster, indem Sie JavaScript und Java-Code vergleichen
Verstehen Sie Entwurfsmuster, indem Sie Implementierungen in JavaScript und Java vergleichen. [Von Zeit zu Zeit aktualisiert]
Dekorationsmuster in Java
Der Versuch, Segmentbäume Schritt für Schritt zu implementieren und zu verstehen (Python)
Lernen Sie das Designmuster "Decorator" mit Python
Java-Kompilierung und Ausführung von CLI verstanden
Lesen Sie die Datei, indem Sie den Zeichencode angeben.
Verstehen Sie den Entscheidungsbaum und klassifizieren Sie Dokumente