【設(shè)計模式】這是我讀過講解建造者模式最易懂的文章
建造者模式介紹
概述
在我們工作中常常會出現(xiàn)建造者模式的身影,它是一種比較常用的創(chuàng)建型設(shè)計模式。建造者模式的原理和代碼實現(xiàn)非常簡單,掌握起來并不難。
使用場景
當(dāng)一個類的構(gòu)造函數(shù)參數(shù)有多個,而且這些參數(shù)有些是可選的參數(shù),就可以考慮使用建造者模式了。
還是看一個場景,我們現(xiàn)在有如下一個雇員類:
class Employee{
private String name; //名字,必須
private int age; //年齡,必須
private String sex; //性別,可選
private String country; //國家,可選
}在實例化對象時其中name和age是必填參數(shù),而sex和country是可選參數(shù),那么我們?nèi)绾螛?gòu)造這個類的實例呢,通常有兩種方式:
1. 折疊構(gòu)造函數(shù)模式
class Employee{
...........
..........
public Employee(String name, int age){
this(name, age, "男");
}
public Employee(String name, int age, String sex){
this(name, age, sex, "中國");
}
public Employee(String name, int age, String sex, String country){
this.name = name;
this.age = age;
this.sex = sex;
this.country = country;
}
}通過這種方式,我們可以根據(jù)需要,選擇不同形式的構(gòu)造函數(shù)創(chuàng)建對象。
2. 屬性設(shè)置模式:
class Employee{
...........
..........
public Employee(){
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setSex(String sex) {
this.sex = sex;
}
public void setCountry(String country) {
this.country = country;
}
}
//使用
public static void main(String[] args) {
Employee employee = new Employee();
employee.setName("宋江"); //還有屬性 沒有設(shè)置,對象還處于無效狀態(tài)
employee.setAge(66); //還有屬性 沒有設(shè)置,對象還處于無效狀態(tài)
employee.setSex("男"); //還有屬性 沒有設(shè)置,對象還處于無效狀態(tài)
employee.setCountry("大宋"); //所有屬性設(shè)置完成,對象可用了
System.out.println(employee);
}
******************【運(yùn)行結(jié)果】******************
Employee{name='宋江', age=66, sex='男', country='大宋'}兩種方式都能創(chuàng)建出你想要的對象,但是兩種方式都有其弊端:
? 1.第一種方式在構(gòu)建對象調(diào)用構(gòu)造函數(shù)時,你首先要決定使用哪一個構(gòu)造函數(shù),當(dāng)可選參數(shù)很多的時候,你就要非常清楚這些參數(shù)的含義,否則很容易就傳混了。
? 2.第二種方式在構(gòu)建對象的過程中,對象的屬性是分步設(shè)置的,會出現(xiàn)無效狀態(tài),容易出錯。
正是因為前面兩種方式都有其不足之處,所以就出現(xiàn)了建造者模式。
建造者模式實現(xiàn)
建造者模式實現(xiàn)
以上面的業(yè)務(wù)場景為例,可以按照下面的方式寫出對應(yīng)的建造者模式的代碼。
class Employee{
private String name;
private int age;
private String sex; //性別,可選
private String country; //國家,可選
//在Employee中創(chuàng)建一個private的構(gòu)造函數(shù),參數(shù)為Builder類型
private Employee(Builder builder){
this.name = builder.name;
this.age = builder.age;
this.sex = builder.sex;
this.country = builder.country;
}
//2.在Employee創(chuàng)建靜態(tài)內(nèi)部類Builder,將Employee的成員變量復(fù)制到Builder類中
public static class Builder{
private String name;
private int age;
private String sex; //性別,可選
private String country; //國家,可選
//3.在Builder中創(chuàng)建一個public的構(gòu)造函數(shù),參數(shù)為必填的那些參數(shù),name 和age。
public Builder(String name, int age){
this.name = name;
this.age = age;
}
//4.在Builder中創(chuàng)建設(shè)置函數(shù),對那些可選參數(shù)進(jìn)行賦值,返回值為Builder類型的實例
public Builder setSex(String sex){
this.sex = sex;
return this;
}
public Builder setCountry(String country){
this.country = country;
return this;
}
//在Builder中創(chuàng)建一個build()方法,在其中構(gòu)建Employee的實例并返回
public Employee build(){
return new Employee(this);
}
}
@Override
public String toString() {
return "Employee{" +
"name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
", country='" + country + '\'' +
'}';
}
}
public class BuilderExample {
public static void main(String[] args) {
//使用建造者模式將對象一步步創(chuàng)建出來
Employee employee = new Employee.Builder("李世民", 55)
.setSex("男")
.setCountry("唐朝")
.build();
System.out.println(employee);
}
}
******************【運(yùn)行結(jié)果】******************
Employee{name='李世民', age=55, sex='男', country='唐朝'}
可用看出,建造者模式很好的解決了前面兩種方式存在的問題,所以如果一個類的構(gòu)造函數(shù)可選參數(shù)過多,我們就需要考慮使用建造者模式,先設(shè)置建造者的變量,然后再一次性地創(chuàng)建對象。
本文源碼地址:
https://github.com/qinlizhong1/javaStudy/tree/master/DesignPattern/src/factory
本文示例代碼環(huán)境:
操作系統(tǒng):macOs 12.1
JDK版本:12.0.1
maven版本: 3.8.4
— 完 —
