javaデザインモード-装飾者モード詳細


例を引く
需要:今は単品のコーヒーがあります。Espreso(イタリアエスプレッソ)とLongBlack(アメリカンコーヒー)があります。ソースはMilk(牛乳)とsugar(砂糖)があります。お客様は単品のコーヒーまたは単品のコーヒー+ソースの組み合わせを注文して、費用を計算します。新しいコーヒーの種類を広げる時に、いい拡張性とメンテナンスの便利さが要求されます。
レンガを投げて玉を引くなら、まず二つの一般的な解法を見てみましょう。
一般解法
プラン一、
エニュメレーションは、各組み合わせを作成することができます。Drink抽象類は飲み物を表し、cost()方法は価格を計算します。
在这里插入图片描述
このように設計するのは非常に賢明ではないです。多くの種類があります。コーヒーや調味料を追加すると、種類の数が倍になり、爆発が起きます。
案二、
調味料をLongblack_Milk類に内蔵して、種類数を減らすのは多すぎます。
在这里插入图片描述
プログラム2は多くの種類にはならないが、ソースを追加または削除する場合、コードの維持量は依然として大きい。
装飾者モード
装飾者モード(Decorator Pattern)は構造型のモードで、装飾器モード/修飾モードとも呼ばれます。新しい機能をオブジェクトに動的に付加することができますが、その構造は変更されません。物体の機能拡張に関しては,継承よりも弾性的である。このモードは、元のクラスを包装するための装飾クラスを作成し、クラス法の完全性を維持する前提で、追加の機能を提供します。
クラス図:
在这里插入图片描述
  • Component抽象類:本体、例えば前のDrinkに似ています。
  • Cocrete Component類:具体的な主体、例えば前の単品コーヒー。
  • Decorator類:装飾者、例えば前の調味料
  • Cocrete Decorator類:具体的な装飾者、例えば前の牛乳。
  • Concrete Componentの具体的なサブクラスが多いなら、もう一つの中間層を加えて、共通部分を抽出して、継承によってもっと違った具体的なサブクラスを実現します。
    装飾者解法
    クラス図:
    在这里插入图片描述
    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)を含みます。
    この文章はここまでです。あなたに助けを与えたいです。私たちのもっと多い内容に注目してください。