javaデザインモード-装飾者モード詳細
例を引く
需要:今は単品のコーヒーがあります。Espreso(イタリアエスプレッソ)とLongBlack(アメリカンコーヒー)があります。ソースはMilk(牛乳)とsugar(砂糖)があります。お客様は単品のコーヒーまたは単品のコーヒー+ソースの組み合わせを注文して、費用を計算します。新しいコーヒーの種類を広げる時に、いい拡張性とメンテナンスの便利さが要求されます。
レンガを投げて玉を引くなら、まず二つの一般的な解法を見てみましょう。
一般解法
プラン一、
エニュメレーションは、各組み合わせを作成することができます。
このように設計するのは非常に賢明ではないです。多くの種類があります。コーヒーや調味料を追加すると、種類の数が倍になり、爆発が起きます。
案二、
調味料を
プログラム2は多くの種類にはならないが、ソースを追加または削除する場合、コードの維持量は依然として大きい。
装飾者モード
装飾者モード(Decorator Pattern)は構造型のモードで、装飾器モード/修飾モードとも呼ばれます。新しい機能をオブジェクトに動的に付加することができますが、その構造は変更されません。物体の機能拡張に関しては,継承よりも弾性的である。このモードは、元のクラスを包装するための装飾クラスを作成し、クラス法の完全性を維持する前提で、追加の機能を提供します。
クラス図:
Component抽象類:本体、例えば前のDrinkに似ています。 Cocrete Component類:具体的な主体、例えば前の単品コーヒー。 Decorator類:装飾者、例えば前の調味料 Cocrete Decorator類:具体的な装飾者、例えば前の牛乳。 Concrete Componentの具体的なサブクラスが多いなら、もう一つの中間層を加えて、共通部分を抽出して、継承によってもっと違った具体的なサブクラスを実現します。
装飾者解法
クラス図:
Drink類とは、前述した抽象的なDecoratorの装飾類であり、装飾された対象(Drink Oj)とを含むcost()の方法で費用の重畳計算を行い、再帰的な計算価格MilkとSugerは具体的な装飾者Coffeeであり、装飾された者本体LongBlackとEspresoは具体的に実現された被装飾者エンティティである。
コード:
抽象類
まとめ:
装飾者モードは宅急便を包装するように、絶えず動的に新しい機能を追加し、すべての状況を組み合わせることができます。
一つ目のMilkにはEspresoが含まれています。
第二部Milkは(Milk+Espreso)を含みます。
Sugerは(Milk+Milk+Espreso)を含みます。
この文章はここまでです。あなたに助けを与えたいです。私たちのもっと多い内容に注目してください。
需要:今は単品のコーヒーがあります。Espreso(イタリアエスプレッソ)とLongBlack(アメリカンコーヒー)があります。ソースはMilk(牛乳)とsugar(砂糖)があります。お客様は単品のコーヒーまたは単品のコーヒー+ソースの組み合わせを注文して、費用を計算します。新しいコーヒーの種類を広げる時に、いい拡張性とメンテナンスの便利さが要求されます。
レンガを投げて玉を引くなら、まず二つの一般的な解法を見てみましょう。
一般解法
プラン一、
エニュメレーションは、各組み合わせを作成することができます。
Drink
抽象類は飲み物を表し、cost()
方法は価格を計算します。このように設計するのは非常に賢明ではないです。多くの種類があります。コーヒーや調味料を追加すると、種類の数が倍になり、爆発が起きます。
案二、
調味料を
Longblack_Milk
類に内蔵して、種類数を減らすのは多すぎます。プログラム2は多くの種類にはならないが、ソースを追加または削除する場合、コードの維持量は依然として大きい。
装飾者モード
装飾者モード(Decorator Pattern)は構造型のモードで、装飾器モード/修飾モードとも呼ばれます。新しい機能をオブジェクトに動的に付加することができますが、その構造は変更されません。物体の機能拡張に関しては,継承よりも弾性的である。このモードは、元のクラスを包装するための装飾クラスを作成し、クラス法の完全性を維持する前提で、追加の機能を提供します。
クラス図:
装飾者解法
クラス図:
Drink類とは、前述した抽象的なDecoratorの装飾類であり、装飾された対象(Drink Oj)とを含むcost()の方法で費用の重畳計算を行い、再帰的な計算価格MilkとSugerは具体的な装飾者Coffeeであり、装飾された者本体LongBlackとEspresoは具体的に実現された被装飾者エンティティである。
コード:
抽象類
public abstract class Drink {//
public String des; //
private float price = 0.0f;
public String getDes() {
return des;
}
public void setDes(String des) {
this.des = des;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
//
public abstract float cost();
}
飾り物師
public class Decorator extends Drink {//
private Drink obj;
public Decorator(Drink obj) { //
this.obj = obj;
}
@Override
public float cost() {
// getPrice
return super.getPrice() + obj.cost();
}
@Override
public String getDes() {
// obj.getDes()
return des + " " + getPrice() + " && " + obj.getDes();
}
}
public class Milk extends Decorator {//
public Milk(Drink obj) {
super(obj);
setDes(" ");
setPrice(2.0f);
}
}
public class Suger extends Decorator {//
public Suger(Drink obj) {
super(obj);
setDes(" ");
setPrice(1.0f);
}
}
飾り物師
public class Coffee extends Drink {//
@Override
public float cost() {
return super.getPrice();
}
}
public class Espresso extends Coffee {//
public Espresso() {
setDes(" ");
setPrice(6.0f);
}
}
public class LongBlack extends Coffee {//
public LongBlack() {
setDes(" ");
setPrice(5.0f);
}
}
クライアントテスト
public class Client {
public static void main(String[] args) {
// : 、
// 1. Espresso
Drink order = new Espresso();
System.out.println("order1 =" + order.cost());
System.out.println("order1 =" + order.getDes());
// 2.1 order
order = new Milk(order);
System.out.println("order =" + order.cost());
System.out.println("order = " + order.getDes());
// 2.2 order
order = new Milk(order);
System.out.println("order =" + order.cost());
System.out.println("order = " + order.getDes());
// 3. order
order = new Suger(order);
System.out.println("order 、 =" + order.cost());
System.out.println("order 、 = " + order.getDes());
System.out.println("===========================");
//
//1. LongBlack
Drink order2 = new LongBlack();
System.out.println("order2 =" + order2.cost());
System.out.println("order2 = " + order2.getDes());
//2. order2
order2 = new Milk(order2);
System.out.println("order2 =" + order2.cost());
System.out.println("order2 = " + order2.getDes());
}
}
実行結果:まとめ:
装飾者モードは宅急便を包装するように、絶えず動的に新しい機能を追加し、すべての状況を組み合わせることができます。
一つ目のMilkにはEspresoが含まれています。
第二部Milkは(Milk+Espreso)を含みます。
Sugerは(Milk+Milk+Espreso)を含みます。
この文章はここまでです。あなたに助けを与えたいです。私たちのもっと多い内容に注目してください。