引言
双休日出去玩了2天,一直没更新,今天我们继续,上一回咱们说了原型模式,这次我们来讲讲建造者模式。
示例地址
类图
建造者模式定义
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示
建造者模式使用场景
1. 相同的方法,不同的执行顺序,产生不同的事件结果时。
2. 多个部件或零件,都可以装配到一个对象中,但是产生的运行结果又不相同时。
3. 产品类非常复杂,或者产品类中的调用顺序不同产生了不同的作用,这个时候使用建造者模式非常合适。
4. 当初始化一个对象特别复杂,如参数多,且很多参数都具有默认值时。
建造者相关的概念
Product 产品类:产品的抽象类
Builder:抽象Builder类,规范产品的组建,一般是由子类实现具体的组建过程。
ConcreteBuilder :具体的Builder类。
Director:统一组装过程。
建造者模式示例
在开发过程中,我们会创建很多的Bean,比如下面这个
1. 创建Bean
/**
* 新闻实体类
*
* @author 512573717@qq.com
* @created 2018/7/16 下午5:32.
*/
public class News {
private int id;
private String title;
private String subTitle;
private String createTime;
private String lookCount;
private String type;
public News() {
}
public News(int id, String title, String subTitle, String createTime, String lookCount, String type) {
this.id = id;
this.title = title;
this.subTitle = subTitle;
this.createTime = createTime;
this.lookCount = lookCount;
this.type = type;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getSubTitle() {
return subTitle;
}
public void setSubTitle(String subTitle) {
this.subTitle = subTitle;
}
public String getCreateTime() {
return createTime;
}
public void setCreateTime(String createTime) {
this.createTime = createTime;
}
public String getLookCount() {
return lookCount;
}
public void setLookCount(String lookCount) {
this.lookCount = lookCount;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
@Override
public String toString() {
return "News{" +
"id=" + id +
", title='" + title + '\'' +
", subTitle='" + subTitle + '\'' +
", createTime='" + createTime + '\'' +
", lookCount='" + lookCount + '\'' +
", type='" + type + '\'' +
'}';
}
}
2. 使用的时候,我们需要这样
News news = new News(1, "今日快讯", "北京大暴雨","2018-01-17", "200", "历史");
System.out.println(news.toString());
3. 导致的问题
这个构造器调用通常需要许多你本不想设置的参数,但还是不得不为它们传递值。
4. 换一种方式
News newsBean = new News();
newsBean.setId(1);
newsBean.setTitle("今日快讯");
newsBean.setSubTitle("北京大暴雨");
newsBean.setCreateTime("2018-01-17");
newsBean.setLookCount("200");
newsBean.setType("历史");
System.out.println(newsBean.toString());
5. 存在问题
构造过程被分到了几个调用中,在构造过程中JavaBean可能处于不一致的状态。
建造者模式
我们使用建模者模式来解决问题
1. 抽象建造者类
/**
* 抽象建造者类
*
* @author 512573717@qq.com
* @created 2018/7/16 下午4:36.
*/
public abstract class Buildler {
public abstract Buildler setId(int id);
public abstract Buildler setTitle(String title);
public abstract Buildler setSubTitle(String subTitle);
public abstract Buildler setCreateTime(String createTime);
public abstract Buildler setLookCount(String lookCount);
public abstract Buildler setType(String type);
public abstract News build();
}
2. 具体建造者类
/**
* 具体建造者类
*
* @author 512573717@qq.com
* @created 2018/7/16 下午4:52.
*/
public class SimpleBuilder extends Buildler {
private News mNews;
public SimpleBuilder() {
mNews = new News();
}
@Override
public Buildler setId(int id) {
mNews.setId(id);
return this;
}
@Override
public Buildler setTitle(String title) {
mNews.setTitle(title);
return this;
}
@Override
public Buildler setSubTitle(String subTitle) {
mNews.setSubTitle(subTitle);
return this;
}
@Override
public Buildler setCreateTime(String createTime) {
mNews.setCreateTime(createTime);
return null;
}
@Override
public Buildler setLookCount(String lookCount) {
mNews.setLookCount(lookCount);
return this;
}
@Override
public Buildler setType(String type) {
mNews.setType(type);
return this;
}
@Override
public News build() {
return mNews;
}
}
3. 指挥者类
/**
* 指挥者类
*
* @author 512573717@qq.com
* @created 2018/7/16 下午4:57.
*/
public class Director {
// 组装产品
public static News create(String type) {
return new SimpleBuilder().setType(type)
.setId(1)
.setTitle("历史上的今天")
.build();
}
}
4. 调用
News history = Director.create("历史");
News military = Director.create("军事");
System.out.println(history.toString());
System.out.println(military.toString());
// 另外一种方式创建
SimpleBuilder simpleBuilder = new SimpleBuilder();
News science =simpleBuilder.setType("科技").setTitle("小米上市").build();
System.out.println(science.toString());
总结
在《Effective Java》书中第二条,就提到“遇到多个构造器参数时要考虑用构建器”,其实这里的构建器就属于建造者模式。建造者模式将构建与表示分离。上面的例子中,我们其实根本就不会知道具体是怎么产生一条新闻的,因为这个过程让director给代劳了。然后,SimpleBuilder。director其实只是执行了这个过程。这样子,达到了分离模块的功能。
网友评论