設計模式——裝飾者模式

1. 情景

面館開張了,主營2種面:酸菜面、牛肉面;外加2種配料:雞蛋、豆皮

裝飾者模式來設計這一訂單系統:

滿足要求:可以返回點的名稱、計算總價格

2. 設計

大體思路:

這里要說的是雞蛋、豆皮是裝飾者,為了讓他可以任意的加配料,返回仍是面條類。

類設計圖:

3. 實現

面條抽象類

public abstract class Noodle {
    String description = "Unknown Name";

    public String getDescription() {
        return description;
    }

    public abstract double cost();
}

裝飾者抽象類

public abstract class CondimentDecorator extends Noodle {
    @Override
    public abstract String getDescription();
}

面條具體類--酸菜面

public class SuancaiNoodle extends Noodle{
    SuancaiNoodle() {
        description = "Suancai Noodle";
    }
    @Override
    public double cost() {
        return 10;
    }
}

面條具體類--牛肉面

public abstract class Noodle {
    String description = "Unknown Name";

    public String getDescription() {
        return description;
    }

    public abstract double cost();
}

配料具體類--雞蛋

public class Egg extends CondimentDecorator{
    private Noodle noodle;
    Egg(Noodle noodle) {
        this.noodle = noodle;
    }
    @Override
    public String getDescription() {
        return noodle.getDescription() + " + Egg";
    }

    @Override
    public double cost() {
        return noodle.cost() + 2;
    }
}

配料具體類--豆皮

public class SkinOfTofu extends CondimentDecorator{
    private Noodle noodle;

    SkinOfTofu(Noodle noodle) {
        this.noodle = noodle;
    }

    @Override
    public String getDescription() {
        return noodle.getDescription() + " + SkinOfTofu";
    }

    @Override
    public double cost() {
        return noodle.cost() + 1;
    }
}

4. 測試

public class NoodleTest {
    public static void main(String[] args) {
        Noodle suancai = new SuancaiNoodle();
        Noodle addEgg = new Egg(suancai);
        Noodle addEggSkin = new SkinOfTofu(addEgg);
        System.out.println(addEggSkin.getDescription());
        System.out.println(addEggSkin.cost());

        System.out.println("-----");

        Noodle beef = new BeefNoodle();
        Noodle addEgg2 = new Egg(beef);
        System.out.println(addEgg2.getDescription());
        System.out.println(addEgg2.cost());
    }
}

結果

Suancai Noodle + Egg + SkinOfTofu
13.0
-----
Beef Noodle + Egg
14.0

5.java  I/O

其中InputStream是抽象組件

其下一列如FileInputStream是抽象裝飾者,BufferedInputStream是具體裝飾者

用法舉例

public class ReadFileTest {
    public static void main(String[] args) {
        try {
            FileInputStream fis = new FileInputStream("jihite/test.json");
            BufferedInputStream bis = new BufferedInputStream(fis);
            BufferedInputStream bis2 = new BufferedInputStream(bis);
            byte[] b = new byte[bis2.available()];
            bis2.read(b);

            System.out.println(new String(b));
            bis2.close();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }
}

6. 歸納

定義:

在不必改變原類文件和使用繼承的情況下,動態地擴展一個對象的功能。它是通過創建一個包裝對象,也就是裝飾來包裹真實的對象。

設計原則:

  • 多組合、少繼承
  • 對擴展開放、對修改關閉

優點:

  • Decorator模式與繼承關系的都是要擴展對象,但是Decorator可以提供比繼承更多的靈活性
  • 通過使用不同的具體裝飾類以及這些裝飾類的排列組合,設計師可以創造出很多不同行為的組合
缺點:
  • 比繼承更加靈活也同時意味著更加多的復雜性
  • 導致設計中出現許多小類,如果過度使用,會使程序變得很復雜
posted @ 2018-11-03 13:33 jihite 閱讀(...) 評論(...) 編輯 收藏
耐克篮球多少钱