Builder模式
</br>
前言
从今年的6月份开始毕业,到现在,回想到自己看的第三方框架时候,大多数都会有这样一连串的链式代码:
Glide.with(this).
load(url).
asBitmap().
into(targetView);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://www.jianshu.com/users/0e5afd21b574/latest_articles")
.addConverterFactory(GsonConverterFactory.create())
.client(new OkHttpClient())
.build();
看了上面的链式的,当时觉得如果学会这种模式并应用到自己的项目代码上,必定是一件高端大气上档次的事。
现在,对于Builder模式,网上也有好多大神们的demo,他们都有自己的看法。在此,我只想弱弱地说下我对这个模式的看法。(下面我将用一个形象生动的故事来说下对这个模式的看法,并且分析这个故事,再对Builder模式下定义,能在什么情况运用)</br>
小菜与苍老师的demo
(高能预警:下面内容与标题没有什么联系,只是让大家提高一下兴趣心,不过,相信你们也是纯洁的,好了,入主题。>_<)</br>
想想到现在,小菜和苍老师在一起生活了许久,突然决定要做一个蛋糕,然后去百度搜了一下做蛋糕,所需要的简略材料:水,鸡蛋,面粉(不要纠结做蛋糕的材料,就三个就好,你们懂的,我懒,想少打代码,嘻嘻)。好了,材料他们已经准备好了,接着他们看了一下做蛋糕的秘诀——水量water,鸡蛋数egg,面粉量flour,还有一个烘烤蛋糕的时间time。
他们蛋糕的做法是:
1、水:1瓢水
2、鸡蛋:1个
3、面粉:1斤
4、烧烤时间 :1h</br>
代码如果下:
/**
* Created by Jenchar on 2016/8/4.
*/
public class Cake {
private int water;
private int egg;
private int flour;
private int time;
public Cake(int water, int egg, int flour, int time) {
this.water = water;
this.egg = egg;
this.flour = flour;
this.time = time;
}
public Cake() {
}
public int getWater() {
return water;
}
public void setWater(int water) {
this.water = water;
}
public int getEgg() {
return egg;
}
public void setEgg(int egg) {
this.egg = egg;
}
public int getFlour() {
return flour;
}
public void setFlour(int flour) {
this.flour = flour;
}
public int getTime() {
return time;
}
public void setTime(int time) {
this.time = time;
}
@Override
public String toString() {
return "Cake{" +
"water=" + water +
", egg=" + egg +
", flour=" + flour +
", time=" + time +
'}';
}
}
Enter.java:
public class Enter {
public static void main(String[] args) {
Cake cake=new Cake(1,1,1,1);
}
}
结果他们尝了下做出来蛋糕,发现不好吃,这下子苍老师极为不开心,然后几天都没“理过他了”(自己理会)。小菜,为了为苍老师吃上好吃的蛋糕,找了一个蛋糕师父。
改善的蛋糕做法
/**
* Created by Jenchar on 2016/8/4.
*/
/**
* Created by Jenchar on 2016/8/4.
*/
public class Cake {
private int water;
private int egg;
private int flour;
private int time;
/**
* 高级蛋糕师父
*/
public static class CakeBuilder{
private int water;
private int egg;
private int flour;
private int time;
public CakeBuilder() {
}
public CakeBuilder setWater(int water){
this.water=water;
//返回当前CakeBuilder实例
return this;
}
public CakeBuilder setEgg(int egg){
this.egg=egg;
//返回当前CakeBuilder实例
return this;
}
public CakeBuilder setFlour(int flour){
this.flour=flour;
//返回当前CakeBuilder实例
return this;
}
public CakeBuilder setTime(int time){
this.time=time;
//返回当前CakeBuilder实例
return this;
}
//高级蛋糕师父根据自己的材料分量,直接帮你做出一个好吃的蛋糕
public Cake builer(){
return new Cake(this);
}
}
/**
* 蛋糕的构造方法
* @param mCakeBuilder 蛋糕的材料分量
*/
public Cake(CakeBuilder mCakeBuilder) {
this.water = mCakeBuilder.water;
this.egg = mCakeBuilder.egg;
this.flour = mCakeBuilder.flour;
this.time = mCakeBuilder.time;
}
/**
* 只能通过高级蛋糕师父的指定蛋糕材料分量来做蛋糕,即pulbic Cake(CakeBuilder mCakeBuilder),
* 不让其他非专业人士,直接做蛋糕给客户吃
*/
private Cake(){
}
}
Enter.java:
public class Enter {
public static void main(String[] args) {
Cake.CakeBuilder
cakeBuilder=new Cake.CakeBuilder().
setWater(1).
setEgg(2).
setFlour(1).
setTime(1);
Cake cake=new Cake(cakeBuilder);
/*Cake cake=new Cake.CakeBuilder().
setWater(1).
setEgg(2).
setFlout(1).
setTime(1).builer();*/
}
}
从此小菜与苍老师因为吃上好吃的蛋糕,再次过上了幸福的生活。
小结
看上面Enter.java类,做蛋糕师父(CakeBuilder)把做蛋糕的材料分量,water=1,egg=2,flour=1,time=1,传送Cake的构造方法,然后,这个蛋糕因为比小菜与苍老师的egg=1多放了一个,变得好吃了。看看!!放的量,小菜与苍老师是不知道的,假设蛋糕师父不放水,water=0:
Cake.CakeBuilder
cakeBuilder=new Cake.CakeBuilder().
setEgg(2).//没放水了
setFlour(1).
setTime(1);
再看看,相比上面的小菜与苍老师做的蛋糕 ,Cake cake=new Cake(1,1,1,1),构造过程一下就给人知道你想做什么了,而且这个构造方法写死,没有灵活之分,而蛋糕大师的做法,想放水,就放水,想不放,就可以修改不放,其他材料分量也是一样。</br>
定义
复杂的对象的构建(想下蛋糕的构建new Cake(1,1,1,1))与它的表示分离(new Cake.CakeBuilder().setWater(1).setEgg(2).setFlout(1).setTime(1).builer(),即分离了,想放水就放水)。</br>
使用情景
1、当初始化一个对象特别复杂,如参数多,且很多参数都具有默认值的时。(上面的蛋糕师父CakeBuilder里面可以设置默认值,不设就全部为0)</br>
2、当一个类的构建,想隐藏的构建细节。</br>
3、相同的方法,不同的执行顺序,产生不同的事件结果。(上面的例子,没有体现出来,你可以这样想,隐藏了构建的细节,从而你无法知道结果如何,所以产生了不同的事件结果)</br>
喜欢我的朋友,可以与我一起讨论问题,我也是学习者,希望与大学一起学习,共同进步。