1.什么是builder模式
? ?簡單解釋,在程序設計的時候,如果面對的對象屬性較多,對象復雜性比較大(例如對象包含對象)的情況,開發者選擇這種設計模式去設計一個類的時候,開發者可以在不知道類內部結構構建細節的情況下,清晰地控制對象構造流程。例如,一個person類擁有很多屬性的時候,最常見的比如name,age,weight,height等等。在這里兩個地方體現出builder模式的優勢:
(1)如果在創建一個person對象,只需要name、age屬性,則需要創建多一個包含這兩個屬性的構造方法。需求不一樣,構造方法就需要更多。累贅。
(2)對于普通的構造方法,當我們初始化weight、height兩個屬性的時候,我們一般會如下。
Person person = new Person("123","53");
如果屬性一多,我們根本很模糊知道weight是哪個。
2.模式適用范圍
(1)當創建復雜對象的算法應該獨立于該對象的組成部分以及它們的裝配方式時。
(2)當構造過程必須允許被構造的對象有不同的表示時。
(3)Builder模式要解決的也正是這樣的問題:
當我們要創建的對象很復雜的時候(通常是由很多其他的對象組合而成),
我們要復雜對象的創建過程和這個對象的表示(展示)分離開來,
這樣做的好處就是通過一步步的進行復雜對象的構建,
由于在每一步的構造過程中可以引入參數,使得經過相同的步驟創建最后得到的對象的展示不一樣。
3.具體應用
筆者這里通過汽車Car類對象包含引擎Engine類、導航Naviaror類、車輪Wheel類作為一個復雜性類說明Builder模式的應用。
(1)公有抽象類Car
/**
* 車的抽象類 較復雜的對象,對象包含對象
* Created by wsy on 2016/2/17.
*/
public abstract class Car {
protected Engine mEngine;
protected Navigator mNavigator;
protected Wheel mWheel;
public Car() {
}
public Car(Engine mEngine, Navigator mNavigator, Wheel mWheel) {
this.mEngine = mEngine;
this.mNavigator = mNavigator;
this.mWheel = mWheel;
}
/**
public Car(Engine mEngine) {
this.mEngine = mEngine;
}
public Car(Engine mEngine, Navigator mNavigator) {
this.mEngine = mEngine;
this.mNavigator = mNavigator;
}
**/
public Engine getmEngine() {
return mEngine;
}
public void setmEngine(Engine mEngine) {
this.mEngine = mEngine;
}
public Navigator getmNavigator() {
return mNavigator;
}
public void setmNavigator(Navigator mNavigator) {
this.mNavigator = mNavigator;
}
public Wheel getmWheel() {
return mWheel;
}
public void setmWheel(Wheel mWheel) {
this.mWheel = mWheel;
}
@Override
public String toString() {
return "Car{" +
"mEngine=" + mEngine +
", mNavigator=" + mNavigator +
", mWheel=" + mWheel +
'}';
}
}
(2) 具體實現奔馳類
/**
* 奔馳實體類
* Created by wsy on 2016/2/17.
*/
public class BenzCar extends Car {
public BenzCar() {
}
public BenzCar(Engine mEngine, Navigator mNavigator, Wheel mWheel) {
super(mEngine, mNavigator, mWheel);
}
/**
public BenzCar(Engine mEngine) {
super(mEngine);
}
public BenzCar(Engine mEngine, Navigator mNavigator) {
super(mEngine, mNavigator);
}
**/
// 這里如果重寫了,直接通過this.mEngine,因為是父類projected類型,訪問不到,因此日志打印會為空值,多態
// @Override
// public void setmEngine(String mEngine) {
// mEngine = "Benz Engine 2016";
// }
}
(3)Car車構建類Builder
/**
* 奔馳構建類
* Created by wsy on 2016/2/17.
*/
public class BenzBuilder{
private Car mCar = new BenzCar();
public BenzBuilder builderEngine(Engine mEngine) {
mCar.setmEngine(mEngine);
return this;
}
public BenzBuilder builderWheel(Wheel mWheel) {
mCar.setmWheel(mWheel);
return this;
}
@Override
public Builder builderNavigator(Navigator mNavigator) {
mCar.setmNavigator(mNavigator);
return this;
}
public Car onCreate() {
return mCar;
}
}
(4)引擎Engine類、導航Naviaror類、車輪Wheel類(這里構建類builder都是靜態內部類)
/**
* 引擎實體類
* Created by wsy on 2016/2/17.
*/
public class Engine {
private String brand;
private String power;
public Engine(String brand, String power) {
this.brand = brand;
this.power = power;
}
public Engine() {
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getPower() {
return power;
}
public void setPower(String power) {
this.power = power;
}
@Override
public String toString() {
return "Engine{" +
"brand='" + brand + '\'' +
", power='" + power + '\'' +
'}';
}
public static class EngineBuilder{
private Engine mEngine = new Engine();
private String brand;
private String power;
public EngineBuilder setBrand(String brand) {
mEngine.setBrand(brand);
return this;
}
public EngineBuilder setPower(String power) {
mEngine.setPower(power);
return this;
}
public Engine create(){
return mEngine;
}
}
}
package cn.wsy.builder.simple.common;
/**
* 導航儀實體類
* Created by wsy on 2016/2/17.
*/
public class Navigator {
private String brand;
private String price;
public Navigator(String brand, String price) {
this.brand = brand;
this.price = price;
}
public Navigator() {
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
@Override
public String toString() {
return "Navigator{" +
"brand='" + brand + '\'' +
", price='" + price + '\'' +
'}';
}
public static class NavigatorBuilder {
private Navigator mNavigator = new Navigator();
private String brand;
private String price;
public NavigatorBuilder setPrice(String price) {
mNavigator.setPrice(price);
return this;
}
public NavigatorBuilder setBrand(String brand) {
mNavigator.setBrand(brand);
return this;
}
public Navigator create(){
return mNavigator;
}
}
}
package cn.wsy.builder.simple.common;
/**
* 車輪實體類
* Created by wsy on 2016/2/17.
*/
public class Wheel {
private String brand;
private String weight;
public Wheel() {
}
public Wheel(String brand, String weight) {
this.brand = brand;
this.weight = weight;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getWeight() {
return weight;
}
public void setWeight(String weight) {
this.weight = weight;
}
@Override
public String toString() {
return "Wheel{" +
"brand='" + brand + '\'' +
", weight='" + weight + '\'' +
'}';
}
public static class WheelBuilder{
private Wheel mWhell = new Wheel();
private String brand;
private String weight;
public WheelBuilder setBrand(String brand) {
mWhell.setBrand(brand);
return this;
}
public WheelBuilder setWeight(String weight) {
mWhell.setWeight(weight);
return this;
}
public Wheel create(){
return mWhell;
}
}
}
(4)測試方法
這里我們通過對比傳統構造方法來對比Builder構造的優勢:
1.如果類奔馳車類構造對象的時候不需要導航儀類,傳統的構造方法需要定義多一個構造方法,具體如下:
public BenzCar(Engine mEngine, Wheel mWheel) {
super(mEngine, mWheel);
}
構造如下:
BenzCar car1 = new BenzCar(new Engine("321","321"),new Wheel("123","123"));
2.利用builder模式構造
//這種方式創建 可觀性清晰 構造器也可以減少
BenzBuilder builder = new BenzBuilder();//oncreate 可以拿到實體對象
BenzCar car = (BenzCar) builder
.builderEngine(new Engine.EngineBuilder().setBrand("brand").create())
.builderNavigator(new Navigator.NavigatorBuilder().setPrice("price").create())
.onCreate()
;Log.i(TAG, car.toString());
這樣是不是更加清晰!需求改動、最初類屬性沒有修改的時候,可以直接不用修改類的構造方法,維護性更高!但是這種方式會嚴重增加的代碼量,所以各有優缺點!!
傻小孩b
20160217