前言
建造者模式在开发中经常用到,看下面一段android代码应该很熟悉
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle("问题:");
builder.setMessage("请问你满十八岁了吗?");
builder.setIcon(R.mipmap.ic_launcher_round);
builder.create();
这里就是标准的使用了建造者模式,这样做有什么好处呢?
- 可以省去大量的构造方法传参数的臃肿代码
- 可以根据自己业务的需求动态的配置需要的参数
- 在建造者模式中,客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。
- 建造者模式很容易进行扩展。如果有新的需求,通过实现一个新的建造者类就可以完成,基本上不用修改之前已经测试通过的代码,因此也就不会对原有功能引入风险。符合开闭原则。
场景构建
构建一个类,类中的变量特别多,调用里面的某个方法进行打印一些参数的操作
代码构建
先构建某用户的一个抽象类
public abstract class PersonInfo {
String name;
String age;
String like;
abstract void setLike(String like);
abstract void setName(String name);
abstract void setAge(String age);
public void displayInfo(){
System.out.print("我是"+name +" 我今年"+age+" 我喜欢"+like);
}
}
其次构建某用户的实体类
public class Person extends PersonInfo {
@Override
void setLike(String like) {
super.like = like;
}
@Override
void setName(String name) {
super.name = name;
}
@Override
void setAge(String age) {
super.age = age;
}
}
这样用户的对象类就构建完成了,这个时候我们需要定义建造者的抽象类
/**
* 构建建造工厂的抽象类,因为一般会涉及到一些属性,所以这里一般是做成抽象类而不是接口
* <p>
* <p>
* 我们定义了两个简单的方法方便展示
*/
public abstract class Builder {
public abstract void setName(String name);
public abstract void setAge(String age);
public abstract void setLike(String like);
public abstract void display();
}
再构建实体建造者类
/**
* 具体的建造者实体类
*/
public class ContentBuilder extends Builder {
private Person person;
public ContentBuilder() {
person = new Person();
}
@Override
public void setName(String name) {
person.setName(name);
}
@Override
public void setAge(String age) {
person.setAge(age);
}
@Override
public void setLike(String like) {
person.setLike(like);
}
@Override
public void display() {
person.displayInfo();
}
}
最后构建建造者的包装类
public class Director {
Builder builder;
public Director(Builder builder) {
this.builder = builder;
}
public void display(){
builder.display();
}
}
结果生成
ContentBuilder contentBuilder = new ContentBuilder();
contentBuilder.setAge("40");
contentBuilder.setName("kobe");
contentBuilder.setLike("打篮球");
Director director = new Director(contentBuilder);
director.display();
这样简单的一个构建者模式就生成了,但是作为一般的构建者模式是不需要采用这么多的抽象类接口来做,就像android中的弹窗,他是直接使用具体的建造者类来进行完成了!所以需要优化
优化
- 不需要建造者的抽象类,直接构建实体类
- 建造者模式中包装类与建造类是一体一般写在内部作为内部类
- 需要提供方法返回包装类对象
根据以上点我们直接构建一个类就可以完成
/**
* 建造者的包装类
*/
public class Director {
private String name;
private String age;
private String like;
public Director(ContentBuilder contentBuilder) {
this.name = contentBuilder.name;
this.age = contentBuilder.age;
this.like = contentBuilder.like;
}
public void displayInfo(){
System.out.print("我是"+name +" 我今年"+age+" 我喜欢"+like);
}
/**
* 由于是用Builder建造者模式来创建某个对象,因此就没有必要再定义一个Builder接口,直接提供一个具体的建造类就可以了。
*/
public static class ContentBuilder {
private String name;
private String age;
private String like;
public ContentBuilder setName(String name) {
this.name = name;
return this;
}
public ContentBuilder setAge(String age) {
this.age = age;
return this;
}
public ContentBuilder setLike(String like) {
this.like = like;
return this;
}
public Director build() {
return new Director(this);
}
}
}
执行代码
Director director = new Director.ContentBuilder()
.setAge("40")
.setName("kobe")
.setLike("篮球")
.build();
director.displayInfo();
结果
我是kobe 我今年40 我喜欢篮球
Process finished with exit code 0
这就跟我们前面的弹窗执行代码模版很相似了,这里就完成了一个常用版的构建者模式!
总结
构建者模式一般常用于包装类与建造类的解耦,不需要关心我具体包装类有哪些参数是进行了设置的,我们只需要对我们想要的属性进行设置即可,这样就能灵活后期的扩展性也更强大,但是缺点也很明显,代码量太大,建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制,所以在使用构建者模式的时候一定要区分场景!
提醒
需要源码的朋友可以发送请求到邮箱
imkobedroid@gmail.com
文章与代码有待改进!希望可以交流
网友评论