1. 程式人生 > >設計模式-裝飾者模式(Decorator)

設計模式-裝飾者模式(Decorator)

概述

  • 定義 : 在不改變原有物件的基礎之上, 將功能附加到物件上
  • 提供了比繼承更有彈性的替代方案(擴充套件原有物件功能)
  • 又叫包裝器Wrapper, 介面卡模式也被稱之為包裝器
  • 型別 : 結構型

適用場景

  • 擴充套件一個類的功能或給一個類新增附加職責
  • 動態的給一個物件新增功能, 這些功能可以再動態的撤銷

優點

  • 繼承放入有力補充, 比繼承靈活, 在不改變原有物件的情況下給一個物件擴充套件功能
  • 通過使用不同裝飾類以及這些裝飾類的排列組合, 可以實現不同效果

缺點

  • 會出現更多的程式碼, 更多的類, 增加程式複雜性
  • 動態裝飾時, 多層裝飾時更復雜

模式角色

  • Component : 定義一個物件介面,可以給這些物件動態地新增職責

  • ConcreteComponent : 定義一個物件,可以給這個物件新增一些職責

  • Decorator : 維持一個指向Component物件的引用,並定義一個與Component介面一致的介面, Java中通常是使用構造器接收Component, Java中通常裝飾者類和被裝飾的類實現同樣的介面, 所以這個角色大多數時候就使用Component介面

  • ConcreteDecorator : 向元件新增職責, Java中代表包裝類

程式碼實現

業務場景

有一個coffee介面, 有一個實現類coffee, 如果需要加一份牛奶的話, 就呼叫牛奶裝飾器, 如果需要加糖的話, 就呼叫加糖的裝飾器, 最終可以展示coffee中加了哪些東西, 加完之後的價格是多少

UML類圖

在這裡插入圖片描述

程式碼實現

Icoffee介面:

/**
 * 被裝飾的類介面
 * 這裡也可以使用抽象類實現
 * @author 七夜雪
 * @create 2018-11-23 14:40
 */
public interface ICoffee {
    public void showDesc();

    public String getDesc
(); public int getPrice(); }

Coffee類:

/**
 * 普通的Coffee類
 *
 * @author 七夜雪
 * @create 2018-11-23 14:41
 */
public class Coffee implements ICoffee {
    private String desc = "一杯咖啡";
    private int price = 20;

    @Override
    public void showDesc() {
        System.out.println(desc + "  價格為:" + price);
    }

    @Override
    public String getDesc() {
        return desc;
    }

    @Override
    public int getPrice() {
        return price;
    }
}

牛奶包裝類:

/**
 * 牛奶裝飾類 : 表示向咖啡中加一份牛奶
 *
 * @author 七夜雪
 * @create 2018-11-23 14:44
 */
public class MilkDecorator implements ICoffee {
    private String desc;
    private int price;

    public MilkDecorator(ICoffee coffee) {
        this.desc = coffee.getDesc() + " 加一份牛奶";
        // 表示每加一份牛奶, 價格增加3元
        this.price = coffee.getPrice() + 3;
    }

    @Override
    public void showDesc() {
        System.out.println(desc + "  價格為:" + price);
    }

    @Override
    public int getPrice() {
        return price;
    }

    @Override
    public String getDesc() {
        return desc;
    }
}

糖包裝類:

/**
 * 糖裝飾類 : 表示向咖啡中加一份糖
 *
 * @author 七夜雪
 * @create 2018-11-23 14:44
 */
public class SugarDecorator implements ICoffee {
    private String desc;
    private int price;

    public SugarDecorator(ICoffee coffee) {
        this.desc = coffee.getDesc() + " 加一份糖";
        // 表示每加一份牛奶, 價格增加2元
        this.price = coffee.getPrice() + 2;
    }

    @Override
    public void showDesc() {
        System.out.println(desc + "  價格為:" + price);
    }

    @Override
    public int getPrice() {
        return price;
    }

    @Override
    public String getDesc() {
        return desc;
    }
}

測試程式碼:

    public static void main(String[] args) {
        ICoffee coffee = new Coffee();
        coffee = new MilkDecorator(coffee);
        coffee = new SugarDecorator(coffee);
        coffee = new SugarDecorator(coffee);
        coffee.showDesc();
    }

測試結果:

一杯咖啡 加一份牛奶 加一份糖 加一份糖  價格為:27