裝飾模式
1.模式動機
一般有兩種方式可以實現給一個類或對象增加行爲:
繼承機制,使用繼承機制是給現有類添加功能的一種有效途徑,通過繼承一個現有類可以使得子類在擁有自身方法的同時還擁有父類的方法。但是這種方法是靜態的,用戶不能控制增加行爲的方式和時機。
關聯機制,即將一個類的對象嵌入另一個對象中,由另一個對象來決定是否調用嵌入對象的行爲以便擴展自己的行爲,我們稱這個嵌入的對象爲裝飾器(Decorator)。
裝飾模式以對客戶透明的方式動態地給一個對象附加上更多的責任,換言之,客戶端並不會覺得對象在裝飾前和裝飾後有什麼不同。裝飾模式可以在不需要創造更多子類的情況下,將對象的功能加以擴展。這就是裝飾模式的模式動機。
2.模式定義
裝飾模式(Decorator Pattern) :動態地給一個對象增加一些額外的職責(Responsibility),就增加對象功能來說,裝飾模式比生成子類實現更爲靈活。其別名也可以稱爲包裝器(Wrapper),與適配器模式的別名相同,但它們適用於不同的場合。根據翻譯的不同,裝飾模式也有人稱之爲“油漆工模式”,它是一種對象結構型模式。
3.模式結構
裝飾模式包含如下角色:
Component: 抽象構件
ConcreteComponent: 具體構件
Decorator: 抽象裝飾類
ConcreteDecorator: 具體裝飾類
4.模式分析
與繼承關係相比,關聯關係的主要優勢在於不會破壞類的封裝性,而且繼承是一種耦合度較大的靜態關係,無法在程序運行時動態擴展。在軟件開發階段,關聯關係雖然不會比繼承關係減少編碼量,但是到了軟件維護階段,由於關聯關係使系統具有較好的鬆耦合性,因此使得系統更加容易維護。當然,關聯關係的缺點是比繼承關係要創建更多的對象。使用裝飾模式來實現擴展比繼承更加靈活,它以對客戶透明的方式動態地給一個對象附加更多的責任。裝飾模式可以在不需要創造更多子類的情況下,將對象的功能加以擴展。
典型的抽象裝飾類代碼:
public class Decorator extends Component
{
private Component component;
public Decorator(Component component)
{
this.component=component;
}
public void operation()
{
component.operation();
}
}
典型的具體裝飾類代碼:
public class ConcreteDecorator extends Decorator
{
public ConcreteDecorator(Component component)
{
super(component);
}
public void operation()
{
super.operation();
addedBehavior();
}
public void addedBehavior()
{
//新增方法
}
}
5.裝飾模式實例與解析
實例一:
變形金剛變形金剛在變形之前是一輛汽車,它可以在陸地上移動。當它變成機器人之後除了能夠在陸地上移動之外,還可以說話;如果需要,它還可以變成飛機,除了在陸地上移動還可以在天空中飛翔。
UML類圖:
代碼實現:
//Transform接口
package priv.qzz.DesignPattern.DecoratorPattern_13;
public interface Transform
{
public void move();
}
//Changer類
package priv.qzz.DesignPattern.DecoratorPattern_13;
public class Changer implements Transform
{
private Transform transform;
public Changer(Transform transform)
{
this.transform=transform;
}
public void move()
{
transform.move();
}
}
//Airplane類
package priv.qzz.DesignPattern.DecoratorPattern_13;
public class Airplane extends Changer
{
public Airplane(Transform transform)
{
super(transform);
System.out.println("變成飛機!");
}
public void fly()
{
System.out.println("在天空飛翔!");
}
}
//Car類
package priv.qzz.DesignPattern.DecoratorPattern_13;
public final class Car implements Transform
{
public Car()
{
System.out.println("變形金剛是一輛車!");
}
public void move()
{
System.out.println("在陸地上移動!");
}
}
//Robot類
package priv.qzz.DesignPattern.DecoratorPattern_13;
public class Robot extends Changer
{
public Robot(Transform transform)
{
super(transform);
System.out.println("變成機器人!");
}
public void say()
{
System.out.println("說話!");
}
}
//Client類(含有main方法)
package priv.qzz.DesignPattern.DecoratorPattern_13;
public class Client
{
public static void main(String args[])
{
Transform camaro;
camaro=new Car();
camaro.move();
System.out.println("-----------------------------");
Airplane bumblebee=new Airplane(camaro);
bumblebee.move();
bumblebee.fly();
}
}
結果:
變形金剛是一輛車!
在陸地上移動!
-----------------------------
變成飛機!
在陸地上移動!
在天空飛翔!
2019.3.23/週六
by 922