學(xué)習(xí)《Android 源碼設(shè)計(jì)模式解析與實(shí)踐》系列筆記
介紹
Builder 模式是一步一步創(chuàng)建一個(gè)復(fù)雜對(duì)象的創(chuàng)建型模式更舞。用戶不需要知道構(gòu)建過程中的實(shí)現(xiàn)細(xì)節(jié)仇矾,便可構(gòu)建出復(fù)雜的對(duì)象模型。該模式將構(gòu)建復(fù)雜對(duì)象的過程和它的部件解耦拍棕,使得構(gòu)建過程和部件表示隔離開來晓铆。
定義
將一個(gè)復(fù)雜對(duì)象的構(gòu)建與它的表示分離,使得同樣的構(gòu)建過程可以構(gòu)建不同的表示绰播。
使用場景
- 相同的方法骄噪,不同的執(zhí)行順序,產(chǎn)生不同的時(shí)間結(jié)果時(shí)蠢箩。
- 多個(gè)部件或零件腰池,都可以裝配到一個(gè)對(duì)象中,但是產(chǎn)生的運(yùn)行結(jié)果又不同時(shí)忙芒。
- 產(chǎn)品類非常復(fù)雜,或者產(chǎn)品類中的調(diào)用順序不同產(chǎn)生了不同的作用讳侨,這個(gè)時(shí)候用建造者模式非常適合呵萨。
- 當(dāng)初始化一個(gè)對(duì)象特別復(fù)雜,如參數(shù)多跨跨,切很多參數(shù)都具有默認(rèn)值時(shí)潮峦。
結(jié)構(gòu)
- Product 產(chǎn)品類:產(chǎn)品的抽象類
- Builder :抽象 Builder 類,規(guī)范產(chǎn)品的組建
- ConcreteBuilder : 具體的 Builder 類
- Director : 統(tǒng)一組裝過程
使用
這里通過構(gòu)建一個(gè)學(xué)生舉例勇婴。
/**
* 人抽象類忱嘹,即 Product 角色
*/
public abstract class Person {
protected String name;
protected int sex;
protected int age;
protected String job;
public void setName(String name) {
this.name = name;
}
public void setSex(int sex) {
this.sex = sex;
}
public void setAge(int age) {
this.age = age;
}
public abstract void setJob();
}
/**
* 具體的 Person 類,Student
*/
public class Student extends Person {
public void setJob() {
job = "student";
}
}
/**
* 抽象的 Builder 類
*/
public abstract class Builder {
public abstract void buildName(String name);
public abstract void buildAge(int age);
public abstract void buildSex(int sex);
public abstract void buildJob();
public abstract Person create();
}
/**
* 具體的 Builder 類
*/
public class StudentBuilder extends Builder {
private Person mPerson = new Student();
@Override
public void buildName(String name) {
mPerson.setName(name);
}
@Override
public void buildAge(int age) {
mPerson.setAge(age);
}
@Override
public void buildSex(int sex) {
mPerson.setSex(sex);
}
@Override
public void buildJob() {
mPerson.setJob();
}
@Override
public Person create() {
return mPerson;
}
}
/**
* Director 類耕渴,負(fù)責(zé)構(gòu)造 Person
*/
public class Director {
private Builder mBuilder;
public Director(Builder builder) {
mBuilder = builder;
}
public void construct(String name, int age, int sex) {
mBuilder.buildJob();
mBuilder.buildName(name);
mBuilder.buildAge(age);
mBuilder.buildSex(sex);
}
}
public class User {
public static void main(String [] args) {
Builder builder = new StudentBuilder();
Director director = new Director(builder);
director.construct("Lynn", 18, 1);
// 拿到構(gòu)建的 Student 對(duì)象
Person studentLynn = builder.create();
}
}
上面的例子中拘悦,通過具體的 StudentBuilder
來構(gòu)建 Student
對(duì)象,Director
封裝了構(gòu)建產(chǎn)品對(duì)象的過程橱脸,對(duì)外隱藏了細(xì)節(jié)础米。Builder
和 Director
將對(duì)象的構(gòu)建與它的表示分離,使得同樣的構(gòu)建過程可以構(gòu)建不同的對(duì)象添诉。
但是屁桑,前面說到的都是傳統(tǒng)的 Builder
模式,實(shí)際開發(fā)中栏赴,經(jīng)常會(huì)省略掉 Director
對(duì)象蘑斧,直接使用一個(gè)內(nèi)部類 Builder
來處理對(duì)象的組裝,這個(gè) Builder
通常為鏈?zhǔn)秸{(diào)用的,它的每個(gè) setter
方法都會(huì)返回自己竖瘾。沒有 Director
的角色會(huì)使結(jié)構(gòu)更加的簡潔沟突。
簡化的 Builder
還是用的上面的例子,不過上面的代碼只沿用了 Person
類准浴。
/**
* 人抽象類事扭,即 Product 角色
*/
public abstract class Person {
protected String name;
protected int sex;
protected int age;
protected String job;
public void setName(String name) {
this.name = name;
}
public void setSex(int sex) {
this.sex = sex;
}
public void setAge(int age) {
this.age = age;
}
public abstract void setJob();
}
public class Student2 extends Person {
public Student2(Builder builder) {
name = builder.name;
sex = builder.sex;
age = builder.age;
setJob();
}
@Override
public void setJob() {
job = "student";
}
public static class Builder {
private String name;
private int sex;
private int age;
public Builder(String name) {
this.name = name;
}
public Builder setSex(int sex) {
this.sex = sex;
return this;
}
public Builder setAge(int age) {
this.age = age;
return this;
}
public Student2 create() {
return new Student2(this);
}
}
}
public class User {
public static void main(String [] args) {
Student2.Builder builder = new Student2.Builder("Lynn");
builder.setAge(20).setSex(1);
// 拿到構(gòu)建的 Student 對(duì)象
Person studentLynn = builder.create();
}
}
可以看到,去掉了 Director
后乐横,結(jié)構(gòu)變得更加簡單明了了求橄。
更多的例子,可以參考 Android
源碼中的 AlertDialog
類葡公,這個(gè)應(yīng)該是最常見的一個(gè)應(yīng)用了罐农。
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setIcon(R.mipmap.ic_launcher)
.setTitle("Title")
.setMessage("Message");
Dialog dialog = alertDialogBuilder.create();
dialog.show();
總結(jié)
Builder
模式在開發(fā)中較為常用,可以使構(gòu)建和表示分離催什。
優(yōu)缺點(diǎn)
- 優(yōu)點(diǎn)
(1)良好的封裝性涵亏,使用構(gòu)造者模式可以使客戶端不必知道產(chǎn)品內(nèi)部組成的細(xì)節(jié)。
(2)構(gòu)造者獨(dú)立蒲凶,容易擴(kuò)展气筋。 - 缺點(diǎn)
(1)會(huì)產(chǎn)生對(duì)于的Builder
對(duì)象,消耗內(nèi)存旋圆。
(2)Builder
類可能會(huì)復(fù)制一遍Product
的屬性宠默,代碼量會(huì)增多。
注意:
- 必需的參數(shù)灵巧,應(yīng)該放在
Builder
的構(gòu)造方法中搀矫; -
create
之后拿到的對(duì)象,其屬性應(yīng)不再改變刻肄。
相關(guān)文章:
設(shè)計(jì)模式整理(1) 代理模式
設(shè)計(jì)模式整理(2) 單例模式
設(shè)計(jì)模式整理(3) Builder 模式
設(shè)計(jì)模式整理(4) 原型模式
設(shè)計(jì)模式整理(5) 工廠模式
設(shè)計(jì)模式整理(6) 策略模式
設(shè)計(jì)模式整理(7) 狀態(tài)模式
設(shè)計(jì)模式整理(8) 責(zé)任鏈模式
設(shè)計(jì)模式整理(9) 觀察者模式
設(shè)計(jì)模式整理(10) 適配器模式
設(shè)計(jì)模式整理(11) 裝飾模式
設(shè)計(jì)模式整理(12) 中介者模式