【設計模式】——建造者模式

【情景展示】    

    如今已經是信息化的時代,網絡已經融入每一個家庭,移動通信業也迅猛發展,4G、5G通信技術日趨完善。面對這個龐大的蛋糕,各個通信運營商間也展開了激烈的競爭。爲了吸引更多的消費者,各大運營商開始使用套餐。例如:20元包400條短信套餐,30元包600條短信套餐。
    下面,我們來看看張三如何去通信營業廳辦理手機套餐的。
    客戶——張三,最近新買了一部OPPO R11手機,使用的是某通信運營商的通信服務。聽說該運營商提供的通信服務有很多手機套餐可供選擇,都是比較實惠的,張三想了想還是要選擇一個適合自己的手機套餐,否則,這一個月的花銷都花在話費上了。說話間,他已來到一個營業廳網點。
    操作員:你好,先生,請問想要辦理什麼業務?
    張三:你好,請問有什麼優惠手機套餐?
    操作員:好的,目前有20元包400條短信的手機套餐和30元包600條短信的手機套餐,兩種套餐必須開通彩鈴業務。
   (操作員回答的很熟練嘛!一定很多人辦理,張三心裏想)
    張三:哦,是這樣啊。哪一種套餐比較划算呢?
    操作員:先生,這要看您的具體消費情況了。如果您每月發短信很多,建議您選擇30元600條短信套餐,如果發短信不是很多,您可以選擇20元包400條短信的套餐。
    張三:哦,好的。嗯……(思考一番),那我辦理20元400條短信的套餐吧。
    操作員:好的,先生。
   (操作員開始操作計算機,設置客戶手機套餐了)
   (張三一旁好奇的看着,噢?原來設置手機套餐還要分幾步的!張三心裏嘀咕着。設置用戶話費20元,短信400條,最後設置了彩鈴)。
    操作員:好了,先生。您的套餐已經設置完成。次月生效!

    張三:哦,好的,還真快啊。謝謝!

    操作員:不客氣,先生,請問還要辦理其他業務嗎?
    張三:沒有了。(起身要離開)
    操作員:好的,先生。那您慢走了,歡迎下次光臨!
    張三滿心歡喜地走了,這裏的服務態度真好,心情也好,又獲得了想要的手機套餐!

【模式定義】

建造者模式是一個構造複雜對象的設計模式。

建造者模式把複雜對象的創建與表示分離,使得同樣的構建過程可以創建不同的表示。

【靜態建模】

    角色分析

    客戶張三——終端需求

    營業廳操作員——指導者(通知指導建造者生產什麼樣的手機套餐)

    計算機——建造者(建造各種手機套餐)

【代碼實現】

工程結構圖:


1、創建產品,手機套餐——MobilePackage

package com.demo.builder.model;

/**
 * 手機套餐
 */
public class MobilePackage {
    //話費
    private float money;
    //短信
    private int shortInfo;
    //彩鈴
    private String music;

    public float getMoney() {
        return money;
    }

    public void setMoney(float money) {
        this.money = money;
    }

    public int getShortInfo() {
        return shortInfo;
    }

    public void setShortInfo(int shortInfo) {
        this.shortInfo = shortInfo;
    }

    public String getMusic() {
        return music;
    }

    public void setMusic(String music) {
        this.music = music;
    }
}
2、建立抽象建造者

(1)建造者接口——IMobileBuilder

package com.demo.builder.itf;

import com.demo.builder.model.MobilePackage;

/**
 * 手機套餐
 */
public interface IMobileBuilder {
    //建造手機套餐的話費
    public void buildMoney();

    //建造手機套餐的短信
    public void buildShortInfo();

    //建造手機套餐的彩鈴
    public void buildMusic();

    //返回建造的手機套餐對象
    public MobilePackage getMobilePackage();

}
(2)抽象建造者——AbstractBasePackage

package com.demo.builder.base;

import com.demo.builder.model.MobilePackage;

public abstract class AbstractBasePackage {
    //手機套餐實例變量(爲了在不同包下的子類使用)
    protected MobilePackage mobilePackage;

    public AbstractBasePackage(){
        this.mobilePackage = new MobilePackage();
    }
}
3、建立具體建造者

(1)具體建造者1——MobileBuilderImpl1

     (20元包400條短信的手機套餐)

package com.demo.builder.itf;

import com.demo.builder.base.AbstractBasePackage;
import com.demo.builder.model.MobilePackage;

/**
 * 套餐1:
 */
public class MobileBuilderImpl1 extends AbstractBasePackage implements IMobileBuilder{

    //建造手機套餐的話費
    public void buildMoney(){
        this.mobilePackage.setMoney(20.0f);
    }

    //建造手機套餐的彩鈴
    public void buildMusic(){
        this.mobilePackage.setMusic("天使");
    }

    //建造手機套餐的短信
    public void buildShortInfo(){
        this.mobilePackage.setShortInfo(400);
    }

    //返回建造的手機套餐對象
    public MobilePackage getMobilePackage(){
        return this.mobilePackage;
    }
}

(2)具體建造者2——MobileBuilderImpl2

     (30元包600條短信的手機套餐)

package com.demo.builder.itf;

import com.demo.builder.base.AbstractBasePackage;
import com.demo.builder.model.MobilePackage;

/**
 * 套餐2
 */
public class MobileBuilderImpl2 extends AbstractBasePackage implements IMobileBuilder{

    //建造手機套餐的話費
    public void buildMoney(){
        this.mobilePackage.setMoney(30.0f);
    }

    //建造手機套餐的彩鈴
    public void buildMusic(){
        this.mobilePackage.setMusic("大海");
    }

    //建造手機套餐的短信
    public void buildShortInfo(){
        this.mobilePackage.setShortInfo(600);
    }

    //返回建造的手機套餐對象
    public MobilePackage getMobilePackage(){
        return this.mobilePackage;
    }
}
4、創建指導者——MobileDirector

package com.demo.builder.director;

import com.demo.builder.itf.IMobileBuilder;
import com.demo.builder.model.MobilePackage;

public class MobileDirector {
    public MobilePackage createMobilePackage(IMobileBuilder mobileBuilder){
        if (mobileBuilder != null){
            //構建話費
            mobileBuilder.buildMoney();
            //構建短信
            mobileBuilder.buildShortInfo();
            //構建彩鈴
            mobileBuilder.buildMusic();
            //返回手機套餐
            return mobileBuilder.getMobilePackage();
        }
        return null;
    }
}
5、主應用程序——MainApp

package com.demo.builder;

import com.demo.builder.director.MobileDirector;
import com.demo.builder.itf.MobileBuilderImpl1;
import com.demo.builder.itf.MobileBuilderImpl2;
import com.demo.builder.model.MobilePackage;


public class MainApp {
    /**
     * 主應用程序
     */
    public static void main(String[] args){

        //創建指導者
        MobileDirector mobileDirector = new MobileDirector();
        //套餐1
        MobileBuilderImpl1 mobileBuilderImpl1 = new MobileBuilderImpl1();
        //套餐2
        MobileBuilderImpl2 mobileBuilderImpl2 = new MobileBuilderImpl2();

        printMessage(mobileDirector.createMobilePackage(mobileBuilderImpl1));
        printMessage(mobileDirector.createMobilePackage(mobileBuilderImpl2));
    }

    /**
     * 打印輸出套餐信息
     */
    public static void printMessage(MobilePackage mobilePackage){
        System.out.println("話費:" + mobilePackage.getMoney() + "\t短信:" +
                mobilePackage.getShortInfo() + "條\t彩鈴:" + mobilePackage.getMusic());
    }

}
6、運行效果


【小結】

1、建造者模式

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

2、設計原則

(1)分步驟創建複雜對象,使構建複雜對象變得不那麼複雜;

(2)構建和表示分離,更好地適應外部需求的變化;

(3)單一職責原則,提高軟件內部的聚合度,降低模塊之間的耦合度。

3、建造者模式和抽象工廠模式的區別

(1)建造者模式着重於分步構造一個複雜對象,而抽象工廠模式則着重多個系列的產

對象即對象族(簡單的或者複雜的)的構造;

(2)建造者模式是在最後一步返回具體產品,而抽象工廠模式則是立即返回具體產品。

4、使用場合

(1)當生產的產品對象內部具有複雜的結構時;

(2)當複雜對象需要與表示分離,可能需要創建不同的表示時;

(3)當需要向客戶隱藏產品內部結構的表示時。



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