Java設計模式-裝飾模式:《穿越火線》RMB 玩家的快樂~

原文地址:xeblog.cn/articles/15git

引言

《穿越火線》這一遊戲風靡一時,做爲手遊版的NC粉, 想當年也是雄姿英發啊。好漢不提當年勇,如今幾乎不怎麼玩了。。。別問我爲何,問就是沒錢,哈哈哈哈嗝~
如今的遊戲,只要一充錢,各類屬性加強,各類坑爹特權,實力再高也玩不贏RMB玩家啊,在小康路上已經迷了路的我,不由得說上一句:實力不容許。github

裝飾模式的定義

裝飾模式是在沒必要改變原類文件和使用繼承的狀況下,動態地擴展一個對象的功能。它是經過建立一個包裝對象,也就是裝飾來包裹真實的對象。設計模式

對於網癮少年來講,就是遊戲裏的皮膚,讓遊戲裏的角色、武器啥的變得好看的。bash

裝飾模式的通用類圖:ide

  • Component
    Component 是一個接口或者抽象類,它定義一個最核心的對象,是一個最原始的業務場景。
  • ConcreteComponent
    ConcreteComponent 是最核心、最原始的業務邏輯實現,要裝飾的就是它。
  • Decorator
    顧名思義,它是一個專門作裝飾的類,說白了,就是一個裝修工。它通常是一個抽象類,也須要實現最原始的業務邏輯,不一樣於其它實現類的是,它須要定義一個 private  變量指向 Component 對象,通常經過構造的方式傳入 Component 對象。
  • ConcreteComponentA、ConcreteComponentB
    它們是兩個具體的裝飾類,經過這兩個裝飾類來加強或減弱原始的業務邏輯,再說白了,就是遊戲裏的兩個皮膚,給原先角色或武器裝飾上後,別提多NB了。

裝飾模式的實現

首先定義一個具體的業務遊戲場景,CF遊戲中的最基本的操做:登入、開火、丟手雷函數

UML類圖this

抽象構件:CFGameServicespa

/** * cf遊戲服務接口 * * @author anlingyi */
public interface CFGameService {

    /** * 登入 * @param username * @param password */
    void login(String username, String password);

    /** * 開槍射擊 */
    void fire();

    /** * 丟手雷 */
    void grenade();
}
複製代碼

具體構件:CFerServiceImpl設計

/** * cf遊戲者實現類 * * @author anlingyi */
public class CFerServiceImpl implements CFGameService {

    @Override
    public void login(String username, String password) {
        System.out.println(username + ", 登入遊戲成功!");
    }

    @Override
    public void fire() {
        System.out.println("開火。。。");
    }

    @Override
    public void grenade() {
        System.out.println("丟雷。。。");
    }
}
複製代碼

抽象裝飾者:CFGameDecorator3d

/** * cf遊戲裝飾類 */
public abstract class CFGameDecorator implements CFGameService {

    /** * 被裝飾的對象 */
    private CFGameService cfGameService;

    /** * 經過構造函數傳遞被修飾對象 * @param cfGameService */
    public CFGameDecorator(CFGameService cfGameService) {
        this.cfGameService = cfGameService;
    }
    
    @Override
    public void login(String username, String password) {
        this.cfGameService.login(username, password);
    }

    @Override
    public void fire() {
        this.cfGameService.fire();
    }

    @Override
    public void grenade() {
        this.cfGameService.grenade();
    }
}
複製代碼

具體的裝飾類:ArmsDecorator、EffectDecorator

/** * 武器裝飾類 * * @author anlingyi */
public class ArmsDecorator extends CFGameDecorator {

    public ArmsDecorator(CFGameService cfGameService) {
        super(cfGameService);
    }

    @Override
    public void fire() {
        // 加強武器
        this.useFirearms();
        super.fire();
    }

    @Override
    public void grenade() {
        // 加強手雷
        this.useGrenade();
        super.grenade();
    }

    /** * 加強武器的方法 */
    private void useFirearms() {
        System.out.println("裝備:AK-47-火麒麟");
    }

    /** * 加強手雷的方法 */
    private void useGrenade() {
        System.out.println("裝備:高爆手雷");
    }
}
複製代碼
/** * 效果裝飾類 * * @author anlingyi */
public class EffectDecorator extends CFGameDecorator {

    public EffectDecorator(CFGameService cfGameService) {
        super(cfGameService);
    }

    @Override
    public void login(String username, String password) {
        // vip會員
        System.out.println("尊貴的vvvvvip會員");
        super.login(username, password);
    }

    @Override
    public void fire() {
        super.fire();
        // 增長擊殺音效
        this.killSound();
    }

    @Override
    public void grenade() {
        super.grenade();
        // 增長丟手雷音效
        this.grenadeSound();
    }

    /** * 增長擊殺音效 */
    private void killSound() {
        System.out.println("嘿帥!");
    }

    /** * 增長丟手雷的音效 */
    private void grenadeSound() {
        System.out.println("發呀的轟!");
    }
}
複製代碼

開始遊戲

平民玩家進入了遊戲。。。

/** * cf客戶端 * * @author anlingyi */
public class CFClient {

    public static void main(String[] args) {
        CFGameService cf = new CFerServiceImpl();
        cf.login("小毅", "123456");
        cf.fire();
        cf.grenade();
    }
}
複製代碼

遊戲效果:

小毅, 登入遊戲成功!
開火。。。
丟雷。。。
複製代碼

毫無樂趣可言。

「這個問題充錢就能解決」 —— 老子(子讀一聲)

RMB玩家進入了遊戲。。。

/** * cf客戶端 * * @author anlingyi */
public class CFClient {

    public static void main(String[] args) {
        CFGameService cf = new CFerServiceImpl();
        // 充錢充錢(修飾武器)
        cf = new ArmsDecorator(cf);
        cf.login("小毅", "123456");
        cf.fire();
        cf.grenade();
    }
}
複製代碼

遊戲效果:

小毅, 登入遊戲成功!
裝備:AK-47-火麒麟
開火。。。
裝備:高爆手雷
丟雷。。。
複製代碼

瞬間NB多了,連隔壁小孩都饞哭了。。。哈哈哈~

繼續充

/** * cf客戶端 * * @author anlingyi */
public class CFClient {

    public static void main(String[] args) {
        CFGameService cf = new CFerServiceImpl();
        // 充錢充錢(修飾武器)
        cf = new ArmsDecorator(cf);
        // 再充(修飾效果)
        cf = new EffectDecorator(cf);
        cf.login("小毅", "123456");
        cf.fire();
        cf.grenade();
    }
}
複製代碼

遊戲效果:

尊貴的vvvvvip會員
小毅, 登入遊戲成功!
裝備:AK-47-火麒麟
開火。。。
嘿帥!
裝備:高爆手雷
丟雷。。。
發呀的轟!
複製代碼

越充越NB,越NB越好玩,越好玩越充。。。今後,在貧困的道路上越走越遠。

裝飾模式的優缺點

優勢

  • 裝飾類和被裝飾類能夠獨立發展,而不會相互耦合。Component 類不須要知道 Decorator 類的存在,Decorator 類是從外部來擴展 Component 類的功能,而 Decorator 類也不用知道具體的構件。
  • 裝飾模式是繼承關係的一個替代方案,裝飾對象和真實對象具備相同的接口。
  • 裝飾模式能夠動態地擴展一個實現類的功能,不用修改原有對象的結構就能夠加強或減弱原有的功能。

缺點

  • 過分的使用裝飾模式會使程序變得更加複雜。

資源

參考

  • 《設計模式之禪》
相關文章
相關標籤/搜索