第三読書今日はデザインパターンの話、続きを読む、Decoratorパターン、装飾を通じて、私たちは、新しい機能を提供するために、コードのコードベースを変更することはできません。
Decoratorパターンのコンセプト
オブジェクトに添付Decoratorパターンの動的責任。機能を拡張するには、継承の代替よりも柔軟に提供するために装飾されました。
コンセプトは、それがあること、誕生日の贈り物、包装に愛のプットのトークンとして使用することができ、我々は彼に誕生日のギフト包装を置けば、同じ袋のような内装が施され、名前は非常に人気があり、簡単なようですそれは愛のトークンとして使用することができます。
例は、材料を追加することは何も追加する必要がどのような材料、コーヒーカフェを購入する本です。私たちは、このようなスチームミルク、豆乳、モカやミルクの泡などで覆われた、コーヒースパイス、さまざまなを追加する必要があります。コーヒーショップでは、追加異なるスパイスに基づいて料金を請求されます。
ビルドへの最も簡単な方法は、など牛乳、豆乳、コスト()メソッド、様々なスパイスの合計金額を計算し、サブクラスがコスト()メソッドに加えて、基本的な飲料を上書きするようにいくつかのプロパティを含む、スーパークラスBeerageを設計することです価格。
モデル誤差
上記の継承コーヒーの例としては、我々は非常に厄介なデザインを見てください。
最初のクラスは、構造設計を繰り返し、スパイスです。
public class Milk {
private String description;
private float price;
public Milk(float price) {
this.description = "Milk";
this.price = price;
}
public float getPrice() {
return price;
}
@Override
public String toString() {
return "Milk{" +
"price=" + price +
'}';
}
}
public class Mocha {
private String description;
private float price;
public Mocha(float price) {
this.description = "Mocha";
this.price = price;
}
public float getPrice() {
return price;
}
@Override
public String toString() {
return "Mocha{" +
"price=" + price +
'}';
}
}
単純に2を入れます調味クラス、すべての後に、限り、二つの性質とgetter()メソッドで十分ですがあるので、実際には、トラブルを書くために私に尋ねました。次はスーパーの飲料である、調味料は、すべてのプロパティが含まれており、すべてのスパイスの合計金額を計算するコスト()メソッドがあります。
public class Beverage {
private String description;
private Milk milk;
private Soy soy;
private Mocha mocha;
private Whip whip;
private float price;
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Milk getMilk() {
return milk;
}
public void setMilk(Milk milk) {
this.milk = milk;
}
public Soy getSoy() {
return soy;
}
public void setSoy(Soy soy) {
this.soy = soy;
}
public Mocha getMocha() {
return mocha;
}
public void setMocha(Mocha mocha) {
this.mocha = mocha;
}
public Whip getWhip() {
return whip;
}
public void setWhip(Whip whip) {
this.whip = whip;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
public float cost() {
return milk.getPrice() + soy.getPrice() + mocha.getPrice() + whip.getPrice();
}
}
最後の飲み物である、と何気なくアコ飲料であるクラスを、設計し、主な役割は、飲み物や食材とリターンの価格を計算するためのコスト()メソッドを書き換えることです。
あなたはそこを控えることができませんか?愚かなこのデザインは、飲み物を持って、新しいクラスのすべての新しいデザインは、複数の成分よりもあれば、ないバーストテーブルに恐れて設計された飲みます。
:私たちは、設計原理と接触して来たクラスは拡張のために開いている必要がありますが、変更のため閉鎖しました。
オープン - クローズ原則、最も重要な設計原理の一つ。新しい動作缶で既存のコードを変更することなく、簡単に拡張タイプを可能にします。彼らはこの目標を達成することができれば、我々はそれが良好な柔軟性を持って設計し、需要の変化に対応するための新機能を受け取るために、変化に対応することができます。
上に示したように、我々は例えば、今、あなたは、次の手順に従いミルクフォームモカ、ダークローストコーヒーを準備する必要があり、飲み物を飾るために調味料、私たちのテーマとして飲むする必要があるので、継承は、確かにこの問題を解決するための良い方法ではありません。
- 深い焙煎コーヒーのオブジェクトを取ります
- モカは、オブジェクトとそれを飾ります
- これは、ミルクの泡のオブジェクトで飾られています
- 通話コスト()メソッド、および手数料は、追加するスパイスの価格に依存します
完了する準備ができて、このようなコーヒー。今度は、Decoratorパターンを使用するコードを見てみましょう。
コードの実装
まず、飲料、それは説明属性、価格を計算するためのコスト()抽象メソッドを備え、すべてのクラスの親クラスです。
public abstract class Beverage {
String description = "Unknown Beverage";
public String getDescription() {
return description;
}
public abstract double cost();
}
次は、抽象スーパークラスの調味クラスです。
public abstract class CondimentDecorator extends Beverage {
public abstract String getDescription();
}
二つの飲み物。
public class Espresso extends Beverage {
public Espresso() {
description = "Espresso";
}
@Override
public double cost() {
return 1.99;
}
}
public class HouseBlend extends Beverage {
public HouseBlend() {
description = "House Blend Coffee";
}
@Override
public double cost() {
return .89;
}
}
調味クラス。
public class Mocha extends CondimentDecorator {
Beverage beverage;
public Mocha(Beverage beverage) {
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription() + ", Mocha";
}
@Override
public double cost() {
return .20 + beverage.cost();
}
}
テストケース。
public class StarbuzzCoffee {
public static void main(String[] args) {
Espresso espresso = new Espresso();
System.out.println(espresso.getDescription() + " $" + espresso.cost());
HouseBlend houseBlend = new HouseBlend();
Mocha mocha = new Mocha(houseBlend);
Mocha mocha1 = new Mocha(mocha);
System.out.println(mocha1.getDescription() + " $" + mocha1.cost());
}
}
我々は価格を得るために継承getDescrition()メソッド、コスト()メソッドによって記述ドリンクを取得し、最初の一杯を作成し、メソッドを使用して見てみましょう。
第二は、カテゴリによって2回コーヒー、パッケージ材料を作成し、その情報と価格を印刷します。
コードは、私たちが飲み物は、プロパティが含まれているため、情報アップ飲料セットに作成されたとき、あなたはドリンクに紙袋を包むこれらの層を追加することができ、成分情報が設定されている成分を継承して、親クラスに新しい成分を追加する必要がある場合、明確です加えて、コスト()メソッド内の()、計算結果によって産コーヒー、飲料メソッド呼び出しコストの成分の添加です。
ここでDecoratorパターン全体に終わった、ちょうど装飾品や装飾品トップレベルの親クラスを継承することを覚えておいてください、そして、デコレータのために同じと同様の方法で行われる装飾されたプロパティデコレータオブジェクトを含み、方法を飾ります。ジャワ、IOでDecoratorパターンを多く含む非常に実用的なアプリケーションには、ソースコードを見ることができます。