程序猿學社的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各個技術系列專題,以及各個技術點的面試題。
原創不易,轉載請註明來源(註明:來源於公衆號:程序猿學社, 作者:程序猿學社)。