【23種設計模式專題】四 建造者模式

程序猿學社的GitHub,歡迎Star
github技術專題
本文已記錄到github

前言

通過上一章的學習,我們已經知道原型模式的淺克隆和深克隆,本文來了解一下建造者模式

定義

  • 建造者模式屬於創建型模式,建造者模式是23種設計模式的一種,將一個複雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示,它提供了一種創建對象的最佳方式。

建造者關係:

  • Product(產品):具體產品對象
  • builder(抽象建造者) : 創建一個產品各個部件的接口
  • ConcreteBuilder(具體建造者): 實現抽象建造者對應的接口
  • Director(指揮者): 創建一個複雜的對象,控制具體的流程

隔壁老王: “社長,你這是說啥咯,看的我一臉懵逼,不知道你說的啥。”
社長: “別急,我們通過一個簡單的案例,更好的理解什麼是創建型模式”

需求

在小公司待過的朋友,應該深有感觸,一個人負責需求、前端、後端、測試、部署等等職位。

隨着業務不斷擴展,老王的就職的公司,開發的效率越來越低,嚴重影響交付給用戶的時間,老王的boss,想了想,這樣下去,公司離倒閉越來越遠,參考大公司開發的流程,一個只負責一個職位,專崗專職,開發的流程實現流程規範化。
分爲:

  • 需求分析
  • 架構設計
  • 概要設計
  • 集成測試

傳統方式

抽象接口

package com.cxyxs.designmode.createtype;

/**
 * Description:
 * Author: 程序猿學社
 * Date:  2020/5/5 17:03
 * Modified By:
 */
public abstract class AbstractProject {
    public  abstract void demand();  //需求分析
    public  abstract void framework();  //架構設計
    public  abstract void outline();  //概要設計
    public  abstract void test();  //集成測試

    public  void project(){
        demand();
        framework();
        outline();
        test();
    }
}
  • 把每個流程抽取成一個個方法,再定義一個project方法,來定義流程的先後順序。

具體接口實現

package com.cxyxs.designmode.createtype;

/**
 * Description:
 * Author: 程序猿學社
 * Date:  2020/5/5 17:08
 * Modified By:
 */
public class OAProject extends AbstractProject{
    @Override
    public void demand() {
        System.out.println("OA 需求階段...");
    }

    @Override
    public void framework() {
        System.out.println("OA 架構設計階段...");
    }

    @Override
    public void outline() {
        System.out.println("OA 概要設計階段...");
    }

    @Override
    public void test() {
        System.out.println("OA 集成測試階段...");
    }
}
package com.cxyxs.designmode.createtype;

/**
 * Description:
 * Author: 程序猿學社
 * Date:  2020/5/5 17:10
 * Modified By:
 */
public class VideoProject extends  AbstractProject {

    @Override
    public void demand() {
        System.out.println("實景視頻 需求階段...");
    }

    @Override
    public void framework() {
        System.out.println("實景視頻 架構設計階段...");
    }

    @Override
    public void outline() {
        System.out.println("實景視頻 概要設計階段...");
    }

    @Override
    public void test() {
        System.out.println("實景視頻 集成測試階段...");
    }
}

測試接口

package com.cxyxs.designmode.createtype;

/**
 * Description:
 * Author: 程序猿學社
 * Date:  2020/5/5 17:12
 * Modified By:
 */
public class Client {
    public static void main(String[] args) {
        OAProject project = new OAProject();
        project.project();
        System.out.println("---------------");
        VideoProject project1 = new VideoProject();
        project1.project();
    }
}

  • 產品(項目)和產品建造的過程(做項目的過程)耦合性太高, 不利於擴展和維護。

隔壁老王: “那如何實現產品和產品建造的解耦?”
社長: “使用建造者模塊,看看通過建造者模式的代碼和傳統方式兩者的區別”

建造者模式

產品

package com.cxyxs.designmode.createtype.build;

import lombok.Data;

/**
 * Description:產品
 * Author: 程序猿學社
 * Date:  2020/5/5 20:19
 * Modified By:
 */
@Data
public class Project {
    private  String demand;
    private  String  framework;
    private  String  outline;
    private  String  test;
}

builder(抽象建造者)

package com.cxyxs.designmode.createtype.build;

/**
 * Description:
 * Author: 程序猿學社
 * Date:  2020/5/5 20:18
 * Modified By:
 */
public abstract class Builder {
    protected Project project=new Project();

    public  abstract void demand();  //需求分析
    public  abstract void framework();  //架構設計
    public  abstract void outline();  //概要設計
    public  abstract void test();  //集成測試

    /**
     * 得到產品
     * @return
     */
    public   Project getProject(){
        return  project;
    };
}

ConcreteBuilder(具體建造者)

package com.cxyxs.designmode.createtype.build;

/**
 * Description:
 * Author: 程序猿學社
 * Date:  2020/5/5 20:25
 * Modified By:
 */
public class OAConcreteBuilder extends Builder {

    @Override
    public void demand() {
        project.setDemand("OA 需求階段...");
        System.out.println("OA 需求階段...");
    }

    @Override
    public void framework() {
        project.setDemand("OA 架構設計階段...");
        System.out.println("OA 架構設計階段...");
    }

    @Override
    public void outline() {
        project.setOutline("OA 概要設計階段...");
        System.out.println("OA 概要設計階段...");
    }

    @Override
    public void test() {
        project.setTest("OA 集成測試階段...");
        System.out.println("OA 集成測試階段...");
    }

    @Override
    public Project getProject() {
        return super.getProject();
    }
}
  • 如果新增一個具體的VideoConcreteBuilder具體建造者,代碼類似。

Director(指揮者)

package com.cxyxs.designmode.createtype.build;

/**
 * Description:
 * Author: 程序猿學社
 * Date:  2020/5/5 20:33
 * Modified By:
 */
public class Director {
    public  Project build(Builder builder){
        builder.demand();
        builder.framework();
        builder.outline();
        builder.test();
        return  builder.getProject();
    };
}
  • 指揮者設置流程的先後順序,返回具體產品

測試類

package com.cxyxs.designmode.createtype.build;

/**
 * Description:
 * Author: 程序猿學社
 * Date:  2020/5/5 20:36
 * Modified By:
 */
public class Client {
    public static void main(String[] args) {
        //具體建造者
        Builder builder = new OAConcreteBuilder();
        //指揮者(項目經理)
        Director director = new Director();
        //得到具體產品
        Project project = director.build(builder);
        System.out.println(project.toString());
    }
}


社長: “到這裏,建造者的demo已經寫完咯,老王,對建造者模式4者的關係,有一個大致的瞭解。”
隔壁老王: “有的,社長”
社長: “那我們來根據UML圖梳理一下對應的關係”

  • Project(產品):也就是我們的OA項目,經過需求、架構設計、概要設計、集成測試這些過程後,得到的最終的項目(產品)。
  • Builder(抽象建造者): 創建一個產品,各個零部件涉及的接口。可以理解爲項目負責人,定義每個階段,我們應該輸出那些內容。
  • ConcreteBuilder(具體建造者): 實現抽象建造者接口,構造各個零部件。
    -Director(指揮者):用來創建一個複雜的對象(產品),並針對性的設計具體的流程(項目經理或者公司的boss),中間的流程,指揮者可自定義。

建造者優點:

  • 把產品和產品各個零部件組裝的流程分離開來,實現了程序的解耦,方便後期進行維護和擴展。
  • 把產品內部的組裝過程和細節,進行了封裝。可以這樣理解,作爲公司的大boss,只需要瞭解,公司各個項目的具體進展情況,無需關注,這個項目,從0到1詳細的一個過程。

缺點:

  • 使用建造者模式,產品之間應有一定的共性,會有限制。
  • 如果內部變化複雜,會有很多的建造類,會造成膿腫。

原創不易,不要白嫖,覺得有用的社友,給我點贊,讓更多的老鐵看到這篇文章。
因技術能力有限,如文中有不合理的地方,希望各位大佬指出,在下方評論留言,謝謝,希望大家一起進步,一起成長。

作者:程序猿學社
原創公衆號:『程序猿學社』,專注於java技術棧,分享java各個技術系列專題,以及各個技術點的面試題。
原創不易,轉載請註明來源(註明:來源於公衆號:程序猿學社, 作者:程序猿學社)。

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