[GO] Comprendre le modèle Decorator en comparant le code JavaScript et Java

introduction

Les détails et autres modèles seront écrits dans ** Comprendre les modèles de conception en comparant les implémentations en JavaScript et Java **. J'ai écrit un exemple de JavaScript en regardant Java. Nous ne tirons pas parti des différences de fonctionnalités telles que le type de classe / type de prototype, la force typée et les modificateurs d'accès. Notez s'il vous plaît.

Decorator Il y a un génoise, si vous appliquez de la crème, ce sera un gâteau court, et si vous mettez de la fraise dessus, ce sera un gâteau court à la fraise Si vous appliquez du chocolat, cela devient un gâteau au chocolat Les objets sont similaires, il y a un objet central en forme de génoise, et la fonction de décoration est recouverte d'une peau pour la terminer à l'objet qui convient à l'usage. Un tel motif de design qui décore de plus en plus les objets décorateur signifie «décorer»

ファイル 2017-01-29 .png

Implémentation en Java

Diagramme de classe

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("Bonjour.")
                            )
                        , '*')
                    )
                )
            , '/');
        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 ** * Je ne sais pas s'il s'agit d'une spécification de console, mais si vous en insérez une sur 2 octets, la mise en page se réduira **

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));
    }
};

Caractères dans le motif décorateur

** Rôle du composant **

Rôle principal lors de l'ajout de fonctionnalités Définir uniquement l'interface (API) Exemple de programme ⇒ Affichage (classe)

** Le rôle de ConcreateComponent **

Implémente l'interface (API) pour le rôle de composant Exemple de programme ⇒ StringDisplay (classe)

** Le rôle du décorateur **

Implémente l'interface (API) pour le rôle de composant Et avoir un rôle de composant Exemple de programme ⇒ Border (classe)

** Le rôle de Concreate Decorator **

Rôle spécifique du décorateur Exemple de programme ⇒ SideBorder (classe)           FullBorder(class)

Diagramme de classe de modèle de décorateur

Decorator.png

Besoin d'un motif de décorateur

En utilisant le modèle Decorator, vous pouvez créer de nombreux rôles Concreate Decorator et les combiner pour créer différents types d'objets. Et c'est aussi une fonctionnalité que des fonctions peuvent être ajoutées sans changer le contenu, et des fonctions peuvent être ajoutées dynamiquement.

Lors de l'utilisation du motif Decorator

Il est similaire à Composite en ce qu'il peut gérer des structures récursives et peut être identifié, mais le but est différent. Le composite a une structure récursive à l'intérieur Le décorateur a une structure récursive à l'extérieur

Compositeと比較.PNG

Modèles associés

référence

[Introduction aux modèles de conception appris dans le langage Java augmenté et révisé](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

Comprendre le modèle Decorator en comparant le code JavaScript et Java
Comprendre le modèle de stratégie en comparant le code JavaScript et Java
Comprendre le modèle d'état en comparant le code JavaScript et Java
Comprendre le modèle composite en comparant le code JavaScript et Java
Comprendre les modèles de conception en comparant les implémentations en JavaScript et Java [mis à jour de temps en temps]
Modèle de décorateur en Java
Essayer d'implémenter et de comprendre les arborescences de segments étape par étape (python)
Apprenez le modèle de conception "Décorateur" avec Python
Compilation et exécution Java comprises par CLI
Lisez le fichier en spécifiant le code de caractère.
Comprendre l'arbre de décision et classer les documents