設計模式 - 建構者模式 (Creational Patterns - Build Pattern)

前言

此篇文章會介紹建構者模式(Build Pattern),並且會繼續使用前文 - 設計模式 - 工廠模式 (Creational Patterns - Factory Pattern) - 的英雄範例進行實作

甚麼是建構者模式?

我們回顧一下之前討論的工廠模式

工廠模式 - 封裝物件產出的邏輯

而工廠模式只關注,你要甚麼我就給你甚麼,對於產出的細節不透漏給client(呼叫此function)知道。

而建構者模式,則是將複雜的封裝流程切分,並且公開開發者認為client端可以掌控的邏輯method,而通常會需要使用到建構者模式也代表此物件的封裝過程比較複雜。

類別圖

  • Director負責透過Builder開放的方法組裝物件
  • Builder定義這個物件要開放的方法

範例

此範例主要是創建一個訓練營(Camp),然後跟去GameClient輸入的Build不同來創建一般或是高級的英雄。

  • Camp 在此是Director的角色

因為範例比較簡單所以感受不太到Builder的威力,若是未來如同真的遊戲般包含眼睛、眼球、身高、體重等等屬性,就可以感受到Builder的重要。

package com.design.pattern.creational.factory.builder;


import java.util.Scanner;

class Hero {
    String hair;
    String body;

    public void setHair(String hair) {
        this.hair = hair;
    }

    public void setBody(String body) {
        this.body = body;
    }
}


abstract class HeroBuilder {
    protected Hero hero;

    public void createHero() {
        hero = new Hero();
    }

    public Hero getHero() {
        return hero;
    }

    public abstract void setHair();

    public abstract void setBody();
}

class NormalHeroBuilder extends HeroBuilder {

    @Override
    public void setHair() {
        hero.setHair("normal");
    }

    @Override
    public void setBody() {
        hero.setBody("normal");
    }
}

class HighHeroBuilder extends HeroBuilder {
    @Override
    public void setHair() {
        hero.setHair("high");
    }

    @Override
    public void setBody() {
        hero.setBody("high");
    }
}

class Camp {
    private HeroBuilder heroBuilder;

    public void setHeroBuilder(HeroBuilder heroBuilder) {
        this.heroBuilder = heroBuilder;
    }

    public Hero getHero() {
        return heroBuilder.getHero();
    }

    public void constructHero() {
        heroBuilder.createHero();
        heroBuilder.setBody();
        heroBuilder.setHair();
    }
}

public class GameClient {

    public static void main(String[] args) {
        Camp heroCamp = new Camp();
        HeroBuilder heroBuilder = null;
        Scanner scanner = new Scanner(System.in);
        String type = scanner.next();
        if (type.equals("Normal")) {
            heroBuilder = new NormalHeroBuilder();
        } else if (type.equals("High")) {
            heroBuilder = new HighHeroBuilder();
        }

        if (heroBuilder != null) {
            heroCamp.setHeroBuilder(heroBuilder);
            heroCamp.constructHero();
            Hero hero = heroCamp.getHero();
            System.out.println(hero.body);
            System.out.println(hero.hair);
        }

    }
}

原始碼連結

結論

Builder Pattern的使用時機

  • 當組裝物件的邏輯變複雜時
  • 當未來客戶端需要其他客製化內容時

留言

這個網誌中的熱門文章

Java Lambda Map篇

(InterviewBit) System Design - Design Cache System

設計模式 - 享元模式 (Structural Patterns - Flyweight Design Pattern)