1. 程式人生 > >java設計模式之 裝飾器模式

java設計模式之 裝飾器模式

食物 implement super map 結束 同時 ring 接口 包裝

適AT

java設計模式之 裝飾器模式

裝飾器模式

裝飾器模式(Decorator Pattern)允許向一個現有的對象添加新的功能,同時又不改變其結構。

這種類型的設計模式屬於結構型模式,它是作為現有的類的一個包裝。

這種模式創建了一個裝飾類,用來包裝原有的類,並在保持類方法簽名完整性的前提下,動態給一個對象添提供了額外的功能。

我們通過下面的實例來演示裝飾器模式的用法。模擬一個人從想吃飯、找飯店、享受美食、結束吃飯的過程

代碼展示:

首先創建一個被修飾的接口 Eat

package decorator;
//吃飯接口
public interface Eat {
    //吃飯方法
    void eat();
}

創建一個被修飾者並且有自己的狀態

技術分享
package decorator;

public class Person implements Eat {

    @Override
    public void eat() {
        System.out.println("======我餓了======");
    }
}
技術分享

創建一個修飾者的抽象類

技術分享
package decorator;

public abstract class LikeEat implements Eat {
    private Eat eat;
    
    public LikeEat(Eat eat) {
        this.eat=eat;
    }
    
    @Override
    public void eat() {
        eat.eat();
    }

}
技術分享

創建五個修飾類的擴展類(即--擴展修飾),分別擁有自己特定的狀態,豐富被修飾的類

技術分享
public class FindInMap extends LikeEat {
    public FindInMap(Eat eat) {
        super(eat);
    }

    public void userMap(){
        System.out.println("打開地圖尋找美食");
    }
    
    @Override
    public void eat() {
        super.eat();
        userMap();
    }
}

public class GotoRestaurant extends LikeEat {

    public GotoRestaurant(Eat eat) {
        super(eat);
    }
    public void onWay(){
        System.out.println("去往飯店的路上");
    }
    
    @Override
    public void eat() {
        super.eat();
        onWay();
    }
    
}

public class InRestaurant extends LikeEat {
    public InRestaurant(Eat eat) {
        super(eat);
    }
    
    public void selectFoot(){
        System.out.println("到達飯店選擇食物");
    }
    
    @Override
    public void eat() {
        super.eat();
        selectFoot();
    }

}

public class EatFoot extends LikeEat {
    public EatFoot(Eat eat) {
        super(eat);
    }
    
    public void eating(){
        System.out.println("享用美食中");
    }
    @Override
    public void eat() {
        super.eat();
        eating();
    }

}

public class endEat extends LikeEat {

    public endEat(Eat eat) {
        super(eat);
    }
    
    public void afterEat(){
        System.out.println("=====美食結束=====");
    }
    
    @Override
    public void eat() {
        super.eat();
        afterEat();
    }
}
技術分享

創建測試類,測試修飾效果

技術分享
public class EatTest {
    public static void main(String[] args) {
        Eat person = new Person();
        likeEat likeEat = new endEat(
                           new EatFoot(
                           new InRestaurant(
                           new GotoRestaurant(
                           new FindInMap(person))))) ;
        likeEat.eat();
    }
}
技術分享

運行結果:

技術分享

總結:
A、LikeEat抽象類中,持有Eat接口,方法全部委托給該接口調用,目的是交給該接口的實現類即子類進行調用。
B、LikeEat抽象類的子類(具體裝飾者),裏面都有一個構造方法調用super(eat),這一句就體現了抽象類依賴於子類實現即抽象依賴於實現的原則。因為構造裏面參數都是Eat接口,只要是該Eat的實現類都可以傳遞進去,即表現出

          likeEat likeEat = new endEat(
                    new EatFoot(
                      new InRestaurant(
                        new GotoRestaurant(
                          new FindInMap(person)))))

這種結構的樣子。所以當調用likeEat.eat()的時候,又因為每個具體裝飾者類中,都先調用super.eat();方法,而該super已經由構造傳遞並指向了具體的某一個裝飾者類(這個可以根據需要調換順序),那麽調用的即為裝飾類的方法,然後才調用自身的裝飾方法,即表現出一種裝飾、鏈式的類似於過濾的行為。

C、具體被裝飾者,可以定義初始的狀態或者初始的自己的裝飾,後面的裝飾行為都在此基礎上一步一步進行點綴、裝飾。
D、裝飾者模式的設計原則為:

  對擴展開放、對修改關閉,這句話體現在我如果想擴展被裝飾者類的行為,無須修改裝飾者抽象類,只需繼承裝飾者抽象類,實現額外的一些裝飾或者叫行為即可對被裝飾者進行包裝。

轉自:http://www.cnblogs.com/kuoAT/p/6951706.html

java設計模式之 裝飾器模式