建造者模式
建造者模式:使用多个简单的对象一步一步的构成一个复杂的对象。其实生活中比比皆是建造者模式,学习也一样,需要你一步一步来。
我们什么时候使用建造者模式呢?需要他的时候吧!
1.我们有多个部件,需要去组装的时候,而且是要按先后顺序去的(得到的结果不是同时的);
2.产品结构较为复杂,组装顺序或者使用的部件不同,会产生不同的结果的;
3.初始化的对象需要的参数多时,而且很多参数具有默认值;
?:蛋炒饭的制作:油 —> 搅匀的蛋 —> 饭 —> ?(我是这样做的,每个人的方法不同,所以照成的结果是不一样的,而且你是按照自己的步骤做的,是串行的去执行的,你肯定不会准备好所有材料,一起放下去吧!而且有些人喜欢吃淀粉,可以再加一点火腿肠)
总结就是按自己的想法去准备食材(参数多,有默认值),自己的想法去做(顺序不同,使用部件不同),开始做(串行的做),得到一份蛋炒饭或黑暗料理(结果不同)。
ps:放点酱油颜色会好看点,味道也会更好。
建造者模式与工厂模式可以结合使用,建造者模式注重部件的组装过程,而工厂方法模式注重的是结果。
一个建造者模式包含了以下4个角色:
- 产品:包含了多个部件的复杂对象(产品:蛋炒饭,部件:材料)
- 抽象建造者:提供创建各个子部件的抽象方法的接口(菜谱,可能是祖传秘方)
- 具体建造者:抽象建造者的实现,完成产品创建的具体方法(实践:开火做饭,放油,放盐操作)
- 实践者:根据建造者对象的构建方法(抽象建造者:菜谱)完成复杂对象的装配,实践者不涉及产品的具体信息(实践者:你,材料都是从冰箱里拿的,你不知道你妈从哪买的,多少钱等。在正规饭店里就是厨子的角色)。
代码:
1.产品(product)
public class EggRice {
private int egg;
private double oil;
private double salt;
private int rice;
private double lgm;
public void setEgg(int egg) {
this.egg += egg;
}
public void setOil(double oil) {
this.oil += oil;
}
public void setSalt(double salt) {
this.salt += salt;
}
public void setRice(int rice) {
this.rice += rice;
}
public void setLgm(double lgm) {
this.lgm += lgm;
}
public String show(){
if(lgm > 0) {
return "获得老干妈蛋炒饭:鸡蛋:"+egg+"个\n"
+"油:"+ oil + "g\n"
+"盐:"+ salt + "g\n"
+"米饭:"+ rice + "份\n"
+"老干妈:"+ lgm + "g\n";
}else {
return "获得普通蛋炒饭:鸡蛋:"+egg+"个\n"
+"油:"+ oil + "g\n"
+"盐:"+ salt + "g\n"
+"米饭:"+ rice + "份\n";
}
}
}
2.抽象建造者 (AbstractBuilder)
abstract public class Builder {
public abstract Builder addEgg(int egg);
public abstract Builder addOil(double oil);
public abstract Builder addSalt(double salt);
public abstract Builder addRice(int rice);
public abstract Builder addLgm(double lgm);
protected abstract EggRice makeRice();
}
3.具体建造者(ConcreteBuilder)
public class ConcreteBuilder extends Builder{
//创建eggRice对象
protected EggRice eggRice = new EggRice();
@Override
public Builder addEgg(int egg) {
eggRice.setEgg(egg);
return this;
}
@Override
public Builder addOil(double oil) {
eggRice.setOil(oil);
return this;
}
@Override
public Builder addSalt(double salt) {
eggRice.setSalt(salt);
return this;
}
@Override
public Builder addRice(int rice) {
eggRice.setRice(rice);
return this;
}
@Override
public Builder addLgm(double lgm) {
eggRice.setLgm(lgm);
return this;
}
public EggRice makeRice() {
return eggRice;
}
}
4.实践者(Director)我就直接在这测试输出了
public class Director {
static Builder builder = new ConcreteBuilder();
public static void main(String args[]) {
EggRice eggRice = builder.addEgg(2) //两个鸡蛋
.addSalt(1.5) //加1.5g盐,搅拌
.addOil(100.5) //加100.5g油,先炒熟鸡蛋
.addRice(1) //加如一人份米饭
.addSalt(8) //再加入8g盐,翻炒均匀
.makeRice(); //出锅
System.out.println(eggRice.show());
}
}
实验结果:
在bundler的操作中我返回的是bundler对象,这样就可以流式的去操作,串行的去执行,这与我们日常生活中做事是一样的,让代码美观易读。
我没有进行一些判断,其实应该在调用各个方法的时候是应该加一些相应的方法的,我就简单的判断了是否加了老干妈。(真实生活中,不同的操作顺序和组合是会产生不同的结果的,本例中没有进行操作的判断。大家可以自己脑补下,比如1个?+1斤?会产生什么样的美食。)