設計模式之裝飾器模式
阿新 • • 發佈:2018-12-10
介紹
概念:向一個現有的物件新增新的功能,同時又不改變其結構。 舉例:現在有一個圓圈,在不改變它的前提,想要把它變成紅色,那麼通過對圓圈進行裝飾(套一層紅色的皮)就能購實現。
裝飾器模式
實現方式:通過引用和繼承來重新父類方法實現。
程式碼實現: Shape.java,幾何圖形介面。
/**
* 幾何圖形,擁有最基本的方法show,用於向外界描述自己
*/
public interface Shape {
/**
* 用於向外界描述自己
*/
void show();
}
Circle.java,圓形實現了幾何圖形介面。
public class Circle implements Shape {
@Override
public void show() {
System.out.println("我是一個圓形");
}
}
ShapeDecorator.java,幾何圖形介面卡,是一個抽象類,主要為了方便擴充套件多個介面卡。
public abstract class ShapeDecorator implements Shape {
private Shape shape;
public ShapeDecorator(Shape shape) {
this .shape = shape;
}
@Override
public void show() {
shape.show();
}
}
RedShapeDecorator.java,紅色幾何圖形介面卡,給幾何圖形塗上紅色,這樣在幾何圖形在向外界描述自己的時候就能帶上“顏色”了。
/**
* 紅色形狀裝飾器,繼承了抽象類ShapeDecorator
* 新增了“紅色”描述
*/
public class RedShapeDecorator extends ShapeDecorator {
public RedShapeDecorator (Shape shape) {
super(shape);
}
@Override
public void show() {
super.show();
color();
}
/**
* 對外不暴露改方法,對於外部呼叫來說,根本不知道該方法的存在
*/
private void color() {
System.out.println("紅色");
}
}
DecoratorPatternDemo.java,介面卡模式執行類
public class DecoratorPatternDemo {
public static void main(String[] args) {
Shape circle = new Circle();
Shape redCircle = new RedShapeDecorator(circle);
System.out.println("-------------------------------");
circle.show();
System.out.println("-------------------------------");
redCircle.show();
}
}
輸出如下:
-------------------------------
我是一個圓形
-------------------------------
我是一個圓形
紅色
Process finished with exit code 0
如上所述,沒有對Circle.java做任何改動卻在呼叫show方法時,沒經過裝飾的還是原本普通的描述,而經過紅色裝飾器之後在描述中帶上了顏色。
還可以增加其他的介面卡,裝飾原本的圓圈。 EllipseDecorator.java,用於增加“橢圓”的描述
public class EllipseDecorator extends ShapeDecorator {
public EllipseDecorator(Shape shape) {
super(shape);
}
@Override
public void show() {
super.show();
ext();
}
private void ext() {
System.out.println("橢圓");
}
}
於是DecoratorPatternDemo可以改成如下:
public class DecoratorPatternDemo {
public static void main(String[] args) {
Shape circle = new Circle();
Shape redCircle = new RedShapeDecorator(circle);
Shape ellipse = new EllipseDecorator(circle);
Shape redEllipse = new EllipseDecorator(redCircle);
System.out.println("-------------------------------");
circle.show();
System.out.println("-------------------------------");
redCircle.show();
System.out.println("-------------------------------");
ellipse.show();
System.out.println("-------------------------------");
redEllipse.show();
System.out.println("-------------------------------");
}
}
輸出如下:
-------------------------------
我是一個圓形
-------------------------------
我是一個圓形
紅色
-------------------------------
我是一個圓形
橢圓
-------------------------------
我是一個圓形
紅色
橢圓
-------------------------------
Process finished with exit code 0
裝飾器模式的優缺點
- 優點 不入侵現有物件的程式碼;因為是使用介面的方式所以介面卡與被介面卡耦合較小;在執行時確定裝飾成什麼樣子(編譯看左邊執行看右邊)。
- 缺點 多層裝飾比較複雜。
使用場景
如果使用繼承:還是以幾何圖形舉例,但是現在是一個圓圈和一個矩形,我分別想給它們塗上顏色,就得實現一個紅色圓圈子類、一個紅色矩形子類,需要建立兩個類;而通過裝飾者模式,只需要增加一個顏色裝飾者就可以了。 也就是說,當會產生大量的子類,使得系統變得臃腫時使用裝飾者模式更合理。