创建者模式一般用于,当一个类的内部数据过于复杂的时候(比如各个属性在设置值的什么要写一大坨代码才可以完成),并且还创建这样的对象不是一个,而是根据不同场景创建多种,并且属性类型基本一样,这个时候就想啊想一种什么法子来管理一下这个类中的数据呢,怎么在创建的时候让它按部就班的来,并且代码可读性很好别让我看花了眼啊,我要的东西也能都很好设置进来,这就是Builder模式的应用场景,Builder模式可以将一个类的构建和表示进行分离。
在看正文前我继续给大家模拟一个生活场景,通俗的为大家解释什么是创建者。
场景:一个暴发户找一家建筑设计公司设计一栋商业和一栋住宅,我们假设这是两个对象,商业和住宅都有相同的属性,比如材料、楼层、结构等,设计公司把图纸和需求给了施工单位,施工单位按照要求完成了施工,交给设计公司一栋商业和一栋住宅,设计公司很满意,把这两个对象交给了暴发户。不考虑实际情况,在上面的场景里,暴发户根本不用操心这个楼是哪个施工单位,那个工人一砖一瓦建成的,他只关注跟设计公司提的需求,设计公司就要满足他,所以该过程屏蔽了用户和建造过程的细节。
所以,我们总结出构建者模式
产品角色(Product):它是包含多个组成部件的复杂对象和属性,是一个模型。
抽象建造者(Builder):它是一个包含创建产品各个子部件的抽象方法的接口或者抽象类,通常还包含一个返回复杂产品的方法 ,该方法一般是抽象并且返回值类型是产品角色(Product)。
具体建造者(Concrete Builder):实现 Builder 接口或者继承Builder 抽象类,完成复杂产品的各个部件的具体创建方法。
指挥者(Director):它调用建造者(Builder)中的部件构造与装配方法完成复杂对象的创建,不设计产品具体构建细节。
产品角色(Product)
//实际是你想创建的对象
public class People {
//这个对象需要的属性,例如创建一个汽车,汽车有发动机,轮子,底盘等
private String head;
private String body;
private String hand;
private String foot;
public String getHead() {
return head;
}
public void setHead(String head) {
this.head = head;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public String getHand() {
return hand;
}
public void setHand(String hand) {
this.hand = hand;
}
public String getFoot() {
return foot;
}
public void setFoot(String foot) {
this.foot = foot;
}
@Override
public String toString() {
return "People{" +
"head='" + head + '\'' +
", body='" + body + '\'' +
", hand='" + hand + '\'' +
", foot='" + foot + '\'' +
'}';
}
抽象建造者(Builder)
public abstract class Builder {
abstract void buildHead();
abstract void buildBody();
abstract void buildHand();
abstract void buildFoot();
abstract People createPeople();
}
具体建造者(Concrete Builder)一
public class ManBuilder extends Builder {
private People people = new People();
void buildHead() {
people.setHead("男人的头");
}
void buildBody() {
people.setBody("男人的身体");
}
void buildHand() {
people.setHand("男人的手");
}
void buildFoot() {
people.setFoot("男人的脚");
}
People createPeople() {
return people;
}
}
具体建造者(Concrete Builder)二
public class WomanBuilder extends Builder {
//声明我们要构建的对象
private People people = new People();
//下面是对象里的属性,实际业务中就要在每个方法写逻辑,根据你当前要构建什么类,//去相应设置对象的各个属性。 //比如,该类构建的是一个女人,所以我把对象里的属性都设置与女人有关,//然后set到对象,最后通过createPeople 方法返回我构建的对象。 void buildHead() {
people.setHead("女人的头");
}
void buildBody() {
people.setBody("女人的身体");
}
void buildHand() {
people.setHand("女人的手");
}
void buildFoot() {
people.setFoot("女人的脚");
}
People createPeople() {
return people;
}
}
指挥者(Director)
public class Director {
private Builder builder;
public Director(Builder builder) {
this.builder = builder;
}
public People construct() {
builder.buildBody();
builder.buildFoot();
builder.buildHand();
builder.buildHead();
return builder.createPeople();
}
/**
* 放开下面的注释,使用测试类中注释的代码。
*/
// public Director() {
//
// }
//
// public People construct(Builder builder) {
// builder.buildBody();
// builder.buildFoot();
// builder.buildHand();
// builder.buildHead();
// return builder.createPeople();
// }
下面是 client 调用的方式
public class ClientTest {
public static void main(String[] args) {
/**
* 与设计者类同理,两种方法,注释与非注释方法任选
*/
// Director director = new Director();
// People people = director.construct(new ManBuilder());
// System.out.println(people.toString());
Director director = new Director(new ManBuilder());
People people = director.construct();
System.out.println(people.toString());
}
}
输出结果
下面是我代码结构图,需要的请加微信
总结:
使用建造者模式可以使客户端不必知道产品内部组成的细节。易于扩展具体建造者,并且具体建造者 之间没有依赖关系。但是缺点很明显,所有的具体建造者 都要用相同的 产品属性,要共用一个模型,想打破这一局面可以用工厂方法,或者使用抽象工厂,大家有没有发现工厂模式与建造者有些共性呢。
工厂模式链接:https://blog.csdn.net/weixin_38003389/article/details/87935107