建造者模式

建造者模式

概念

建造者模式是設計模式的一種,將一個複雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。

角色

  • 抽象建造者: 爲創建一個產品對象的各個部分指定抽象接口。通常有兩類方法,一類是buildPartX(),用於創建複雜對象的各個部分;另一類是getResult(),用於返回複雜對象
  • 具體建造者: 實現了抽象建造者的接口,實現了各個部分的具體構造和裝配方法,定義並明確所創建的複雜對象
  • 產品: 被構造的複雜對象,包括多個組件
  • 指揮者: 安排複雜對象的建造次序,客戶端一般只需要和指揮者進行交互

UML圖如下

在這裏插入圖片描述

建造者模式的優缺點

優點

  • 客戶端不需要知道產品內部組成,將產品本身與產品的創建過程進行解耦
  • 每一個具體建造者都相對獨立。方便替換具體建造者或增加新的具體建造者,符合開閉原則
  • 將複雜產品的創建步驟分解在不同點的方法中,使得創建過程更加清晰

缺點

  • 如果產品間差異很大,不適合用建造者模式
  • 如果產品的內容變化複雜,可能會導致需要定義很多具體建造者類來實現這種變化,導致系統變得很龐大

適合環境

  • 產品對象有複雜的內部結構
  • 產品對象的屬性相互依賴,需要指定其生產順序
  • 創建過程獨立於創建該對象的類
  • 隔離複雜對象的創建和使用

例子

我們現在要開發一款角色扮演遊戲,玩具可以創建不同的角色,不同的角色具有不同的能力。角色作爲遊戲的一個重要組成部分,需要對角色進行設計,而且伴隨着遊戲的更新會不斷添加新角色,遊戲角色是一個複雜對象,包含性別、髮型、服裝等都有所差異。如天使擁有美麗的面容和披肩長髮,身穿白裙;惡魔及其醜陋並且光頭穿一身黑衣服。我們需要創建出該遊戲的角色

分析

我們先將實體與簡單工廠的角色一一對應

  • 複雜產品對象: Action
  • 抽象建造者: ActionBuilder
  • 具體建造者: HeroBuilder
  • 具體建造者: AngelBuilder
  • 具體建造者: DevilBuilder
  • 指揮者: ActionController

看不懂不要緊,我們先看UML圖,在看代碼應該就能理解了

[外鏈圖片轉存失敗(img-5OPwRgiC-1564501958249)(https://raw.githubusercontent.com/kevinlu98/cloudimg/master/data/[email protected])]

編碼

當然,具體的遊戲開發比我們這個僞代碼難多了,我們就是模擬一下這個過程

Action.java

package cn.kevinlu98.builder;

/**
 * @Author: Kevin·Lu
 * @Date: 12:20 AM 2019/7/28
 * @Description: 遊戲角色類,充當複雜產品對象。
 */
public class Actor {

    private String type;        //角色類型
    private String sex;         //性別
    private String face;        //臉型
    private String costume;     //服裝
    private String hairstyle;   //髮型

    //getter and setter
}

ActionBuilder.java

package cn.kevinlu98.builder;

/**
 * @Author: Kevin·Lu
 * @Date: 12:24 AM 2019/7/28
 * @Description: 遊戲角色建造者,充當抽象建造者
 */
public abstract class ActorBuilder {
    protected Actor actor = new Actor();

    public abstract void buildType();

    public abstract void buildSex();

    public abstract void buildFace();

    public abstract void buildCustomer();

    public abstract void buildHairstyle();

    /**
     * 工廠方法,返回一個完整的角色對象
     *
     * @return
     */
    public Actor createActor() {
        return actor;
    }
}

HeroBuilder.java

package cn.kevinlu98.builder;

/**
 * @Author: Kevin·Lu
 * @Date: 12:27 AM 2019/7/28
 * @Description: 英雄角色建造者,充當具體建造者
 */
public class HeroBuilder extends ActorBuilder {
    @Override
    public void buildType() {
        actor.setType("英雄");
    }

    @Override
    public void buildSex() {
        actor.setSex("男");
    }

    @Override
    public void buildFace() {
        actor.setFace("英俊");
    }

    @Override
    public void buildCustomer() {
        actor.setCostume("盔甲");
    }

    @Override
    public void buildHairstyle() {
        actor.setHairstyle("飄逸");
    }
}

AngelBuilder.java

package cn.kevinlu98.builder;

/**
 * @Author: Kevin·Lu
 * @Date: 12:29 AM 2019/7/28
 * @Description: 天使角色建造者,充當具體建造者
 */
public class AngelBuilder extends ActorBuilder {
    @Override
    public void buildType() {
        actor.setType("天使");
    }

    @Override
    public void buildSex() {
        actor.setSex("女");
    }

    @Override
    public void buildFace() {
        actor.setFace("漂亮");
    }

    @Override
    public void buildCustomer() {
        actor.setCostume("白裙");
    }

    @Override
    public void buildHairstyle() {
        actor.setHairstyle("披肩長髮");
    }
}

DevilBuilder.java

package cn.kevinlu98.builder;

/**
 * @Author: Kevin·Lu
 * @Date: 12:30 AM 2019/7/28
 * @Description: 惡魔角色建造者,充當具體建造者
 */
public class DevilBuilder extends ActorBuilder {
    @Override
    public void buildType() {
        actor.setType("惡魔");
    }

    @Override
    public void buildSex() {
        actor.setSex("妖");
    }

    @Override
    public void buildFace() {
        actor.setFace("醜陋");
    }

    @Override
    public void buildCustomer() {
        actor.setCostume("黑衣");
    }

    @Override
    public void buildHairstyle() {
        actor.setHairstyle("光頭");
    }
}

ActionController.java

package cn.kevinlu98.builder;

/**
 * @Author: Kevin·Lu
 * @Date: 12:31 AM 2019/7/28
 * @Description: 角色控制器,充當指揮者
 */
public class ActorController {
    public Actor construct(ActorBuilder builder) {
        builder.buildCustomer();
        builder.buildFace();
        builder.buildHairstyle();
        builder.buildSex();
        builder.buildType();
        return builder.createActor();
    }
}

config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<config>
    <className>cn.kevinlu98.builder.AngelBuilder</className>
</config>

XMLUtil.java(略,和之前的大同小異)

運行結果

在這裏插入圖片描述

至此,工廠方法設計模式介紹完成,希望能幫助到您

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章