gpt4 book ai didi

java - Java 中的装饰器设计模式 - 为什么它不添加新成分到列表中?

转载 作者:行者123 更新时间:2023-12-01 18:54:53 26 4
gpt4 key购买 nike

我尝试用 Java 实现一个简单的装饰器模式。主要思想是具体装饰器必须向基本列表中添加一些内容。但是,我的实现无法正常工作,我不知道为什么。

输出如下所示:

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 成为一个接口(interface),并让装饰器仅包装具体实例,而没有自己的状态。

// 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 有 3 个元素,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.

关于java - Java 中的装饰器设计模式 - 为什么它不添加新成分到列表中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14380079/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com