裝飾模式能夠在不改變一個對象自己功能的基礎上給對象增長額外的新行爲,好比把房子裝修就是一個很典型的場景。java
裝飾模式是一種用於替代繼承的技術,它經過一種無須定義子類的方式來給對象動態增長職責,使用對象之間的關聯關係取代類之間的繼承關係。在裝飾模式中引入了裝飾類,在裝飾類中既能夠調用待裝飾的原有類的方法,還能夠增長新的方法,以擴充原有類的功能。編程
定義以下:ide
裝飾模式(Decorator Pattern):動態地給一個對象增長一些額外的職責,就增長對象功能來講,裝飾模式比生成子類實現更爲靈活。裝飾模式是一種對象結構型模式。性能
結構如圖:this
角色說明:spa
Component(抽象構件)
:它是具體構件和抽象裝飾類的都要繼承的接口(也能夠是父類,建議接口,面向接口編程
),聲明瞭在具體構件中實現的業務方法,它的引入可使客戶端以一致的方式處理未被裝飾的對象以及裝飾以後的對象,實現客戶端的透明操做。ConcreteComponent(具體構件)
:它是抽象構件類的子類,用於定義具體的構件對象,實現了在抽象構件中聲明的方法,裝飾器能夠給它增長額外的職責(方法)。Decorator(抽象裝飾類)
:它也是抽象構件類的子類,用於給具體構件增長職責,可是具體職責在其子類中實現。它維護一個指向抽象構件對象的引用,經過該引用能夠調用裝飾以前構件對象的方法,並經過其子類擴展該方法,以達到裝飾的目的。ConcreteDecorator(具體裝飾類)
:它是抽象裝飾類的子類,負責向構件添加新的職責。每個具體裝飾類都定義了一些新的行爲,它能夠調用在抽象裝飾類中定義的方法,並能夠增長新的方法用以擴充對象的行爲。因爲具體構件類和裝飾類都實現了相同的抽象構件接口,所以裝飾模式以對客戶透明的方式動態地給一個對象附加上更多的責任,換言之,客戶端並不會以爲對象在裝飾前和裝飾後有什麼不一樣。裝飾模式能夠在不須要創造更多子類的狀況下,將對象的功能加以擴展。.net
咱們如今能夠畫圓,可是須要自定義線條的粗細和線條的風格,怎麼經過裝飾器來實現這一個功能呢?設計
先來看一下代碼:調試
Shape:
code
// 形狀的接口
public interface Shape {
// 畫圖
void draw();
}
複製代碼
Circle:
// 圓形
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("畫圓");
}
}
複製代碼
ShapeDecorator:
// 抽象類形狀裝飾器
public abstract class ShapeDecorator implements Shape {
protected Shape decoratedShape;
public ShapeDecorator(Shape decoratedShape) {
super();
this.decoratedShape = decoratedShape;
}
}
複製代碼
LineStyleDecorator:
//自定義線條裝飾器
public class LineStyleDecorator extends ShapeDecorator {
protected LineStyle style;
public LineStyleDecorator(Shape decoratedShape, LineStyle style) {
super(decoratedShape);
this.style = style;
}
@Override
public void draw() {
decoratedShape.draw();
System.out.println("線條風格: " + style);
}
}
複製代碼
LineThinknessDecorator:
// 自定義線條粗細裝飾器
public class LineThinknessDecorator extends ShapeDecorator {
// 厚度
protected double thickness;
public LineThinknessDecorator(Shape decoratedShape, double thickness) {
super(decoratedShape);
this.thickness = thickness;
}
@Override
public void draw() {
decoratedShape.draw();
System.out.println("線條粗細:" + thickness);
}
}
複製代碼
LineStyle
:
// 線條風格
public enum LineStyle {
SOLID, // 實心
DASH, // 長劃
DOT, // 點
DOUBLE_DASH, // 雙線
}
複製代碼
client:
public class Client {
public static void main(String[] args) {
Shape circle = new Circle();
circle.draw();
System.out.println();
// 經過兩個裝飾類,定義了線條的粗細以及線條的風格
Shape circle1 = new LineStyleDecorator(
new LineThinknessDecorator(new Circle(), 2.0d),
LineStyle.DASH);
circle1.draw();
}
}
複製代碼
結果打印:
畫圓
畫圓 線條粗細:2.0 線條風格: DASH
**說明:**抽象裝飾器ShapeDecorator和具體的構件Circle都實現了抽象構件Shape,ShapeDecorator維護了一個Shape引用,經過該引用指向裝飾前的構件對象,並經過子類LineStyleDecorator和LineThinknessDecorator來擴展對象行爲。
優點:
劣勢: