古典的なコーヒーデコレータの例(Wikipediaからコピーされています)を考えます。一般的なメンバーを置く場所デコレータの変数
public interface Coffee {
public double getCost();
}
public class SimpleCoffee implements Coffee {
public double getCost() {
return 1;
}
}
public abstract class CoffeeDecorator implements Coffee {
protected final Coffee decoratedCoffee;
public CoffeeDecorator(Coffee c) {
this.decoratedCoffee = c;
}
public double getCost() {
return decoratedCoffee.getCost();
}
}
class WithMilk extends CoffeeDecorator {
public WithMilk(Coffee c) {
super(c);
}
public double getCost() {
return super.getCost() + 0.5;
}
}
のは、すべてのデコレータ(例えばミルク)の価格は、すべてのコーヒーを持っている(コーヒーの大きさを言う)、コーヒーの大きさは他の場所では使用されないことになると、いくつかの属性に依存して、今言ってみましょう。どこのクラスの階層にコーヒーのサイズを追加する必要がありますか?
私は(それが公衆に設定すると、それが保護に設定すると、サイズが不必要
を暴露され、デコレータは本当にdecoratedCoffeeを介してアクセスすることはできませんコーヒーインタフェース
public interface Coffee {
public double getCost(); // Returns the cost of the coffee
public/protected double size;
}
にそれを置くことができます私はCoffeeDecoratorにそれを置くことができます
この記事Java: cannot access a protected member of the superclass in the extending subclassとWhy can't a derived class call protected member function in this code?)を参照してください、その後私は
にコンストラクタを変更する必要があります私は置くことができます(私はnull以外のサイズのいずれかがどちらかのオプションではありません見つけるまで明らかにdecoratedCoffee
秒のチェーンを掘り)何とか...最もエレガントな解決策のように見えるしていません
public CoffeeDecorator(Coffee c) {
if c is of type CoffeeDecorator
size = c.size;
this.decoratedCoffee = c;
}
それは単にデザイン原則に反する各デコレータにあります。
私はこのシナリオがかなり頻繁に起こると確信しています。そのようなケースを処理する最良の方法は何か知りたいのですが?
ありがとうございます。
---編集31/3/2016 ---
特定の属性(今コーヒーサイズに改名以前カップサイズは、)すべてのコーヒーを持っているべきものであることを明確にします。
おそらく、コーヒーサイズはより良い用語になるだろう、キーはデコレータがすべてのコーヒーに存在する「いくつかの属性」に依存していることである、私は明確にするだろう – Woofas
@Woofasそれでも明確ではない、 "コーヒーサイズ"はどういう意味ですか?そしてデコレータがそれにどれだけ依存しているのですか?なぜ、getCost()(いくつかの 'getSize()'メソッド)と同じ方法で追加することはできませんか、この属性をまったく公開せず、tell([tell、do not ask] http://martinfowler.com/bliki/TellDontAsk.html)) 'コーヒー'オブジェクトは、この 'サイズ'に応じて何かをするのですか?一般的に、 'coffee size'の例はまだ現実的ではないので、正確に何が問題なのか明確ではありません。 –