【設計模式】抽象工廠模式

設計模式

抽象工廠模式

抽象工廠模式(Abstract Factory Pattern)是所有形態(tài)的工廠模式中最為抽象和最具一般性的一種形態(tài)。抽象工廠模式是指當有多個抽象角色時,使用的一種工廠模式。抽象工廠模式可以向客戶端提供一個接口,使客戶端在不必指定產(chǎn)品的具體的情況下,創(chuàng)建多個產(chǎn)品族中的產(chǎn)品對象。

UML類圖

抽象工廠模式
  1. 抽象產(chǎn)品類(AbstractProductX):多個系列抽象產(chǎn)品(X=A,B,C...)。
  2. 具體產(chǎn)品類(ProductX):實現(xiàn)基類中的抽象方法(多個不同的具體產(chǎn)品,X=1,2,3..)。
  3. 抽象工廠類或接口(AbstractFactory):定義具體工廠的多個公共接口(擁有各系列產(chǎn)品創(chuàng)建的接口)。
  4. 具體工廠類(FactoryX):定義創(chuàng)建各系列具體產(chǎn)品實例的方法。(每個工廠對應一種具體產(chǎn)品,X=1,2,3...)。

與工廠模式的區(qū)別

  1. 工廠模式的工廠只能生產(chǎn)一個系列的產(chǎn)品。而抽象工廠模式的工廠可以生產(chǎn)一個或多個系列的產(chǎn)品。
  2. 工廠模式關注的是一個系列的不同種產(chǎn)品。而抽象工廠模式關注的是不同系列產(chǎn)品。

案例分析

接著上篇【設計模式】工廠模式的話題。

場景:玩《英雄聯(lián)盟》(5v5 moba端游)新開一局游戲,游戲開始每個玩家需要選一個英雄之外,還需要選擇天賦,召喚師技能。也就是需要創(chuàng)建三種產(chǎn)品。并且,在不同玩法下,比如召喚師峽谷(自選或排位等)與哭嚎深淵(大亂斗),創(chuàng)建的產(chǎn)品也略微有所差異,比如大亂斗下英雄一開始就3級,召喚師技能沒有傳送,有雪球。結構上:

  1. 產(chǎn)品(三個系列):英雄,天賦,召喚師技能。
  2. 工廠(兩個):召喚師峽谷工廠,哭嚎深淵工廠。

代碼實現(xiàn)

英雄基類(新增lv成員變量和print()方法)

public abstract class Hero {
    protected String name;
    protected int lv;

    public abstract void say();

    public void print() {
        System.out.println("name:" + name);
        System.out.println("lv:" + lv);
    }

}

只考慮一種英雄,比如寒冰射手-艾希。


艾希

艾希類:

public class Ashe extends Hero {
    // 簡化構造方法,只弄個名字。
    public Ashe() {
        this.name = "寒冰射手-艾希";
    }

    // 艾希臺詞(不重要)
    @Override
    public void say() {
        System.out.println(name + ":" + "世間萬物皆系于一箭之上。");
    }
}

召喚師峽谷中的艾希:

public class Ashe_XiaGu extends Ashe {
    // 在召喚師峽谷中初始等級1級。
    public Ashe_XiaGu() {
        super();
        this.lv = 1;
    }
}

哭嚎深淵中的艾希:

public class Ashe_ShenYuan extends Ashe {
    // 在哭嚎深淵中初始等級3級。
    public Ashe_ShenYuan() {
        super();
        this.lv = 3;
    }
}

天賦基類:(就簡單點只用打印信息區(qū)分下好了)

public abstract class Talent {
    // 只打印一下信息
    public abstract void print();
}

兩個天賦實現(xiàn)類:

public class Talent_XiaGu extends Talent{

    @Override
    public void print() {
        System.out.println("召喚師峽谷中的天賦");
    }

}
public class Talent_ShenYuan extends Talent{

    @Override
    public void print() {
        System.out.println("哭嚎深淵中的天賦");
    }

}

召喚師技能基類:

public abstract class Skill {
    // 召喚師技能種類
    protected String[] skill_type;

    // 選擇兩種召喚師技能
    public void choose(int i, int j) {
        System.out.println("你選擇了" + skill_type[i] + "和" + skill_type[j]);
    }
}

兩個召喚師技能實現(xiàn)類:

public class Skill_XiaGu extends Skill {
    public Skill_XiaGu() {
        this.skill_type = new String[] { "閃現(xiàn)", "治療", "傳送", "凈化", "光盾", "虛弱",
                "懲戒", "疾走" };
    }
}
public class Skill_ShenYuan extends Skill {
    public Skill_ShenYuan() {
        this.skill_type = new String[] { "閃現(xiàn)", "治療", "雪球", "凈化", "光盾", "虛弱",
                "回藍", "疾走" };
    }
}

準備工作完畢,接下來就是重點了。

抽象工廠類或接口:

public interface AbstractFactory {
    //創(chuàng)建英雄
    public abstract Hero createHero();
    //創(chuàng)建天賦
    public abstract Talent createTalent();
    //創(chuàng)建召喚師技能
    public abstract Skill createSkill();

}

召喚師峽谷工廠類:

public class Factory_XiaGu implements AbstractFactory {
    //假設我選艾希
    public Hero createHero() {
        return new Ashe_XiaGu();
    }

    public Talent createTalent() {
        return new Talent_XiaGu();
    }

    public Skill createSkill() {
        return new Skill_XiaGu();
    }
}

哭嚎深淵工廠類:

public class Factory_ShenYuan implements AbstractFactory {
    //假設我選艾希
    public Hero createHero() {
        return new Ashe_ShenYuan();
    }

    public Talent createTalent() {
        return new Talent_ShenYuan();
    }

    public Skill createSkill() {
        return new Skill_ShenYuan();
    }
}

最后是客戶端代碼:

public class Client {
    public static void main(String[] args) {
        System.out.println("請選擇游戲模式");
        System.out.println("1,召喚師峽谷   2,哭嚎深淵");
        Scanner can = new Scanner(System.in);
        int w = can.nextInt();
        can.close();
        AbstractFactory factory = null;
        switch (w) {
        case 1:
            // 召喚師峽谷
            factory = new Factory_XiaGu();
            break;
        case 2:
            // 哭嚎深淵
            factory = new Factory_ShenYuan();
            break;
        }
        // 英雄(選擇的是艾希)
        Hero hero = factory.createHero();
        hero.print();
        hero.say();
        // 天賦
        Talent talent = factory.createTalent();
        talent.print();
        // 召喚師技能
        Skill skill = factory.createSkill();
        skill.choose(0, 2);

    }

}

客戶端選擇游戲模式,就相當于選擇了不同的工廠去生產(chǎn)游戲元素(英雄,天賦,召喚師技能)。

也可以結合工廠模式使用,比如選擇游戲類型后,利用工廠模式選擇英雄等等。

工廠模式,客戶端不需要知道產(chǎn)品的創(chuàng)建過程。并且,客戶端只需要選擇游戲模式,就可以用工廠創(chuàng)建多個系列的產(chǎn)品(英雄,天賦,召喚師技能)。主要特點就是一個工廠多系列產(chǎn)品。

運行結果

玩局匹配,選召喚師峽谷:


控制臺

源計劃皮膚的寒冰射手。


源計劃-艾希

實際應用

常見的案例就是使用不同的數(shù)據(jù)庫,數(shù)據(jù)庫能處理用戶,也能處理關系。但是,數(shù)據(jù)庫分MySQL,Orical等。處理同樣或類似的事情,他們的具體實現(xiàn)存在差異。那就可以抽出一個工廠基類,再分別寫兩個不同的工廠去處理。這樣的話,某些東西就可以做到可遷移的目的。

附件

設計模式Demo
GitHub源碼:https://github.com/wzmyyj/Design-Pattern

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,663評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,125評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,506評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,614評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,402評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,934評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,021評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,168評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,690評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,596評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,784評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,288評論 5 357
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,027評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,404評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,662評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,398評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,743評論 2 370

推薦閱讀更多精彩內(nèi)容