Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Java中从装饰器模式中删除装饰对象_Java_Design Patterns_Decorator - Fatal编程技术网

如何在Java中从装饰器模式中删除装饰对象

如何在Java中从装饰器模式中删除装饰对象,java,design-patterns,decorator,Java,Design Patterns,Decorator,我在读“假人的设计模式”。我阅读并练习装饰图案。使用Decorator模式,我们可以用任何东西装饰对象。现在,我想在装饰之前移除装饰过的对象。我已经通过ArrayList解决了这个问题,但我仍然觉得不好。你能告诉我如何移除装饰物吗?还有什么更好的方法 这是我的方式: Computer.java ComponentDecorator.java CD.java java Monitor.java Main.java import java.util.ArrayList; 导入java.util.ar

我在读“假人的设计模式”。我阅读并练习装饰图案。使用Decorator模式,我们可以用任何东西装饰对象。现在,我想在装饰之前移除装饰过的对象。我已经通过ArrayList解决了这个问题,但我仍然觉得不好。你能告诉我如何移除装饰物吗?还有什么更好的方法

这是我的方式:

Computer.java

ComponentDecorator.java

CD.java

java

Monitor.java

Main.java

import java.util.ArrayList;
导入java.util.array;
公共班机{
静态ArrayList=新建ArrayList();
公共静态void main(字符串[]args){
添加组件(新CD(),新磁盘(),新监视器());
System.out.println(list.size());
Computer=getComputer();
移除组件(新监视器());
penii=getComputer();
System.out.println(penii.description());
}
私有静态void addComponent(ComponentDecorator…comp){
addAll(Arrays.asList(comp));
}
私有静态void removeComponent(ComponentDecorator comp){
用于(组件装饰器c:列表){
如果(c.getClass()==comp.getClass()){
list.remove(list.indexOf(c));
打破
}
}
}
专用静态计算机getComputer(){
计算机c=新计算机();
e类;
for(组件装饰器d:列表){
e=d.getClass();
试一试{
c=(计算机)e.getConstructor(新类[]{Computer.Class}).newInstance(c);
}捕获(例外情况除外){
例如printStackTrace();
}
}
返回c;
}
}

我怀疑我误解了您的问题,但要从装饰器中获取装饰(内部)对象,只需向装饰器添加一个get方法即可。加

公共抽象计算机getdecordent()

组件装饰和

公共计算机getdecordent(){return Computer;}


到每个子类(CD、监视器等)。这就是您想要的吗?

更好的方法是将“removeDecorator”方法添加到ComponentDecorator类中

public abstract class ComponentDecorator {

private ComponentDecorator subject;

public ComponentDecorator(ComponentDecorator subject) {
  this.subject = subject;
}

@Override
public abstract String description();
}

public void removeDecorator(ComponentDecorator toRemove) {
  if (subject == null) {
    return;
  } else if (subject.equals(toRemove)) {
    subject = subject.getSubject();
  } else {
    subject.removeDecorator(toRemove);
  }
}

public ComponentDecorator getSubject() {
  return subject;
}


// Computer
public class Computer extends ComponentDecorator{

public Computer() {
  super(null);
}

public String description() {
  return "computer";
}

// CD
public class CD extends ComponentDecorator {

  public CD(ComponentDecorator computer) {
    super(computer);
  }

  @Override
  public String description() {
    return getSubject().description() + " and a CD";
  }
}

// main
public static void main(String[] args) {
    ComponentDecorator penIII = new Computer();
    penIII = new CD(penIII);
    penIII = new Monitor(penIII);
    System.out.println(penIII.description());
}
}

如果您没有要删除的装饰器的引用,那么可以创建另一个方法,而装饰器将创建一个类


但是,您需要将装饰对象设置为“ComponentDecorator”而不是“Computer”。我建议让计算机类扩展ComponentDecorator,而不是相反的方式。

向接口添加两个方法,Uncorate()和removeDecoration(String className):

ThingInterface.java

public interface ThingInterface {
    public ThingInterface undecorate();
    public ThingInterface removeDecoration(String className);
    public String nonDecoratedString();
    public String decoratedString();
}
public class BaseThing implements ThingInterface {

    private String basicString;

    public BaseThing(String string) {
        basicString = string;
    }

    @Override
    public ThingInterface undecorate() {
        return this;
    }

    @Override
    public ThingInterface removeDecoration(String className) {
        return this;
    }

    @Override
    public String nonDecoratedString() {
        return basicString;
    }

    @Override
    public String decoratedString() {
        return basicString;
    }

}
public abstract class AbstractThingDecorator implements ThingInterface {

    private ThingInterface thing;

    public AbstractThingDecorator(ThingInterface thing) {
        this.thing = thing;
    }

    @Override
    public ThingInterface removeDecoration(String className) {
        ThingInterface undecorate = this;
        if(this.getClass().getName() == className) {
            undecorate = this.undecorate();
        } 
        else {
            ArrayList<String> classStack = new ArrayList();
            while(undecorate != undecorate.undecorate()) {
                if(undecorate.getClass().getName() != className) {
                    classStack.add(undecorate.getClass().getName());
                }
                undecorate = undecorate.undecorate();
            }
            for(int i = classStack.size()-1;i == 0;i--) {
                try {
                    Class<?> clazz = Class.forName(classStack.get(i));
                    Constructor<?> ctor = clazz.getConstructor(ThingInterface.class);
                    Object object = ctor.newInstance(new Object[] { undecorate });      
                    undecorate = (ThingInterface) object;
                }
                catch(Exception e) {
                    System.out.println("Exception:" + e.getMessage());
                }
            }
        }
        return undecorate;
    }

    @Override
    public ThingInterface undecorate() {
        return this.thing;
    }

    @Override
    public String nonDecoratedString() {
        return thing.nonDecoratedString();
    }

    @Override
    public String decoratedString() {
        return thing.decoratedString();
    }

}
public class ThingDecorator extends AbstractThingDecorator {
    public ThingDecorator(ThingInterface thing) {
        super(thing);
    }

    @Override
    public ThingInterface undecorate() {
        return super.undecorate();
    }

    @Override
    public String decoratedString() {
        return super.decoratedString() + ", decorated";
    }
}
public class FancyThingDecorator extends AbstractThingDecorator {
    public FancyThingDecorator(ThingInterface thing) {
        super(thing);
    }

    @Override
    public ThingInterface undecorate() {
        return super.undecorate();
    }

    @Override
    public String decoratedString() {
        return super.decoratedString() + ", fancy";
    }
}
public class Decorator {

    /**
     * @param args
     */
    public static void main(String[] args) {
        ThingInterface thing = new BaseThing("Basic string");
        ThingInterface decorator = new ThingDecorator(thing);
        ThingInterface fancyDecorator = new FancyThingDecorator(thing);
        ThingInterface extraFancy = new FancyThingDecorator(new ThingDecorator(thing));
        ThingInterface undecorate = new FancyThingDecorator(new ThingDecorator(thing));

        System.out.println("Basic thing is: " + thing.decoratedString()+".");
        System.out.println("Decorated thing is: " + decorator.decoratedString()+".");
        System.out.println("Fancy thing is: " + fancyDecorator.decoratedString()+".");
        System.out.println("Decorated fancy thing is: " + extraFancy.decoratedString()+".");

        while(extraFancy.undecorate() != extraFancy) {
            extraFancy = extraFancy.undecorate();
            System.out.println("Rolling back decorations: " + extraFancy.decoratedString()+".");
        }

        System.out.println("Decoration chain before removal is: " + undecorate.decoratedString());
        System.out.println("Removing decoration for " + ThingDecorator.class.getName());
        undecorate = undecorate.removeDecoration(ThingDecorator.class.getName());
        System.out.println("Decoration chain after removal is: " + undecorate.decoratedString()+".");

    }

}
对于这些方法,您的基类将只返回自身:

BaseThing.java

public interface ThingInterface {
    public ThingInterface undecorate();
    public ThingInterface removeDecoration(String className);
    public String nonDecoratedString();
    public String decoratedString();
}
public class BaseThing implements ThingInterface {

    private String basicString;

    public BaseThing(String string) {
        basicString = string;
    }

    @Override
    public ThingInterface undecorate() {
        return this;
    }

    @Override
    public ThingInterface removeDecoration(String className) {
        return this;
    }

    @Override
    public String nonDecoratedString() {
        return basicString;
    }

    @Override
    public String decoratedString() {
        return basicString;
    }

}
public abstract class AbstractThingDecorator implements ThingInterface {

    private ThingInterface thing;

    public AbstractThingDecorator(ThingInterface thing) {
        this.thing = thing;
    }

    @Override
    public ThingInterface removeDecoration(String className) {
        ThingInterface undecorate = this;
        if(this.getClass().getName() == className) {
            undecorate = this.undecorate();
        } 
        else {
            ArrayList<String> classStack = new ArrayList();
            while(undecorate != undecorate.undecorate()) {
                if(undecorate.getClass().getName() != className) {
                    classStack.add(undecorate.getClass().getName());
                }
                undecorate = undecorate.undecorate();
            }
            for(int i = classStack.size()-1;i == 0;i--) {
                try {
                    Class<?> clazz = Class.forName(classStack.get(i));
                    Constructor<?> ctor = clazz.getConstructor(ThingInterface.class);
                    Object object = ctor.newInstance(new Object[] { undecorate });      
                    undecorate = (ThingInterface) object;
                }
                catch(Exception e) {
                    System.out.println("Exception:" + e.getMessage());
                }
            }
        }
        return undecorate;
    }

    @Override
    public ThingInterface undecorate() {
        return this.thing;
    }

    @Override
    public String nonDecoratedString() {
        return thing.nonDecoratedString();
    }

    @Override
    public String decoratedString() {
        return thing.decoratedString();
    }

}
public class ThingDecorator extends AbstractThingDecorator {
    public ThingDecorator(ThingInterface thing) {
        super(thing);
    }

    @Override
    public ThingInterface undecorate() {
        return super.undecorate();
    }

    @Override
    public String decoratedString() {
        return super.decoratedString() + ", decorated";
    }
}
public class FancyThingDecorator extends AbstractThingDecorator {
    public FancyThingDecorator(ThingInterface thing) {
        super(thing);
    }

    @Override
    public ThingInterface undecorate() {
        return super.undecorate();
    }

    @Override
    public String decoratedString() {
        return super.decoratedString() + ", fancy";
    }
}
public class Decorator {

    /**
     * @param args
     */
    public static void main(String[] args) {
        ThingInterface thing = new BaseThing("Basic string");
        ThingInterface decorator = new ThingDecorator(thing);
        ThingInterface fancyDecorator = new FancyThingDecorator(thing);
        ThingInterface extraFancy = new FancyThingDecorator(new ThingDecorator(thing));
        ThingInterface undecorate = new FancyThingDecorator(new ThingDecorator(thing));

        System.out.println("Basic thing is: " + thing.decoratedString()+".");
        System.out.println("Decorated thing is: " + decorator.decoratedString()+".");
        System.out.println("Fancy thing is: " + fancyDecorator.decoratedString()+".");
        System.out.println("Decorated fancy thing is: " + extraFancy.decoratedString()+".");

        while(extraFancy.undecorate() != extraFancy) {
            extraFancy = extraFancy.undecorate();
            System.out.println("Rolling back decorations: " + extraFancy.decoratedString()+".");
        }

        System.out.println("Decoration chain before removal is: " + undecorate.decoratedString());
        System.out.println("Removing decoration for " + ThingDecorator.class.getName());
        undecorate = undecorate.removeDecoration(ThingDecorator.class.getName());
        System.out.println("Decoration chain after removal is: " + undecorate.decoratedString()+".");

    }

}
现在,您真正需要的是抽象类:

AbstractThingDecorator.java

public interface ThingInterface {
    public ThingInterface undecorate();
    public ThingInterface removeDecoration(String className);
    public String nonDecoratedString();
    public String decoratedString();
}
public class BaseThing implements ThingInterface {

    private String basicString;

    public BaseThing(String string) {
        basicString = string;
    }

    @Override
    public ThingInterface undecorate() {
        return this;
    }

    @Override
    public ThingInterface removeDecoration(String className) {
        return this;
    }

    @Override
    public String nonDecoratedString() {
        return basicString;
    }

    @Override
    public String decoratedString() {
        return basicString;
    }

}
public abstract class AbstractThingDecorator implements ThingInterface {

    private ThingInterface thing;

    public AbstractThingDecorator(ThingInterface thing) {
        this.thing = thing;
    }

    @Override
    public ThingInterface removeDecoration(String className) {
        ThingInterface undecorate = this;
        if(this.getClass().getName() == className) {
            undecorate = this.undecorate();
        } 
        else {
            ArrayList<String> classStack = new ArrayList();
            while(undecorate != undecorate.undecorate()) {
                if(undecorate.getClass().getName() != className) {
                    classStack.add(undecorate.getClass().getName());
                }
                undecorate = undecorate.undecorate();
            }
            for(int i = classStack.size()-1;i == 0;i--) {
                try {
                    Class<?> clazz = Class.forName(classStack.get(i));
                    Constructor<?> ctor = clazz.getConstructor(ThingInterface.class);
                    Object object = ctor.newInstance(new Object[] { undecorate });      
                    undecorate = (ThingInterface) object;
                }
                catch(Exception e) {
                    System.out.println("Exception:" + e.getMessage());
                }
            }
        }
        return undecorate;
    }

    @Override
    public ThingInterface undecorate() {
        return this.thing;
    }

    @Override
    public String nonDecoratedString() {
        return thing.nonDecoratedString();
    }

    @Override
    public String decoratedString() {
        return thing.decoratedString();
    }

}
public class ThingDecorator extends AbstractThingDecorator {
    public ThingDecorator(ThingInterface thing) {
        super(thing);
    }

    @Override
    public ThingInterface undecorate() {
        return super.undecorate();
    }

    @Override
    public String decoratedString() {
        return super.decoratedString() + ", decorated";
    }
}
public class FancyThingDecorator extends AbstractThingDecorator {
    public FancyThingDecorator(ThingInterface thing) {
        super(thing);
    }

    @Override
    public ThingInterface undecorate() {
        return super.undecorate();
    }

    @Override
    public String decoratedString() {
        return super.decoratedString() + ", fancy";
    }
}
public class Decorator {

    /**
     * @param args
     */
    public static void main(String[] args) {
        ThingInterface thing = new BaseThing("Basic string");
        ThingInterface decorator = new ThingDecorator(thing);
        ThingInterface fancyDecorator = new FancyThingDecorator(thing);
        ThingInterface extraFancy = new FancyThingDecorator(new ThingDecorator(thing));
        ThingInterface undecorate = new FancyThingDecorator(new ThingDecorator(thing));

        System.out.println("Basic thing is: " + thing.decoratedString()+".");
        System.out.println("Decorated thing is: " + decorator.decoratedString()+".");
        System.out.println("Fancy thing is: " + fancyDecorator.decoratedString()+".");
        System.out.println("Decorated fancy thing is: " + extraFancy.decoratedString()+".");

        while(extraFancy.undecorate() != extraFancy) {
            extraFancy = extraFancy.undecorate();
            System.out.println("Rolling back decorations: " + extraFancy.decoratedString()+".");
        }

        System.out.println("Decoration chain before removal is: " + undecorate.decoratedString());
        System.out.println("Removing decoration for " + ThingDecorator.class.getName());
        undecorate = undecorate.removeDecoration(ThingDecorator.class.getName());
        System.out.println("Decoration chain after removal is: " + undecorate.decoratedString()+".");

    }

}
FancyThingDecorator.java

public interface ThingInterface {
    public ThingInterface undecorate();
    public ThingInterface removeDecoration(String className);
    public String nonDecoratedString();
    public String decoratedString();
}
public class BaseThing implements ThingInterface {

    private String basicString;

    public BaseThing(String string) {
        basicString = string;
    }

    @Override
    public ThingInterface undecorate() {
        return this;
    }

    @Override
    public ThingInterface removeDecoration(String className) {
        return this;
    }

    @Override
    public String nonDecoratedString() {
        return basicString;
    }

    @Override
    public String decoratedString() {
        return basicString;
    }

}
public abstract class AbstractThingDecorator implements ThingInterface {

    private ThingInterface thing;

    public AbstractThingDecorator(ThingInterface thing) {
        this.thing = thing;
    }

    @Override
    public ThingInterface removeDecoration(String className) {
        ThingInterface undecorate = this;
        if(this.getClass().getName() == className) {
            undecorate = this.undecorate();
        } 
        else {
            ArrayList<String> classStack = new ArrayList();
            while(undecorate != undecorate.undecorate()) {
                if(undecorate.getClass().getName() != className) {
                    classStack.add(undecorate.getClass().getName());
                }
                undecorate = undecorate.undecorate();
            }
            for(int i = classStack.size()-1;i == 0;i--) {
                try {
                    Class<?> clazz = Class.forName(classStack.get(i));
                    Constructor<?> ctor = clazz.getConstructor(ThingInterface.class);
                    Object object = ctor.newInstance(new Object[] { undecorate });      
                    undecorate = (ThingInterface) object;
                }
                catch(Exception e) {
                    System.out.println("Exception:" + e.getMessage());
                }
            }
        }
        return undecorate;
    }

    @Override
    public ThingInterface undecorate() {
        return this.thing;
    }

    @Override
    public String nonDecoratedString() {
        return thing.nonDecoratedString();
    }

    @Override
    public String decoratedString() {
        return thing.decoratedString();
    }

}
public class ThingDecorator extends AbstractThingDecorator {
    public ThingDecorator(ThingInterface thing) {
        super(thing);
    }

    @Override
    public ThingInterface undecorate() {
        return super.undecorate();
    }

    @Override
    public String decoratedString() {
        return super.decoratedString() + ", decorated";
    }
}
public class FancyThingDecorator extends AbstractThingDecorator {
    public FancyThingDecorator(ThingInterface thing) {
        super(thing);
    }

    @Override
    public ThingInterface undecorate() {
        return super.undecorate();
    }

    @Override
    public String decoratedString() {
        return super.decoratedString() + ", fancy";
    }
}
public class Decorator {

    /**
     * @param args
     */
    public static void main(String[] args) {
        ThingInterface thing = new BaseThing("Basic string");
        ThingInterface decorator = new ThingDecorator(thing);
        ThingInterface fancyDecorator = new FancyThingDecorator(thing);
        ThingInterface extraFancy = new FancyThingDecorator(new ThingDecorator(thing));
        ThingInterface undecorate = new FancyThingDecorator(new ThingDecorator(thing));

        System.out.println("Basic thing is: " + thing.decoratedString()+".");
        System.out.println("Decorated thing is: " + decorator.decoratedString()+".");
        System.out.println("Fancy thing is: " + fancyDecorator.decoratedString()+".");
        System.out.println("Decorated fancy thing is: " + extraFancy.decoratedString()+".");

        while(extraFancy.undecorate() != extraFancy) {
            extraFancy = extraFancy.undecorate();
            System.out.println("Rolling back decorations: " + extraFancy.decoratedString()+".");
        }

        System.out.println("Decoration chain before removal is: " + undecorate.decoratedString());
        System.out.println("Removing decoration for " + ThingDecorator.class.getName());
        undecorate = undecorate.removeDecoration(ThingDecorator.class.getName());
        System.out.println("Decoration chain after removal is: " + undecorate.decoratedString()+".");

    }

}
最后,我的java主页:

Decorator.java

public interface ThingInterface {
    public ThingInterface undecorate();
    public ThingInterface removeDecoration(String className);
    public String nonDecoratedString();
    public String decoratedString();
}
public class BaseThing implements ThingInterface {

    private String basicString;

    public BaseThing(String string) {
        basicString = string;
    }

    @Override
    public ThingInterface undecorate() {
        return this;
    }

    @Override
    public ThingInterface removeDecoration(String className) {
        return this;
    }

    @Override
    public String nonDecoratedString() {
        return basicString;
    }

    @Override
    public String decoratedString() {
        return basicString;
    }

}
public abstract class AbstractThingDecorator implements ThingInterface {

    private ThingInterface thing;

    public AbstractThingDecorator(ThingInterface thing) {
        this.thing = thing;
    }

    @Override
    public ThingInterface removeDecoration(String className) {
        ThingInterface undecorate = this;
        if(this.getClass().getName() == className) {
            undecorate = this.undecorate();
        } 
        else {
            ArrayList<String> classStack = new ArrayList();
            while(undecorate != undecorate.undecorate()) {
                if(undecorate.getClass().getName() != className) {
                    classStack.add(undecorate.getClass().getName());
                }
                undecorate = undecorate.undecorate();
            }
            for(int i = classStack.size()-1;i == 0;i--) {
                try {
                    Class<?> clazz = Class.forName(classStack.get(i));
                    Constructor<?> ctor = clazz.getConstructor(ThingInterface.class);
                    Object object = ctor.newInstance(new Object[] { undecorate });      
                    undecorate = (ThingInterface) object;
                }
                catch(Exception e) {
                    System.out.println("Exception:" + e.getMessage());
                }
            }
        }
        return undecorate;
    }

    @Override
    public ThingInterface undecorate() {
        return this.thing;
    }

    @Override
    public String nonDecoratedString() {
        return thing.nonDecoratedString();
    }

    @Override
    public String decoratedString() {
        return thing.decoratedString();
    }

}
public class ThingDecorator extends AbstractThingDecorator {
    public ThingDecorator(ThingInterface thing) {
        super(thing);
    }

    @Override
    public ThingInterface undecorate() {
        return super.undecorate();
    }

    @Override
    public String decoratedString() {
        return super.decoratedString() + ", decorated";
    }
}
public class FancyThingDecorator extends AbstractThingDecorator {
    public FancyThingDecorator(ThingInterface thing) {
        super(thing);
    }

    @Override
    public ThingInterface undecorate() {
        return super.undecorate();
    }

    @Override
    public String decoratedString() {
        return super.decoratedString() + ", fancy";
    }
}
public class Decorator {

    /**
     * @param args
     */
    public static void main(String[] args) {
        ThingInterface thing = new BaseThing("Basic string");
        ThingInterface decorator = new ThingDecorator(thing);
        ThingInterface fancyDecorator = new FancyThingDecorator(thing);
        ThingInterface extraFancy = new FancyThingDecorator(new ThingDecorator(thing));
        ThingInterface undecorate = new FancyThingDecorator(new ThingDecorator(thing));

        System.out.println("Basic thing is: " + thing.decoratedString()+".");
        System.out.println("Decorated thing is: " + decorator.decoratedString()+".");
        System.out.println("Fancy thing is: " + fancyDecorator.decoratedString()+".");
        System.out.println("Decorated fancy thing is: " + extraFancy.decoratedString()+".");

        while(extraFancy.undecorate() != extraFancy) {
            extraFancy = extraFancy.undecorate();
            System.out.println("Rolling back decorations: " + extraFancy.decoratedString()+".");
        }

        System.out.println("Decoration chain before removal is: " + undecorate.decoratedString());
        System.out.println("Removing decoration for " + ThingDecorator.class.getName());
        undecorate = undecorate.removeDecoration(ThingDecorator.class.getName());
        System.out.println("Decoration chain after removal is: " + undecorate.decoratedString()+".");

    }

}
输出为:

基本的东西是:基本字符串

装饰的东西是:基本串,装饰的

花式的东西是:基本的弦,花式的

装饰花式的东西是:基本串,装饰,花式

回滚装饰:基本字符串,装饰

回滚装饰:基本字符串

拆前装饰链是:基本串、装饰、花式

去除装饰物


拆下后的装饰链是:基本串,花式。

对不起,我英语不好。这意味着我装饰了一个对象,我想删除一个已经装饰过的对象。例如:我有一台电脑,然后我将它添加到硬盘、屏幕和CD驱动器中。但过了一会儿,我取出了CD驱动器,我的电脑只有显示器和硬盘。这些设备删除了随机和随机选项。我正在寻找这个问题的最佳解决方案谢谢你的回答,但我不想得到装饰物。我想在移除装饰器之前获得装饰对象。公共计算机getDecorated(){return Computer;}此方法返回一个修饰对象,这不是必需的,因为构造函数已经在执行它修饰对象/取消修饰对象…您能告诉我更好的方法是什么吗?不过现在。。。你们所拥有的不是更像拦截器而不是装饰器吗?