建造者模式(Builder Pattern)
不同於工場模式,給一些生成要求而產生目標物件
(ex: 以遊戲舉例,跟兵工廠說, 我要弓箭手, 工廠就把弓箭手給你)
若有太多客制項目,工廠要為了這些該怎麼辦
如:我要一個有紅色弓箭的弓箭手,且要女的,身材很好,年歲.... 一大堆條件.
對於工廠來說他只要產生弓箭手! 其餘的他不管...
上面只個例子,主要強調針對太多客制項目的時候,該怎麼處裡呢?
Builder Pattern 就是一個可參考的設計模型
以下我以包子舉例好了
有個包子工廠專門生產包子
如肉包, 菜包, 素包等常見的肉包
但我這個客人很奇怪,嘴很挑,想吃點山珍海味的包子(魚翅包子啊, 開口笑包子之類的)
對包子工廠來說,就需要一直開很多建構式或者type來處理.
若我想要一個魚翅包子,那不就要新增或修改工廠裡面的項目嘛?
對使用者來說,我只要個特別餡料的包子而已,還要研究整個包子工廠運作,會不會太麻煩!!!
這時候就可以使用builder pattern了
讓使用者自行客制所需要的內容
工廠根據內容再產生需求的包子,讓使用者簡單操作
以下是個簡單的範例
我用手機來舉例, 或許大家比較有感
有個手機工廠 可以產生很多種類的手機
有ios, android, windows phone 三種系統
也可以根據需求來客制裝置
程式碼如下:
package com.owen.blogapp;
import java.lang.ref.WeakReference;
import java.util.Locale;
/**
* Created by owen on 2017/11/19.
*/
public class Phone {
private enum TYPE {IOS, ANDROID, WINDOW_PHONE, OTHER}
private TYPE mType;
private boolean mWifi;
private boolean mBluetooth;
private int mMemorySize;
private int mDiskSize;
private int mPowerSize;
private Locale mLocale;
private String mDefaultInput;
private String[] mOther;
public Phone(){}
public Phone(TYPE mType, boolean mWifi, boolean mBluetooth,
int mMemorySize, int mDiskSize, int mPowerSize,
Locale mLocale, String mDefaultInput, String[] mOther, String... other) {
this.mType = mType;
this.mWifi = mWifi;
this.mBluetooth = mBluetooth;
this.mMemorySize = mMemorySize;
this.mDiskSize = mDiskSize;
this.mPowerSize = mPowerSize;
this.mLocale = mLocale;
this.mDefaultInput = mDefaultInput;
this.mOther = mOther;
}
public TYPE getType() {
return mType;
}
public void setType(TYPE mType) {
this.mType = mType;
}
public boolean ismWifi() {
return mWifi;
}
public void setWifi(boolean mWifi) {
this.mWifi = mWifi;
}
public boolean ismBluetooth() {
return mBluetooth;
}
public void setBluetooth(boolean mBluetooth) {
this.mBluetooth = mBluetooth;
}
public int getMemorySize() {
return mMemorySize;
}
public void setMemorySize(int mMemorySize) {
this.mMemorySize = mMemorySize;
}
public int getDiskSize() {
return mDiskSize;
}
public void setDiskSize(int mDiskSize) {
this.mDiskSize = mDiskSize;
}
public int getPowerSize() {
return mPowerSize;
}
public void setPowerSize(int mPowerSize) {
this.mPowerSize = mPowerSize;
}
public Locale getLocale() {
return mLocale;
}
public void setLocale(Locale mLocale) {
this.mLocale = mLocale;
}
public String getDefaultInput() {
return mDefaultInput;
}
public void setDefaultInput(String mDefaultInput) {
this.mDefaultInput = mDefaultInput;
}
public String[] getOther() {
return mOther;
}
public void setOther(String[] mOther) {
this.mOther = mOther;
}
public static class Builder {
private WeakReference mWType;
private WeakReference mWWifi;
private WeakReference mWBluetooth;
private WeakReference mWMemorySize;
private WeakReference mWDiskSize;
private WeakReference mWPowerSize;
private WeakReference mWLocale;
private WeakReference mWDefaultInput;
private WeakReference mWOther;
public Builder setType(TYPE type) {
mWType = new WeakReference<>(type);
return this;
}
public Builder setWifiEnable(boolean wifiEnable) {
mWWifi = new WeakReference<>(wifiEnable);
return this;
}
public Builder setBTEnable(boolean setBTEnable) {
mWBluetooth = new WeakReference<>(setBTEnable);
return this;
}
public Builder setemorySize(int size) {
mWMemorySize = new WeakReference<>(size);
return this;
}
public Builder setDiskSize(int diskSize) {
mWDiskSize = new WeakReference<>(diskSize);
return this;
}
public Builder setPowerSize(int powerSize) {
mWPowerSize = new WeakReference<>(powerSize);
return this;
}
public Builder setLocale(Locale locale) {
mWLocale = new WeakReference<>(locale);
return this;
}
public Builder setDefaultInput(String defaultInput) {
mWDefaultInput = new WeakReference<>(defaultInput);
return this;
}
public Builder setOther(String... other) {
mWOther = new WeakReference<>(other);
return this;
}
public Phone build() {
Phone phone = new Phone();
if (mWType != null && mWType.get()!= null){
phone.setType(mWType.get());
}
if (mWBluetooth != null && mWBluetooth.get()!= null){
phone.setBluetooth(mWBluetooth.get());
}
if (mWMemorySize != null && mWMemorySize.get()!= null){
phone.setMemorySize(mWMemorySize.get());
}
if (mWDiskSize != null && mWDiskSize.get()!= null){
phone.setDiskSize(mWDiskSize.get());
}
if (mWPowerSize != null && mWPowerSize.get()!= null){
phone.setPowerSize(mWPowerSize.get());
}
if (mWLocale != null && mWLocale.get()!= null){
phone.setLocale(mWLocale.get());
}
if (mWDefaultInput != null && mWDefaultInput.get()!= null){
phone.setDefaultInput(mWDefaultInput.get());
}
if (mWOther != null && mWOther.get()!= null){
phone.setOther(mWOther.get());
}
return phone;
}
}
}
整個程式碼有個好處, 不用針對部分需求建立建構式...
