Android設計模式之中的一個個樣例讓你徹底明確裝飾者模式(Decorator Pattern)


導讀

這篇文章中我不會使用概念性文字來說明裝飾者模式。由於通常概念性的問題都非常抽象。非常難懂。使得讀者非常難明確究竟為什么要使用這樣的設計模式。我們設計模式的誕生,肯定是前輩們在設計程序的時候遇到了某種困難,為了避免這樣的苦難的發生,從而設計出來的這樣的設計模式,所以這篇文章中我會帶領大家遇見這樣的困難,從而使用設計模式解決這樣的困難,最后大家就會明確什么是設計者模式,什么時候應該使用設計者模式以及怎樣使用設計者模式了

首先我們先來看一下裝飾者模式的UML圖是什么樣子的。圖中各個類的含義不懂沒有關系,以下我會用一個形象的樣例來一一介紹他們,相信大家看完后肯定就明確了
這里寫圖片描寫敘述

假設不用裝飾者設計模式會出現什么問題?

這里我不准備用一些概念性的文字來說明什么是裝飾者模式,我就要用一個實際的樣例來形象的說明什么是裝飾者模式。
比方我們玩網絡游戲。我們都要先創建一個角色對吧,這些角色每一個人創建出來的都不一樣,由於角色肯定能夠依據用戶的審美來個性化打造,但是每一個角色最開始的能力都是一樣的,不會由於一個玩家給他捏了一張特別帥的臉而變得特別的厲害。

那么這個角色肯定是一個接口,這就是UML圖中的Conponent接口

/** * 游戲角色 */
public interface Avatar {
    String describe();
}

非常easy,僅僅有一個方法,我們僅僅用來演示。真正的游戲角色不可能僅僅有這么簡單。describe方法用來描寫敘述這個角色。

好,我們玩游戲肯定有職業對吧,假設我們這款游戲僅僅設計了4種職業:戰士(Worrior),法師(Mage),獵人(Hunter),術士(Warlock)。我們要創建4個實現類。這就相應ConcreteComponent類

public class Worrior implements Avatar {
    @Override
    public String describe() {
        return "戰士";
    }
}
public class Mage implements Avatar {
    @Override
    public String describe() {
        return "法師";
    }
}
public class Hunter implements Avatar {
    @Override
    public String describe() {
        return "獵人";
    }
}
public class WarLock implements Avatar {
    @Override
    public String describe() {
        return "術士";
    }
}

好了,如今我們已經創建好4種職業的游戲角色了。如今我們的玩家認為太單調了,全部相同職業的角色都長一個樣子,你們應該同意我們在創建角色的時候能夠改動角色的外觀。比方選擇頭發顏色。

這可怎么辦,我們有4種職業啊,每種職業提供3種顏色的頭發。我們得再創建12個子類啊,並且之前設計的4個實現類的作用也就不大了,由於大家肯定都去改變一下頭發的顏色。

好。先硬着頭皮來寫吧。

public class WorriorWithRedHair implements Avatar{

    @Override
    public String describe() {
        return "戰士+紅顏色頭發";
    }
}
public class WorriorWithGreenHair implements Avatar{

    @Override
    public String describe() {
        return "戰士+綠顏色頭發";
    }
}
public class WorriorWithBlueHair implements Avatar{

    @Override
    public String describe() {
        return "戰士+藍顏色頭發";
    }
}

public class MageWithRedHair implements Avatar{

    @Override
    public String describe() {
        return "法師+紅顏色頭發";
    }
}
public class MageWithGreenHair implements Avatar{

    @Override
    public String describe() {
        return "法師+綠顏色頭發";
    }
}
public class MageWithBlueHair implements Avatar{

    @Override
    public String describe() {
        return "法師+藍顏色頭發";
    }

public class HunterWithRedHair implements Avatar{

    @Override
    public String describe() {
        return "獵人+紅顏色頭發";
    }
}
public class HunterWithGreenHair implements Avatar{

    @Override
    public String describe() {
        return "獵人+綠顏色頭發";
    }
}
public class HunterWithBlueHair implements Avatar{

    @Override
    public String describe() {
        return "獵人+藍顏色頭發";
    }

public class WarLockWithRedHair implements Avatar{

    @Override
    public String describe() {
        return "術士+紅顏色頭發";
    }
}
public class WarLockWithGreenHair implements Avatar{

    @Override
    public String describe() {
        return "術士+綠顏色頭發";
    }
}
public class WarLockWithBlueHair implements Avatar{

    @Override
    public String describe() {
        return "術士+藍顏色頭發";
    }

好了。加班到半夜,最終寫完了。第二天上班,老板來找你了,如今我們的玩家越來越多了,他們反映說我們的角色還是太單調。我們還要讓玩家能夠選擇上衣的顏色和褲子的顏色,上衣有5種顏色,褲子有5種顏色。

聽完這個需求,我想你也應該吐血了。

比方玩家A會選擇戰士+紅色頭發+白色上衣+藍色褲子,玩家B會選擇術士+藍色頭發+白色上衣+黃色褲子。

這組合也太多了。這得寫多少個實現類。

這樣的方法肯定是行不通的。

使用裝飾者模式怎樣解決這個問題?

這時公司來了個大牛。他聽說了這個情況,接下了這個需求,你心想他一定是瘋了。但是第二天他就完畢了任務。你吃了一大驚,趕緊去看他的代碼是怎么實現的。原來這位大牛使用了你連聽都沒說過的裝飾者設計模式。

首先他設計了一個類。實現了Avatar接口,並且傳入了一個Avatar對象,這就相應UML圖中的Decorator

public class AvatarDecorator implements Avatar {
    private Avatar av;
    public AvatarDecorator(Avatar avatar){
        av = avatar;
    }

    @Override
    public String describe() {
        return av.describe();
    }
}

我們看到他里面持有一個Avatar類型的對象,在describe方法中實際調用的也是av的describe對象,我們傳入的Avatar對象也就是我們須要進行裝飾的對象了。

好。如今我們先來設計頭發顏色的裝飾類

public class RedHair extends AvatarDecorator {
    public RedHair(Avatar avatar) {
        super(avatar);
    }

    @Override
    public String describe() {
        return super.describe()+"+紅色頭發";
    }
}
public class GreenHair extends AvatarDecorator {
    public GreenHair(Avatar avatar) {
        super(avatar);
    }

    @Override
    public String describe() {
        return super.describe()+"+綠色頭發";
    }
}
public class BlueHair extends AvatarDecorator {
    public BlueHair(Avatar avatar) {
        super(avatar);
    }

    @Override
    public String describe() {
        return super.describe()+"+藍色頭發";
    }
}

我們看到。我們的構造方法是調用的super()的構造方法,也就是調用的AvatarDecorator的構造方法,我們的describe中也先調用了super.describe()然后后面加上了我們的裝飾內容,也就是說我們傳進來的一個Avatar對象被我們裝飾了。

這就相當於UML中的ConcreteDecorator。

好了,如今玩家想要創建一個角色的話就能夠這樣創建出來

//紅色頭發戰士
Avatar avatar1 = new RedHair(new Worrior());
//綠色頭發術士
Avatar avatar2 = new GreenHair(new WarLock());

接下來我們再設計上衣和褲子的裝飾類

public class WhiteJacket extends AvatarDecorator {
    public WhiteJacket(Avatar avatar) {
        super(avatar);
    }

    @Override
    public String describe() {
        return super.describe()+"+白色上衣";
    }
}
public class RedJacket extends AvatarDecorator {
    public RedJacket(Avatar avatar) {
        super(avatar);
    }

    @Override
    public String describe() {
        return super.describe()+"+紅色上衣";
    }
}public class BlackJacket extends AvatarDecorator {
    public BlackJacket(Avatar avatar) {
        super(avatar);
    }

    @Override
    public String describe() {
        return super.describe()+"+黑色上衣";
    }
}public class GreenJacket extends AvatarDecorator {
    public GreenJacket(Avatar avatar) {
        super(avatar);
    }

    @Override
    public String describe() {
        return super.describe()+"+綠色上衣";
    }
}public class BlueJacket extends AvatarDecorator {
    public BlueJacket(Avatar avatar) {
        super(avatar);
    }

    @Override
    public String describe() {
        return super.describe()+"+藍色上衣";
    }
}
public class WhitePants extends AvatarDecorator {
    public WhitePants(Avatar avatar) {
        super(avatar);
    }

    @Override
    public String describe() {
        return super.describe()+"+白色褲子";
    }
}
public class BlackPants extends AvatarDecorator {
    public BlackPants(Avatar avatar) {
        super(avatar);
    }

    @Override
    public String describe() {
        return super.describe()+"+黑色褲子";
    }
}
public class RedPants extends AvatarDecorator {
    public RedPants(Avatar avatar) {
        super(avatar);
    }

    @Override
    public String describe() {
        return super.describe()+"+紅色褲子";
    }
}
public class GreenPants extends AvatarDecorator {
    public GreenPants(Avatar avatar) {
        super(avatar);
    }

    @Override
    public String describe() {
        return super.describe()+"+綠色褲子";
    }
}
public class BluePants extends AvatarDecorator {
    public BluePants(Avatar avatar) {
        super(avatar);
    }

    @Override
    public String describe() {
        return super.describe()+"+藍色褲子";
    }
}

好了。如今我們就能夠隨意組合我們的角色了

 //綠色頭發獵人穿着白色上衣和黑色褲子
        Avatar avatar3 = new GreenHair(new WhiteJacket(new BlackPants(new Hunter())));
        //紅色頭發法師穿着紅色上衣和白色褲子
        Avatar avatar4 = new RedHair(new RedJacket(new WhitePants(new Mage())));

有圖有真相

這里寫圖片描寫敘述


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM