要實現裝飾者模式,注意一下幾點內容:
1.裝飾者類要實現真實類同樣的接口
2.裝飾者類內有一個真實對象的引用(可以通過裝飾者類的構造器傳入)
3.裝飾類對象在主類中接受請求,將請求發送給真實的對象(相當於已經將引用傳遞到了裝飾類的真實對象)
4.裝飾者可以在傳入真實對象後,增加一些附加功能(因爲裝飾對象和真實對象都有同樣的方法,裝飾對象可以添加一定操作在調用真實對象的方法,或者先調用真實對象的方法,再添加自己的方法)
5.不用繼承,
先用實例說話,最後再具體裝飾者模式
假設要製造添加甜蜜素和着色劑的饅頭:
1.需要生產一個正常饅頭
2.爲節省成本(不使用玉米麪),使用染色劑加入到正常饅頭中
3.和麪,最後生產出染色饅頭
一..先實現做麪包的接口
IBread接口包括準備材料,和麪,蒸饅頭,加工饅頭(即調用前面三個步驟)
package com.Geeksun.Decoration;
public interface IBread {
public void prepare();
public void kneadFlour();
public void steamed();
public void process();
}
二.製作正常饅頭
package com.Geeksun.Decoration;
public class NormalBread implements IBread {
@Override
public void prepare() {
System.out.println("準備麪粉,水以及發酵粉...");
}
@Override
public void kneadFlour() {
System.out.println("和麪...");
}
@Override
public void steamed() {
System.out.println("蒸饅頭...香噴噴的饅頭出爐了");
}
@Override
public void process() {
prepare();
kneadFlour();
steamed();
}
}
三.定義出製作麪包的抽象類
抽象類實現了IBread這個製作麪包的接口,同時包含IBread接口的實例
對應上述的第2個注意點:裝飾者類內有一個真實對象的引用
package com.Geeksun.Decoration;
public abstract class AbstractBread implements IBread {
protected IBread bread;
public AbstractBread(IBread bread){
this.bread = bread;
}
@Override
public void prepare() {
bread.prepare();
}
@Override
public void kneadFlour() {
bread.kneadFlour();
}
@Override
public void steamed() {
bread.steamed();
}
@Override
public void process() {
prepare();
kneadFlour();
steamed();
}
}
四.生產有着色劑的"玉米饅頭"
繼承AbstarctBread類,所以可以有選擇的覆蓋正常生產饅頭的方法,並添加原有方法原來的信息,同時也可以添加自己的方法
裝飾者模式中這裏最關鍵,
對應上述的第1個注意點:裝飾者類要實現真實類同樣的接口
package com.Geeksun.Decoration;
public class CornDecorator extends AbstractBread {
public CornDecorator(IBread bread) {
super(bread);
}
public void paint(){
System.out.println("添加檸檬黃的着色劑");
}
@Override
public void kneadFlour() {
this.paint();
super.kneadFlour();
}
}
五.生產有甜蜜素的"甜饅頭"
實現與第四部一樣
package com.Geeksun.Decoration;
public class SweetDecorator extends AbstractBread {
public SweetDecorator(IBread bread) {
super(bread);
}
public void paint(){
System.out.println("增加甜味劑");
}
@Override
public void kneadFlour() {
this.paint();
super.kneadFlour();
}
}
六.開始製作添加甜蜜素和着色劑的饅頭
package com.Geeksun.Decoration;
public class Client {
public static void main(String[] args) {
System.out.println("=======開始裝飾饅頭");
IBread normalBread = new NormalBread();
normalBread = new SweetDecorator(normalBread);
normalBread = new CornDecorator(normalBread);
normalBread.process();
System.out.println("=======裝飾饅頭結束");
}
}
七.輸出
=======開始裝飾饅頭
準備麪粉,水以及發酵粉...
添加檸檬黃的着色劑
增加甜味劑
和麪...
蒸饅頭...香噴噴的饅頭出爐了
=======裝飾饅頭結束
裝飾者模式中的4個角色
(1)被裝飾者抽象Component:是一個接口或者抽象類,定義最核心的對象,這個類是裝飾者的基類,例如IBread接口
(2)被裝飾者具體實現ConcreteComponent:這是Component接口或抽象類的實現,例如本例中的NormalBread
(3)裝飾者Decorator:一般是抽象類,實現Component,它裏面必然有一個指向Component的引用,例如本例中AbstractBread
(4)裝飾者實現ConcreteDecorator1和ConcreteDecorator2:用來裝飾最基本的類,如本例中的CornDecorator,