Java設(shè)計(jì)模式-裝飾模式:《穿越火線(xiàn)》RMB 玩家的快樂(lè)~

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

引言

《穿越火線(xiàn)》這一游戲風(fēng)靡一時(shí),作為手游版的NC粉, 想當(dāng)年也是雄姿英發(fā)啊。好漢不提當(dāng)年勇,現(xiàn)在幾乎不怎么玩了。。。別問(wèn)我為什么,問(wèn)就是沒(méi)錢(qián),哈哈哈哈嗝~
現(xiàn)在的游戲,只要一充錢(qián),各種屬性增強(qiáng),各種坑爹特權(quán),實(shí)力再高也玩不贏RMB玩家啊,在小康路上已經(jīng)迷了路的我,不禁得說(shuō)上一句:實(shí)力不允許。

image

裝飾模式的定義

裝飾模式是在不必改變?cè)?lèi)文件和使用繼承的情況下,動(dòng)態(tài)地?cái)U(kuò)展一個(gè)對(duì)象的功能。它是通過(guò)創(chuàng)建一個(gè)包裝對(duì)象,也就是裝飾來(lái)包裹真實(shí)的對(duì)象。

對(duì)于網(wǎng)癮少年來(lái)說(shuō),就是游戲里的皮膚,讓游戲里的角色、武器啥的變得好看的。

裝飾模式的通用類(lèi)圖:

image
  • Component
    Component 是一個(gè)接口或者抽象類(lèi),它定義一個(gè)最核心的對(duì)象,是一個(gè)最原始的業(yè)務(wù)場(chǎng)景。
  • ConcreteComponent
    ConcreteComponent 是最核心、最原始的業(yè)務(wù)邏輯實(shí)現(xiàn),要裝飾的就是它。
  • Decorator
    顧名思義,它是一個(gè)專(zhuān)門(mén)做裝飾的類(lèi),說(shuō)白了,就是一個(gè)裝修工。它一般是一個(gè)抽象類(lèi),也需要實(shí)現(xiàn)最原始的業(yè)務(wù)邏輯,不同于其它實(shí)現(xiàn)類(lèi)的是,它需要定義一個(gè) private 變量指向 Component 對(duì)象,一般通過(guò)構(gòu)造的方式傳入 Component 對(duì)象。
  • ConcreteComponentA、ConcreteComponentB
    它們是兩個(gè)具體的裝飾類(lèi),通過(guò)這兩個(gè)裝飾類(lèi)來(lái)增強(qiáng)或減弱原始的業(yè)務(wù)邏輯,再說(shuō)白了,就是游戲里的兩個(gè)皮膚,給原先角色或武器裝飾上后,別提多NB了。
image

裝飾模式的實(shí)現(xiàn)

首先定義一個(gè)具體的業(yè)務(wù)游戲場(chǎng)景,CF游戲中的最基本的操作:登入、開(kāi)火、丟手雷

UML類(lèi)圖

image

抽象構(gòu)件:CFGameService

/**
 * cf游戲服務(wù)接口
 *
 * @author anlingyi
 */
public interface CFGameService {

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

    /**
     *  開(kāi)槍射擊
     */
    void fire();

    /**
     * 丟手雷
     */
    void grenade();
}

具體構(gòu)件:CFerServiceImpl

/**
 * cf游戲者實(shí)現(xiàn)類(lèi)
 *
 * @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("開(kāi)火。。。");
    }

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

抽象裝飾者:CFGameDecorator

/**
 * cf游戲裝飾類(lèi)
 */
public abstract class CFGameDecorator implements CFGameService {

    /**
     * 被裝飾的對(duì)象
     */
    private CFGameService cfGameService;

    /**
     * 通過(guò)構(gòu)造函數(shù)傳遞被修飾對(duì)象
     * @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();
    }
}

具體的裝飾類(lèi):ArmsDecorator、EffectDecorator

/**
 * 武器裝飾類(lèi)
 *
 * @author anlingyi
 */
public class ArmsDecorator extends CFGameDecorator {

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

    @Override
    public void fire() {
        // 增強(qiáng)武器
        this.useFirearms();
        super.fire();
    }

    @Override
    public void grenade() {
        // 增強(qiáng)手雷
        this.useGrenade();
        super.grenade();
    }

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

    /**
     * 增強(qiáng)手雷的方法
     */
    private void useGrenade() {
        System.out.println("裝備:高爆手雷");
    }
}
/**
 * 效果裝飾類(lèi)
 *
 * @author anlingyi
 */
public class EffectDecorator extends CFGameDecorator {

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

    @Override
    public void login(String username, String password) {
        // vip會(huì)員
        System.out.println("尊貴的vvvvvip會(huì)員");
        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("發(fā)呀的轟!");
    }
}

開(kāi)始游戲

平民玩家進(jìn)入了游戲。。。

/**
 * cf客戶(hù)端
 *
 * @author anlingyi
 */
public class CFClient {

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

游戲效果:

小毅, 登入游戲成功!
開(kāi)火。。。
丟雷。。。

毫無(wú)樂(lè)趣可言。

image

“這個(gè)問(wèn)題充錢(qián)就能解決” —— 老子(子讀一聲)

RMB玩家進(jìn)入了游戲。。。

/**
 * cf客戶(hù)端
 *
 * @author anlingyi
 */
public class CFClient {

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

游戲效果:

小毅, 登入游戲成功!
裝備:AK-47-火麒麟
開(kāi)火。。。
裝備:高爆手雷
丟雷。。。

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

image

繼續(xù)充

/**
 * cf客戶(hù)端
 *
 * @author anlingyi
 */
public class CFClient {

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

游戲效果:

尊貴的vvvvvip會(huì)員
小毅, 登入游戲成功!
裝備:AK-47-火麒麟
開(kāi)火。。。
嘿帥!
裝備:高爆手雷
丟雷。。。
發(fā)呀的轟!

越充越NB,越NB越好玩,越好玩越充。。。從此,在貧困的道路上越走越遠(yuǎn)。

image

裝飾模式的優(yōu)缺點(diǎn)

優(yōu)點(diǎn)

  • 裝飾類(lèi)和被裝飾類(lèi)可以獨(dú)立發(fā)展,而不會(huì)相互耦合。Component 類(lèi)不需要知道 Decorator 類(lèi)的存在,Decorator 類(lèi)是從外部來(lái)擴(kuò)展 Component 類(lèi)的功能,而 Decorator 類(lèi)也不用知道具體的構(gòu)件。
  • 裝飾模式是繼承關(guān)系的一個(gè)替代方案,裝飾對(duì)象和真實(shí)對(duì)象具有相同的接口。
  • 裝飾模式可以動(dòng)態(tài)地?cái)U(kuò)展一個(gè)實(shí)現(xiàn)類(lèi)的功能,不用修改原有對(duì)象的結(jié)構(gòu)就可以增強(qiáng)或減弱原有的功能。

缺點(diǎn)

  • 過(guò)度的使用裝飾模式會(huì)使程序變得更加復(fù)雜。

資源

參考

  • 《設(shè)計(jì)模式之禪》
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容