Android设计模式-Builder模式(建造者模式)

概述

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

举个栗子

下面以宠物医院记录宠物狗信息为例

//汪汪信息类
public class Dog{   
    private int identifier;//编号
    private String name;//名字
    private int age;//年龄
    private int weight;//体重
    private String breed;//品种
    private boolean gender;//性别,true:公狗;false:母狗
    private String sickness;//疾病

    public void setIdentifier(int identifier){
         this.identifier=identifier;
    }

     public void setName(String name){
         this.name=name;
    }

     public void setAge(int age){
         this.age=age;
    }

     public void setWeight(int weight){
         this.weight=weight;
    }

     public void setBreed(int breed){
         this.breed=breed;
    }

     public void setGender(boolean gender){
         this.gender=gender;
    }
    public void setSickness(String sickness){
         this.sickness=sickness;
    }
}

初始化,赋值:

//一只新的汪进来了
Dog dog=new Dog;
dog.setIdentifier(2222);//因为是一只二哈,2炸了
dog.setName("sijia");//撕家小能手呀
dog.setAge(3);
dog.setWeight(20);
dog.setBreed("Husky");
dog.setGender(true);
dog.setSickness("doubi");//这只哈士奇太逗逼了,还能治吗?

终于搞定了,有没有觉得赋值很麻烦,那有没有简洁点的方式,有的。在Dog类中增加新的方法:

public void setDogInfo(int identifier,int String name,int age,int weight,String breed,boolean gender,String sickness){
    this.identifier=identifier;
    this.name=name;
    this.age=age;
    this.weight=weight;
    this.breed=breed;
    this.gender=gender;
    this.sickness=sickness;
}

或者新增构造方法:

public setDogInfo(int identifier,String name,int age,int weight,String breed,boolean gender,String sickness){
    this.identifier=identifier;
    this.name=name;
    this.age=age;
    this.weight=weight;
    this.breed=breed;
    this.gender=gender;
    this.sickness=sickness;
}

public setDogInfo(int identifier,String name){
    this.identifier=identifier;
    this.name=name;
}

public setDogInfo(int identifier,String name,int age,int weight){
    this.identifier=identifier;
    this.name=name;
    this.age=age;
    this.weight=weight;
}

初始化,赋值

//这样
Dog dog=new Dog();
dog.setDogInfo(2222,"sijia",3,20,"Husky",true,"doubi");

//或者这样
Dog dog=new Dog(2222,"sijia",3,20,"Husky",true,"doubi");

//再或者这样
Dog dog=new Dog(2222,"sijia");

一行搞定,不过数字和字符串的含义不是一目了然,还是得查看定义。新增参数就得修改定义,调用的地方也得修改 
而且如果参数更多的话,看起来会更乱。

建造者模式就为提供了另外一种解决方式,引入构造器Builder,让它实现构造的任务。

//汪汪信息类
public class Dog{   
    private int identifier;//编号
    private String name;//名字
    private int age;//年龄
    private int weight;//体重
    private String breed;//品种
    private boolean gender;//性别,true:公狗;false:母狗
    private String sickness;//疾病

    static class Builder{
        private Dog dog;

        public Builder(){
            dog=new Dog();
        }
        public Builder setIdentifier(int identifier){
             dog.identifier=identifier;
             return this;
    }

         public Builder setName(String name){
             dog.name=name;
             return this;
        }

         public Builder setAge(int age){
             dog.age=age;
             return this;
        }

         public Builder setWeight(int weight){
             dog.weight=weight;
             return this;
        }

         public Builder setBreed(int breed){
             dog.breed=breed;
             return this;
        }

         public Builder setGender(boolean gender){
             dog.gender=gender;
             return this;
        }
        public Builder setSickness(String sickness){
             dog.sickness=sickness;
             return this;
        }

        public Dog create(){
            return dog;
        }
    }
}

在对象内部增加了Builder,Buidler设置参数的方法返回都是Builder这个对象 
现在调用一下:

Dog.Builder builder = new Dog.Builder();
Dog dog = builder.setIdentifier(2222).setName("sijia").setAge(3)
.setWeight(20).setBreed("Husky").setGender(true).setSickness("doubi")
.create();

这样,每项参数定义清晰,而且直接头尾相连定义,省去重复的代码。 
感觉上是我们先获取Builder,然后构建所有参数,最后再将构建出的对象显露出来。 
契合了模式定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

其实在Android中, Builder模式也是被大量的运用。比如常见的对话框的创建

AlertDialog.Builder builder=new AlertDialog.Builder(this);
AlertDialog dialog=builder.setTitle("标题")
		.setIcon(android.R.drawable.ic_dialog_alert)
		.setView(R.layout.myview)
		.setPositiveButton(R.string.positive, new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {

			}
		})
		.setNegativeButton(R.string.negative, new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {

			}
		})
		.create();
dialog.show();

其实在java中有两个常见的类也是Builder模式,那就是StringBuilder和StringBuffer,只不过其实现过程简化了一点罢了。

我们再找找Builder模式在各个框架中的应用。

如Gson中的GsonBuilder,代码太长了,就不贴了,有兴趣自己去看源码,这里只贴出其Builder的使用方法

GsonBuilder builder=new GsonBuilder();
Gson gson=builder.setPrettyPrinting()
		.disableHtmlEscaping()
		.generateNonExecutableJson()
		.serializeNulls()
		.create();

还有EventBus中也有一个Builder,只不过这个Builder外部访问不到而已,因为它的构造函数不是public的,但是你可以在EventBus这个类中看到他的应用。

public static EventBusBuilder builder() {
	return new EventBusBuilder();
}
public EventBus() {
	this(DEFAULT_BUILDER);
}
EventBus(EventBusBuilder builder) {
	subscriptionsByEventType = new HashMap<Class<?>, CopyOnWriteArrayList<Subscription>>();
	typesBySubscriber = new HashMap<Object, List<Class<?>>>();
	stickyEvents = new ConcurrentHashMap<Class<?>, Object>();
	mainThreadPoster = new HandlerPoster(this, Looper.getMainLooper(), 10);
	backgroundPoster = new BackgroundPoster(this);
	asyncPoster = new AsyncPoster(this);
	subscriberMethodFinder = new SubscriberMethodFinder(builder.skipMethodVerificationForClasses);
	logSubscriberExceptions = builder.logSubscriberExceptions;
	logNoSubscriberMessages = builder.logNoSubscriberMessages;
	sendSubscriberExceptionEvent = builder.sendSubscriberExceptionEvent;
	sendNoSubscriberEvent = builder.sendNoSubscriberEvent;
	throwSubscriberException = builder.throwSubscriberException;
	eventInheritance = builder.eventInheritance;
	executorService = builder.executorService;
}

再看看著名的网络请求框架OkHttp

Request.Builder builder=new Request.Builder();
Request request=builder.addHeader("","")
	.url("")
	.post(body)
	.build();

可见各大框架中大量的运用了Builder模式。最后总结一下

  • 定义一个静态内部类Builder,内部的成员变量和外部类一样
  • Builder类通过一系列的方法用于成员变量的赋值,并返回当前对象本身(this)
  • Builder类提供一个build方法或者create方法用于创建对应的外部类,该方法内部调用了外部类的一个私有构造函数,该构造函数的参数就是内部类Builder
  • 外部类提供一个私有构造函数供内部类调用,在该构造函数中完成成员变量的赋值,取值为Builder对象中对应的值
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值