定义及应用场景
建造者模式(Builder Pattern)指的是将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。属于创建型模式。应用场景如下:
- 当初始化一个对象的参数特别多时可以考虑使用建造者模式。
- 当产品类的调用顺序不同能产生不同的作用。
建造者模式中的4个角色:
- 产品(Product):需要创建的产品类对象
- 建造者抽象(Builder):建造者的抽象(有时会是接口),规范产品对象的各个组成部分的建造,其中会包含一个用来返回最终产品的方法,Product build()。
- 建造者(ConcreteBuilder):具体的实现类,根据业务逻辑具体化对象的各个组成部分。
- 调用者(Director):调用具体的建造者,负责最终产品的创建。
建造者模式的基本(传统)写法
产品Product
public class House {
private String floor;//必选
private String wallpaper;//必选
private String bed;//必选
private String tv;
private String airConditioning;
public House() {
}
public House(String floor, String wallpaper, String bed) {
this.floor = floor;
this.wallpaper = wallpaper;
this.bed = bed;
}
@Override
public String toString() {
return "House{" +
"floor='" + floor + '\'' +
", wallpaper='" + wallpaper + '\'' +
", bed=" + bed +
", tv='" + tv + '\'' +
", airConditioning='" + airConditioning + '\'' +
'}';
}
public String getFloor() {
return floor;
}
public void setFloor(String floor) {
this.floor = floor;
}
public String getWallpaper() {
return wallpaper;
}
public void setWallpaper(String wallpaper) {
this.wallpaper = wallpaper;
}
public String getBed() {
return bed;
}
public void setBed(String bed) {
this.bed = bed;
}
public String getTv() {
return tv;
}
public void setTv(String tv) {
this.tv = tv;
}
public String getAirConditioning() {
return airConditioning;
}
public void setAirConditioning(String airConditioning) {
this.airConditioning = airConditioning;
}
}
建造者抽象Builder
public abstract class HouseBuilder {
public abstract void setTv();
public abstract void setAirConditioning();
public abstract House getHouse();
}
建造者(ConcreteBuilder) 海尔建造者,格力建造者
public class HaierHouseBuilder extends HouseBuilder{
private House house;
public HaierHouseBuilder(String floor, String wallpaper, String bed) {
this.house = new House(floor, wallpaper, bed);
}
@Override
public void setTv() {
house.setTv("海尔电视");
}
@Override
public void setAirConditioning() {
house.setAirConditioning("海尔空调");
}
@Override
public House getHouse() {
return house;
}
}
public class GeliHouseBuilder extends HouseBuilder{
private House house;
public GeliHouseBuilder(String floor, String wallpaper, String bed) {
this.house = new House(floor, wallpaper, bed);
}
@Override
public void setTv() {
house.setTv("格力电视");
}
@Override
public void setAirConditioning() {
house.setAirConditioning("格力空调");
}
@Override
public House getHouse() {
return house;
}
}
调用者(Director)
public class HouseDirector {
public void makeHouse(HouseBuilder builder) {
builder.setTv();
builder.setAirConditioning();
}
}
public class Test {
public static void main(String[] args) {
HouseDirector director = new HouseDirector();
GeliHouseBuilder geliHouseBuilder = new GeliHouseBuilder("瓷砖", "灰色壁纸", "1.8米床");
director.makeHouse(geliHouseBuilder);
House geliHouse = geliHouseBuilder.getHouse();
System.out.println("geliHouse: " + geliHouse.toString());
HaierHouseBuilder haierHouseBuilder = new HaierHouseBuilder("木地板", "粉色色壁纸", "1.5米床");
director.makeHouse(haierHouseBuilder);
House haierHouse = haierHouseBuilder.getHouse();
System.out.println("haierHouse: " + haierHouse.toString());
}
}
输出:
geliHouse: House{floor=‘瓷砖’, wallpaper=‘灰色壁纸’, bed=1.8米床, tv=‘格力电视’, airConditioning=‘格力空调’}
haierHouse: House{floor=‘木地板’, wallpaper=‘粉色色壁纸’, bed=1.5米床, tv=‘海尔电视’, airConditioning=‘海尔空调’}
建造者模式的链式写法
将house变成HouseBuilder的内部类,每完成一个都返回this
public class HouseChainBuilder {
private House house = new House();
public HouseChainBuilder addTv(String tv) {
house.setTv(tv);
return this;
}
public HouseChainBuilder addAirConditioning(String airConditioning) {
house.setAirConditioning(airConditioning);
return this;
}
public House builder() {
return this.house;
}
public class House{
private String floor;//必选
private String wallpaper;//必选
private String bed;//必选
private String tv;
private String airConditioning;
@Override
public String toString() {
return "House{" +
"floor='" + floor + '\'' +
", wallpaper='" + wallpaper + '\'' +
", bed=" + bed +
", tv='" + tv + '\'' +
", airConditioning='" + airConditioning + '\'' +
'}';
}
public String getFloor() {
return floor;
}
public void setFloor(String floor) {
this.floor = floor;
}
public String getWallpaper() {
return wallpaper;
}
public void setWallpaper(String wallpaper) {
this.wallpaper = wallpaper;
}
public String getBed() {
return bed;
}
public void setBed(String bed) {
this.bed = bed;
}
public String getTv() {
return tv;
}
public void setTv(String tv) {
this.tv = tv;
}
public String getAirConditioning() {
return airConditioning;
}
public void setAirConditioning(String airConditioning) {
this.airConditioning = airConditioning;
}
}
}
public class TestChain {
public static void main(String[] args) {
HouseChainBuilder chainBuilder = new HouseChainBuilder()
.addTv("小米电视").addAirConditioning("小米空调");
System.out.println(chainBuilder.builder());
}
}
输出
House{floor=‘null’, wallpaper=‘null’, bed=null, tv=‘小米电视’, airConditioning=‘小米空调’}
建造模式在jdk中的使用
StringBuilder提供的append()方法
建造者模式的优缺点
优点
1、封装性好,创建与使用分离
2、扩展性好,建造者类之间独立。
缺点
1、增加类的复杂度,产生了多余的Builder对象
2、产品发生改变,建造者都要修改成本大。