構(gòu)造者模式的定義
是指將一個(gè)復(fù)雜對象的構(gòu)造與它的表示分離白热,使同樣的構(gòu)建過程可以創(chuàng)建不同的表示,這樣的設(shè)計(jì)模式被稱為建造者模式东帅。
通俗的說,假如你要創(chuàng)建一個(gè)人類的對象,那么各個(gè)實(shí)例的屬性不同,也就是人的高矮胖瘦不一樣.這個(gè)時(shí)候可以考慮用構(gòu)造者模式.
構(gòu)造者模式的角色分類
- 具體的產(chǎn)品(要建造的東西)
- 抽象構(gòu)造者,一個(gè)包含創(chuàng)建產(chǎn)品各個(gè)子部件的抽象方法的接口,還要包含一個(gè)返回產(chǎn)品的方法.
- 具體構(gòu)造者,實(shí)現(xiàn)了抽象構(gòu)造者,重新其中的抽象方法.
- 指揮官,用來指揮如何生成產(chǎn)品.
構(gòu)造者模式的兩種分類
構(gòu)造者模式一共有四個(gè)角色,如果省掉其中的指揮者和抽象構(gòu)造者,只有一個(gè)具體的構(gòu)造者,那么久是簡單的構(gòu)造者模式.
正常構(gòu)造者模式
1,
假如我們要創(chuàng)建人類這個(gè)種產(chǎn)品.屬性有很多,我們隨意選幾個(gè)來做演示. 產(chǎn)品的信息如下:
public class Person {
private String eyes; //眼睛
private String mouth; //嘴
private String legs; //腿
// 省略get和set方法
}
2,
抽象構(gòu)造者,在這個(gè)抽象的類中,定義一些要用的方法
/**
* 抽象構(gòu)造者
*/
public abstract class AbstractBuilder {
//創(chuàng)建人類對象(產(chǎn)品)
protected Person person = new Person();
public abstract void buildEyes();
public abstract void buildMouth();
public abstract void buildLegs();
//返回對象
public Person getPerson(){
return person;
}
}
3,
具體構(gòu)造者
/**
* 具體構(gòu)造者
*/
public class GirlPerson extends AbstractPersonBuilder {
@Override
public void buildEyes() {
person.setEyes("大眼睛");
}
@Override
public void buildMouth() {
person.setMouth("小嘴巴");
}
@Override
public void buildLegs() {
person.setLegs("大長腿");
}
}
4,
指揮者
/**
* 指揮者
*/
public class Director {
//抽象構(gòu)造者
private AbstractPersonBuilder abstractPersonBuilder;
public Director(AbstractPersonBuilder abstractPersonBuilder) {
this.abstractPersonBuilder = abstractPersonBuilder;
}
//開始建造
public Person instance(){
abstractPersonBuilder.buildEyes();
abstractPersonBuilder.buildMouth();
abstractPersonBuilder.buildLegs();
return abstractPersonBuilder.getPerson();
}
}
5,
測試類
public static void main(String[] args) {
GirlPerson girlPerson = new GirlPerson();
Director director = new Director(girlPerson);
Person instance = director.instance();
System.out.println(instance.toString());
//log輸出
//Person{eyes='大眼睛', mouth='小嘴巴', legs='大長腿'}
}
也許到這里大家還沒有看出來,這么復(fù)雜的寫,有什么好處呢?
建造者(Builder)模式創(chuàng)建的是復(fù)雜對象抗俄,其產(chǎn)品的各個(gè)部分經(jīng)常面臨著劇烈的變化,但將它們組合在一起的算法卻相對穩(wěn)定音榜,所以它通常在以下場合使用。
- 創(chuàng)建的對象較復(fù)雜捧弃,由多個(gè)部件構(gòu)成赠叼,各部件面臨著復(fù)雜的變化擦囊,但構(gòu)件間的建造順序是穩(wěn)定的。
- 創(chuàng)建復(fù)雜對象的算法獨(dú)立于該對象的組成部分以及它們的裝配方式嘴办,即產(chǎn)品的構(gòu)建過程和最終的表示是獨(dú)立的瞬场。
假如我們現(xiàn)在需要重新添加一個(gè)男人的對象.那么只需要新建一個(gè)類繼承抽象構(gòu)造者即可.越是復(fù)雜的對象,用構(gòu)造模模式創(chuàng)建會很舒服.簡單的對象就算了.
簡單構(gòu)造者模式
這個(gè)構(gòu)造模式是除去了指揮者和抽象構(gòu)造者而產(chǎn)生的.
它的作用在于可以在創(chuàng)建對象的時(shí)候,可以通過內(nèi)類的一個(gè)構(gòu)造者.來靈活的創(chuàng)建.
public class User{
String name;
int age;
String email;
String address;
public User(){
}
//想要有名字和郵箱的構(gòu)造器
public User(String name, String email){
this.name = name;
this.email = email;
}
//想要有名字和地址的構(gòu)造器
public User(String name, String address){
this.name = name;
this.address = address;
}
}
在上面代碼中,很容易可以發(fā)現(xiàn)涧郊,在我們正常的需求下贯被,Java構(gòu)造器的編寫將會出問題,由于參數(shù)個(gè)數(shù)和類型一樣無法構(gòu)成重載底燎,所以這樣寫是不行的刃榨,那么Builder模式就是為了解決這種情況而出現(xiàn)的弹砚。
Builder模式的實(shí)現(xiàn)
下面我們一起來看一下Builder模式如何編寫的
public class User {
String name;
int age;
String phone;
String email;
String address;
//注意無參構(gòu)造器私有双仍,避免外界使用構(gòu)造器創(chuàng)建User對象
private User() {
}
@Override
public String toString() {
return "User [name=" + name + ", age=" + age + ", phone=" + phone + ",
email=" + email + ", address=" + address
+ "]";
}
public static class Builder {
private String name;
private int age;
private String phone;
private String email;
private String address;
public Builder() {
}
public Builder setName(String name) {
this.name = name;
return this;
}
public Builder setAge(int age) {
this.age = age;
return this;
}
public Builder setPhone(String phone) {
this.phone = phone;
return this;
}
public Builder setEmail(String email) {
this.email = email;
return this;
}
public Builder setAddress(String address) {
this.address = address;
return this;
}
public User build() {
User user = new User();
user.name = name;
user.age = age;
user.email = email;
user.phone = phone;
user.address = address;
return user;
}
}
}
根據(jù)上面的代碼,我們可以看出來桌吃,就是在User內(nèi)部創(chuàng)建一個(gè)內(nèi)部類朱沃,并且擁有和User一樣的字段(屬性),并且提供SET方法茅诱,最重要的是要提供一個(gè)能夠返回User對象的方法(build)逗物,這樣才能通過Builder來創(chuàng)建User對象。
Builder設(shè)計(jì)模式還有一個(gè)好處瑟俭,那便是我們可以隨意組合輸入的參數(shù)翎卓,不僅避免了重載出錯(cuò)的問題,還不需要寫過多的構(gòu)造器摆寄。
下面我們一起看看寫完Builder模式類之后如何來調(diào)用:
public class UserTest {
public static void main(String[] args) {
User u = new User.Builder().setName("bob").setAge(22).build();
System.out.println(u);
}
}