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("打開地圖尋找美食"); } @Overridepublic 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、裝飾者模式的設計原則為:
對擴展開放、對修改關閉,這句話體現在我如果想擴展被裝飾者類的行為,無須修改裝飾者抽象類,只需繼承裝飾者抽象類,實現額外的一些裝飾或者叫行為即可對被裝飾者進行包裝。
java設計模式之 裝飾器模式