1. 程式人生 > >Java設計模式-裝飾者模式

Java設計模式-裝飾者模式

定義:

裝飾者是在不改變物件的情況下動態給物件新增屬性和行為,將責任動態的附加在物件上。 與繼承有類似功能即擴充套件功能。

裝飾者模式與繼承的區別:

**繼承:**在子類擴充套件功能的時候是靜態的,並且是已知需要擴充套件的功能,是在編譯時實現的。

**裝飾者模式:**比繼承更靈活,可以動態的擴充套件功能,可以在編譯時實現。符合開閉原則:類對擴充套件開發,對修改關閉。 這也是裝飾者模式的優點。

缺點:

會出現很多的小類,難管理。

角色:
  • 裝飾者和被裝飾者的父類:一個抽象的介面或抽象類,定義基本行為。 裝飾者也繼承(實現)這個類不是為了繼承固定的行為,而是為了讓裝飾者和被裝飾者屬於同一型別從而在裝飾的時候被裝飾者不會被修改。 也因此,裝飾類可以替換被裝飾類。
  • 被裝飾者:具體被裝飾的物件
  • 抽象裝飾者(Decorator):一個介面或抽象類,從外類裝飾被裝飾者,被裝飾者不需要知道裝飾者的存在。
  • 具體裝飾者:繼承(實現)被裝飾者,定義需要附加在被裝飾者的責任,即擴充套件被裝飾者。
程式示例:

對於遊戲裝備的定價系統,一套遊戲裝備可能會附加武器、頭飾等其他的裝飾品一起售出,並且搭配不同的飾品售價不一,並且搭配的飾品是動態的。因此可以使用裝飾者模式,遊戲裝備是被裝飾者,武器、頭飾是裝飾者。

Java中的IO就是典型的裝飾者模式。

/**
 * 被裝飾者和裝飾者的父類
 */
public abstract class GameComponent {
    String desc = "遊戲裝備";
    public String getDesc() {
        return desc;
    }
    public abstract int getPrice();
}
/**
 * 具體被裝飾者
 */
public class WangzheCon extends GameComponent {
    @Override
    public String getDesc() {
        return "王者榮耀的裝備:";
    }
    @Override
    public int getPrice() {
        return 99;
    }
}
/**
 * 抽象裝飾者
 */
public abstract class MyDecorator {
    public abstract String getDecs();
}
public class ClothDecora extends GameComponent {

    GameComponent gameComponent;

    public ClothDecora(GameComponent gameComponent) {
        this.gameComponent = gameComponent;
    }

    @Override
    public String getDesc() {
        return "增加一種頭飾:";
    }

    @Override
    public int getPrice() {
        return 20+gameComponent.getPrice();
    }
}
/**
 * 具體裝飾者--武器裝飾者
 * 繼承同一子類是為了與被裝飾者關聯,保持被裝飾者的型別
 */

public class WeaponDecora extends GameComponent{

    //需要持有被裝飾者
    GameComponent gameComponent ;

    public WeaponDecora(GameComponent gameComponent) {
        this.gameComponent = gameComponent;
    }

    @Override
    public String getDesc() {
        return "新增一種武器:";
    }

    @Override
    public int getPrice() {
        return 30+gameComponent.getPrice();
    }
}

測試類:

 public static void main(String[] agrs){
        WangzheCon wangzheCon= new WangzheCon();

        System.out.println("描述:"+wangzheCon.getDesc()+wangzheCon.getPrice());

        WeaponDecora weaponDecora = new WeaponDecora(wangzheCon);
        System.out.println("武器裝飾描述:"+weaponDecora.getDesc()+weaponDecora.getPrice());

        ClothDecora clothDecora = new ClothDecora(wangzheCon);

        System.out.println("頭飾裝飾描述:"+clothDecora.getDesc()+clothDecora.getPrice());
        //或者
        WangzheCon wangzheCon1 = new WangzheCon();
        WeaponDecora weaponDecora1 = new WeaponDecora(new ClothDecora(wangzheCon1));

        System.out.println("裝備描述:"+weaponDecora1.getDesc()+weaponDecora1.getPrice());

    }

程式碼示例:https://github.com/MarinaTsang/demo/tree/master/decorator