簡體   English   中英

Java中的裝飾器設計模式-為什么不向列表中添加新的裝飾元素?

[英]Decorator Design Pattern in Java - why it doesnt add new ingridients to list?

我試圖用Java實現一個簡單的Decorator Pattern。 主要思想是混凝土裝飾師必須在基本列表中添加一些內容。 但是,我的實現無法正常工作,我也不知道為什么。

輸出如下所示:

ING -1,ING 0,ING 1.

但應該是:

ING -1,ING 0,ING 1, ING 2.

這是我的代碼:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package newpackage;

import java.util.ArrayList;
import java.util.List;

abstract class Tester {

    protected List<String> ingridients = new ArrayList();
    protected String description;

    public String getDescription() {
        description = "";
        for (String i : ingridients) {
            description += i;
            description += ",";
        }
        description = description.substring(0, description.length() - 1);
        description += ".";
        return description;
    }
}

abstract class Decorator extends Tester {

    @Override
    public abstract String getDescription();
}

class Test1 extends Tester {

    public Test1() {
        this.ingridients.add("ING -1");
        this.ingridients.add("ING 0");
    }
}

class Ing1 extends Decorator {

    private Tester t;

    public Ing1(Tester t) {
        this.t = t;
    }

    @Override
    public String getDescription() {
        this.t.ingridients.add("ING 1");
        return this.t.getDescription();
    }
}

class Ing2 extends Decorator {

    private Tester t;

    public Ing2(Tester t) {
        this.t = t;
    }

    @Override
    public String getDescription() {
        this.t.ingridients.add("ING 2");
        return this.t.getDescription();
    }
}

public class Test {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Tester t = new Test1();
        t = new Ing1(t);
        t = new Ing2(t);

        System.out.println(t.getDescription());
    }
}

編輯代碼:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package newpackage;

import java.util.ArrayList;
import java.util.List;

interface Tester {

    List<String> ingridients = new ArrayList();
    public String getDescription();
}

abstract class Decorator implements Tester {

    @Override
    public abstract String getDescription();
}


class Test1 implements Tester {

    public Test1() {
        ingridients.add("ING -1");
        ingridients.add("ING 0");
    }

    @Override
    public String getDescription() {
        String description = "";
        for (String i : ingridients) {
            description += i;
            description += ",";
        }
        description = description.substring(0, description.length() - 1);
        description += ".";
        return description;
    }
}

class Ing1 extends Decorator {

    private Tester t;

    public Ing1(Tester t) {
        this.t = t;
    }

    @Override
    public String getDescription() {
        this.t.ingridients.add("ING 1");
        return this.t.getDescription();
    }
}

class Ing2 extends Decorator {

    private Tester t;

    public Ing2(Tester t) {
        this.t = t;
    }

    @Override
    public String getDescription() {
        this.t.ingridients.add("ING 2");
        return this.t.getDescription();
    }
}

public class Test {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Tester t = new Test1();
        t = new Ing1(t);
        t = new Ing2(t);

        System.out.println(t.getDescription());
    }
}

我在調試器中運行它,我可以看到您的裝飾器不只是裝飾器,因為它們具有自己的狀態。 使您的Tester成為接口,讓裝飾者僅包裝具體實例,而沒有其自身的狀態。

// adds to the list in t1
this.t.ingridients.add("ING 2");

// add to the list in t
this.t.ingridients.add("ING 1");

// returns the contents of t.
return this.t.getDescription();

最后,t.ingredients具有三項,t1.ingredients具有1個元素,而t2.ingredients無。


你可以這樣寫

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;


public class Test {
    public static void main(String[] ignored) {
        Tester t012 = new Ing2(new Ing1(new Ing0(new None())));
        System.out.println(t012.getDescription());

        Tester t210 = new Ing0(new Ing1(new Ing2(new None())));
        System.out.println(t210.getDescription());
    }
}

abstract class Tester {
    public List<String> getIngredients() {
        return Collections.emptyList();
    }

    public String getDescription() {
        StringBuilder sb = new StringBuilder();
        String sep = "";
        for (String s : getIngredients()) {
            sb.append(sep).append(s);
            sep=", ";
        }
        sb.append(".");
        return sb.toString();
    }
}

class None extends Tester {
}

class Ing0 extends Tester {
    private final Tester wrapped;
    Ing0(Tester wrapped) {
        this.wrapped = wrapped;
    }

    @Override
    public List<String> getIngredients() {
        List<String> list = new ArrayList<>(wrapped.getIngredients());
        list.add("ING -1");
        list.add("ING 0");
        return Collections.unmodifiableList(list);
    }
}

class Ing1 extends Tester {
    private final Tester wrapped;
    Ing1(Tester wrapped) {
        this.wrapped = wrapped;
    }

    @Override
    public List<String> getIngredients() {
        List<String> list = new ArrayList<>(wrapped.getIngredients());
        list.add("ING 1");
        return Collections.unmodifiableList(list);
    }
}

class Ing2 extends Tester {
    private final Tester wrapped;
    Ing2(Tester wrapped) {
        this.wrapped = wrapped;
    }

    @Override
    public List<String> getIngredients() {
        List<String> list = new ArrayList<>(wrapped.getIngredients());
        list.add("ING 2");
        return Collections.unmodifiableList(list);
    }
}

版畫

ING -1, ING 0, ING 1, ING 2.
ING 2, ING 1, ING -1, ING 0.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM