6

「ダミーのデザインパターン」を読んでいます。Decorator Pattern を読んで練習しました。Decorator パターンを使用すると、オブジェクトを何でも装飾できます。さて、装飾されたオブジェクトを削除してから装飾したいと思います。この問題は ArrayList で解決しましたが、まだ良くないと感じています。装飾されたオブジェクトを削除する方法を教えてもらえますか? そして、より良い方法は何ですか?

これが私のやり方です:

コンピューター.java

public class Computer {

    public Computer() {
    }

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

}

ComponentDecorator.java

public abstract class ComponentDecorator extends Computer {
    @Override
    public abstract String description();
}

CD.java

public class CD extends ComponentDecorator {
    private Computer computer;

    public CD() {
    }

    public CD(Computer computer) {
        this.computer = computer;
    }

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

}

ディスク.java

public class Disk extends ComponentDecorator {
    private Computer computer;

    public Disk() {
    }

    public Disk(Computer c) {
        computer = c;
    }

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

}

Monitor.java

public class Monitor extends ComponentDecorator {
    private Computer computer;

    public Monitor() {
    }

    public Monitor(Computer computer) {
        this.computer = computer;
    }

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

}

Main.java

import java.util.ArrayList;
import java.util.Arrays;

public class Main {
    static ArrayList<ComponentDecorator> list = new ArrayList<>();

    public static void main(String[] args) {
        addComponent(new CD(), new Disk(), new Monitor());
        System.out.println(list.size());
        Computer penIII = getComputer();
        removeComponent(new Monitor());
        penIII = getComputer();
        System.out.println(penIII.description());
    }

    private static void addComponent(ComponentDecorator... comp) {
        list.addAll(Arrays.asList(comp));
    }

    private static void removeComponent(ComponentDecorator comp) {
        for(ComponentDecorator c : list) {
            if(c.getClass() == comp.getClass()) {
                list.remove(list.indexOf(c));
                break;
            }
        }
    }

    private static Computer getComputer() {
        Computer c = new Computer();
        Class e;
        for(ComponentDecorator d : list) {
            e = d.getClass();
            try {
                c = (Computer) e.getConstructor(new Class[]{Computer.class}).newInstance(c);
            } catch(Exception ex) {
                ex.printStackTrace();
            }
        }
        return c;
    }
}
4

3 に答える 3

10

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

}

削除するデコレータの参照がない場合は、代わりに Class である別のメソッドを作成できます。

ただし、「Computer」ではなく「ComponentDecorator」として装飾されたオブジェクトが必要です。その逆ではなく、Computer クラスが ComponentDecorator を拡張するようにすることをお勧めします。

于 2012-09-02T23:28:28.220 に答える
1

私はあなたの質問を誤解していると思いますが、装飾された (内側の) オブジェクトをデコレーターから取り出すには、デコレーターに get メソッドを追加するだけです。追加

public abstract Computer getDecorated();

ComponentDecorator と

public Computer getDecorated(){return computer;}

各サブクラス (CD、モニターなど) に。それはあなたが探していたものですか?

于 2012-09-02T21:50:08.230 に答える