在日常開發(fā)工作中,適當(dāng)?shù)氖褂靡恍┰O(shè)計(jì)模式,可以讓代碼擴(kuò)展性更強(qiáng),能更好地?fù)肀ё兓?,讓代碼更加優(yōu)雅。本文主要介紹設(shè)計(jì)模式中的裝飾模式,并附上測試示例 Demo 供大家參考。

  • 定義

  裝飾模式(Decorator Pattern)允許向一個(gè)現(xiàn)有的對象添加新的功能,同時(shí)又不改變其結(jié)構(gòu)。這種類型的設(shè)計(jì)模式屬于結(jié)構(gòu)型模式,它是作為現(xiàn)有的類的一個(gè)包裝。

  • 個(gè)人理解

  裝飾模式可以在運(yùn)行時(shí),在不修改原有代碼的前提下,動(dòng)態(tài)地為對象添加或移除指定的業(yè)務(wù)邏輯,比起繼承,采用裝飾模式讓代碼更據(jù)擴(kuò)展性,更為靈活,避免了繼承導(dǎo)致的代碼耦合。

  裝飾模式的設(shè)計(jì)理念是:對修改關(guān)閉,對擴(kuò)展開放;面對接口編程。

  • 示例介紹

  個(gè)人有時(shí)間會(huì)自己煮湯(這不是重點(diǎn)哈,只是剛好有這么一個(gè)場景適合采用裝飾模式,因此也就拿來做例子了),在煮湯的過程中,我們需要添加不同的食材,就拿涼瓜排骨湯來說吧,需要的食材有排骨、涼瓜、大豆、食用鹽、水等,當(dāng)然根據(jù)不同人的不同喜好,可以添加其他的食材。以上說到的這些食材都是制作“涼瓜排骨湯”所必須的,沒有它們的點(diǎn)綴,湯喝起來也就不是那個(gè)味道了,這里的點(diǎn)綴我們可以理解為裝飾,是食材裝飾了“涼瓜排骨湯”,也就是說食材是裝飾者,而“涼瓜排骨湯”是被裝飾的對象。UML 圖如下:

電腦培訓(xùn),計(jì)算機(jī)培訓(xùn),平面設(shè)計(jì)培訓(xùn),網(wǎng)頁設(shè)計(jì)培訓(xùn),美工培訓(xùn),Web培訓(xùn),Web前端開發(fā)培訓(xùn)

 

   從上面的 UML 圖可以看出,菜式類 Dish 和 食材抽象類 AbSeasoning 都需要實(shí)現(xiàn)食材接口 IMaterial 。菜式類 Dish 定義了一個(gè)屬性 name ,用于存儲(chǔ)菜式名稱,食材抽象類 AbSeasoning定義了一個(gè)食材引用 material 、食材名稱 name 和食材分量 weight ,分別用于存儲(chǔ)食材引用、食材名稱和食材分量。食材類 Seasoning 則需要繼承食材抽象類 AbSeasoning ,菜式類 Dish 和食材類 Seasoning 都需要實(shí)現(xiàn)各自獲取食材的方法 getStuff。在運(yùn)行的過程中,只需要把菜式賦給食材的食材引用即可,如果后續(xù)還需要添加其他的食材,可以把最后一次添加的食材賦給新食材的食材引用即可達(dá)到動(dòng)態(tài)添加的效果。

  •  示例代碼

   IMaterial 食材接口類(裝飾者接口)

package decorator;public interface IMaterial {    public String getStuff();
}

  Dish 菜式類(被裝飾對象)

電腦培訓(xùn),計(jì)算機(jī)培訓(xùn),平面設(shè)計(jì)培訓(xùn),網(wǎng)頁設(shè)計(jì)培訓(xùn),美工培訓(xùn),Web培訓(xùn),Web前端開發(fā)培訓(xùn)

package decorator;public class Dish implements IMaterial {    private String name;

    @Override    public String getStuff() {        return this.getName();
    }    public String getName() {        return name;
    }    public void setName(String name) {        this.name = name;
    }
}

電腦培訓(xùn),計(jì)算機(jī)培訓(xùn),平面設(shè)計(jì)培訓(xùn),網(wǎng)頁設(shè)計(jì)培訓(xùn),美工培訓(xùn),Web培訓(xùn),Web前端開發(fā)培訓(xùn)

  AbSeasoning 食材抽象類(裝飾者抽象類)

電腦培訓(xùn),計(jì)算機(jī)培訓(xùn),平面設(shè)計(jì)培訓(xùn),網(wǎng)頁設(shè)計(jì)培訓(xùn),美工培訓(xùn),Web培訓(xùn),Web前端開發(fā)培訓(xùn)

package decorator;public abstract class AbSeasoning implements IMaterial {    private IMaterial material;    private String name;    private String weight;    public IMaterial getMaterial() {        return material;
    }    public void setMaterial(IMaterial material) {        this.material = material;
    }    public String getName() {        return name;
    }    public void setName(String name) {        this.name = name;
    }    public String getWeight() {        return weight;
    }    public void setWeight(String weight) {        this.weight = weight;
    }

}

電腦培訓(xùn),計(jì)算機(jī)培訓(xùn),平面設(shè)計(jì)培訓(xùn),網(wǎng)頁設(shè)計(jì)培訓(xùn),美工培訓(xùn),Web培訓(xùn),Web前端開發(fā)培訓(xùn)

  Seasoning 食材類(裝飾者)

電腦培訓(xùn),計(jì)算機(jī)培訓(xùn),平面設(shè)計(jì)培訓(xùn),網(wǎng)頁設(shè)計(jì)培訓(xùn),美工培訓(xùn),Web培訓(xùn),Web前端開發(fā)培訓(xùn)

package decorator;public class Seasoning extends AbSeasoning {

    @Override    public String getStuff() {        return this.getMaterial().getStuff() + "\n" + this.getName() + ":" + this.getWeight();
    }

}

電腦培訓(xùn),計(jì)算機(jī)培訓(xùn),平面設(shè)計(jì)培訓(xùn),網(wǎng)頁設(shè)計(jì)培訓(xùn),美工培訓(xùn),Web培訓(xùn),Web前端開發(fā)培訓(xùn)

  TestMain 測試類

電腦培訓(xùn),計(jì)算機(jī)培訓(xùn),平面設(shè)計(jì)培訓(xùn),網(wǎng)頁設(shè)計(jì)培訓(xùn),美工培訓(xùn),Web培訓(xùn),Web前端開發(fā)培訓(xùn)

package test;import decorator.AbSeasoning;import decorator.Dish;import decorator.Seasoning;public class TestMain {    public static void main(String[] args) {
        Dish dish = new Dish();
        dish.setName("涼瓜排骨湯");

        AbSeasoning spareribs = new Seasoning();
        spareribs.setName("排骨");
        spareribs.setWeight("500g");
        spareribs.setMaterial(dish);

        AbSeasoning bitterGourd = new Seasoning();
        bitterGourd.setName("涼瓜");
        bitterGourd.setWeight("200g");
        bitterGourd.setMaterial(spareribs);

        AbSeasoning soybean = new Seasoning();
        soybean.setName("大豆");
        soybean.setWeight("50g");
        soybean.setMaterial(bitterGourd);

        AbSeasoning salt = new Seasoning();
        salt.setName("食用鹽");
        salt.setWeight("5g");
        salt.setMaterial(soybean);

        AbSeasoning water = new Seasoning();
        water.setName("水");
        water.setWeight("500ml");
        water.setMaterial(salt);

        System.out.println(water.getStuff());
    }

}

電腦培訓(xùn),計(jì)算機(jī)培訓(xùn),平面設(shè)計(jì)培訓(xùn),網(wǎng)頁設(shè)計(jì)培訓(xùn),美工培訓(xùn),Web培訓(xùn),Web前端開發(fā)培訓(xùn)

  測試結(jié)果

  電腦培訓(xùn),計(jì)算機(jī)培訓(xùn),平面設(shè)計(jì)培訓(xùn),網(wǎng)頁設(shè)計(jì)培訓(xùn),美工培訓(xùn),Web培訓(xùn),Web前端開發(fā)培訓(xùn)

 

 歡迎轉(zhuǎn)載,轉(zhuǎn)載必須標(biāo)明出處 

http://www.cnblogs.com/rexfang/p/6748313.html