一、生成器模式
封装一个复杂对象构造过程,并允许按步骤构造
![](https://img.haomeiwen.com/i1316029/d1fd5249e8709c06.png)
二、示例
度假计划生成项目:时间、门票、餐厅、住宿、特殊活动等,一个计划就是一个具体对象,要便于扩展
对于用户来说关心的只是选择计划的种类,例如3日游、4日游和他的旅行开始时间,然后得到计划的细节安排
此处则使用生成器模式,将不同的计划安排制定成模板,选择不同的模板引入旅游的开始日期即可生成计划书
1.定义旅游安排的对象和属性
/**
* 旅游安排的对象,定义旅游日期,酒店,门票以及活动等属性和基础方法
*/
public class VacationDay {
private Date mDate;
private String mHotels;
private ArrayList<String> mTickets = null;
private ArrayList<String> mEvents = null;
public VacationDay(Date date) {
mDate = date;
mTickets = new ArrayList<String>();
mEvents = new ArrayList<String>();
}
public void setDate(Date date) {
mDate = date;
}
public void setHotel(String mHotels) {
this.mHotels = mHotels;
}
public void addTicket(String ticket) {
mTickets.add(ticket);
}
public void addEvent(String event) {
mEvents.add(event);
}
public String showInfo() {
StringBuilder stb = new StringBuilder();
stb.append("Date:" + mDate.toString() + "\n");
stb.append("Hotel:" + mHotels + "\n");
stb.append("Tickets:" + mTickets.toString() + "\n");
stb.append("Events" + mEvents.toString() + "\n");
return stb.toString();
}
}
/**
* 对外提供的假期旅游对象,用于制定计划的生成器使用
*/
public class Vacation {
private ArrayList<VacationDay> mVacationDayLst;
private Date mStDate;
private int mDays = 0;
private VacationDay mVacationDay;
public Vacation(String std) {
mVacationDayLst = new ArrayList<VacationDay>();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
mStDate = sdf.parse(std);
mVacationDay = new VacationDay(mStDate);
mVacationDayLst.add(mVacationDay);
mDays++;
} catch (ParseException e) {
e.printStackTrace();
}
}
public void setStDate(String std) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
mStDate = sdf.parse(std);
} catch (ParseException e) {
e.printStackTrace();
}
}
public Date getStDate() {
return mStDate;
}
public void addDay() {
mVacationDay = new VacationDay(nextDate(mDays));
mVacationDayLst.add(mVacationDay);
mDays++;
}
public boolean setVacationDay(int i) {
if ((i > 0) && (i < mVacationDayLst.size())) {
mVacationDay = mVacationDayLst.get(i);
return true;
}
mVacationDay = null;
return false;
}
public void setHotel(String mHotels) {
mVacationDay.setHotel(mHotels);
}
public void addTicket(String ticket) {
mVacationDay.addTicket(ticket);
}
public void addEvent(String event) {
mVacationDay.addEvent(event);
}
public void showInfo() {
for (int i = 0, len = mVacationDayLst.size(); i < len; i++) {
System.out.println("** " + (i + 1) + " day**");
System.out.println(mVacationDayLst.get(i).showInfo());
}
}
private Date nextDate(int n) {
Calendar cal = Calendar.getInstance();
cal.setTime(mStDate);
cal.add(Calendar.DATE, n);
return cal.getTime();
}
}
2.定义生成器的抽象类和抽象方法
/**
* 生成器模式,定义抽象生成器,定义基本的抽象方法
*/
public abstract class AbsBuilder {
public Vacation mVacation;
public AbsBuilder(String std) {
mVacation = new Vacation(std);
}
public abstract void buildvacation();
public abstract void buildDay(int i);
public abstract void addHotel(String hotel);
public abstract void addTicket(String ticket);
public abstract void addEvent(String tvent);
public Vacation getVacation() {
return mVacation;
}
}
3.实现抽象类,制定不同的计划模板
/**
* 生成器模式,定义3天旅游的生成器对象
*/
public class Builder3d extends AbsBuilder {
public Builder3d(String std) {
super(std);
}
@Override
public void buildDay(int i) {
mVacation.setVacationDay(i);
}
@Override
public void addHotel(String hotel) {
mVacation.setHotel(hotel);
}
@Override
public void addTicket(String ticket) {
mVacation.addTicket(ticket);
}
@Override
public void addEvent(String event) {
mVacation.addEvent(event);
}
@Override
public void buildvacation() {
addTicket("Plane Ticket");
addEvent("Fly to Destination");
addEvent("Supper");
addEvent("Dancing");
addHotel("Four Seasons");
mVacation.addDay();
addTicket("Theme Park");
addEvent("Bus to Park");
addEvent("lunch");
addHotel("Four Seasons");
mVacation.addDay();
addTicket("Plane Ticket");
addEvent("City Tour");
addEvent("Fly to Home");
}
}
/**
* 生成器模式,定义4天旅游的生成器对象
*/
public class Builder4d extends AbsBuilder {
public Builder4d(String std) {
super(std);
}
@Override
public void buildDay(int i) {
mVacation.setVacationDay(i);
}
@Override
public void addHotel(String hotel) {
mVacation.setHotel(hotel);
}
@Override
public void addTicket(String ticket) {
mVacation.addTicket(ticket);
}
@Override
public void addEvent(String event) {
mVacation.addEvent(event);
}
@Override
public void buildvacation() {
addTicket("Plane Ticket");
addEvent("Fly to Destination");
addEvent("Supper");
addHotel("Hilton");
mVacation.addDay();
addTicket("Zoo Ticket");
addEvent("Bus to Zoo");
addEvent("Feed animals");
addHotel("Hilton");
mVacation.addDay();
addTicket("Beach");
addEvent("Swimming");
addHotel("Home inn");
mVacation.addDay();
addTicket("Plane Ticket");
addEvent("Fly to Home");
}
}
4.定义引导者,对外提供生成方法
/**
* 生成器模式,引导者对象
*/
public class Director {
private AbsBuilder builder;
public Director(AbsBuilder builder) {
this.builder = builder;
}
public void setBuilder(AbsBuilder builder) {
this.builder = builder;
}
public void construct() {
builder.buildvacation();
builder.getVacation().showInfo();
}
}
5.对外直接调用引导者生成对象即可
/**
* 生成器模式,简化复杂对象的生成
* 旅游计划项目,对于用户来说只关心旅游日期和开始时间,可以自动展示出所有计划即可
*/
public class MainTest {
public static void main(String[] args) {
Director mDirector = new Director(new Builder4d("2015-12-29"));
mDirector.construct();
mDirector.setBuilder(new Builder3d("2015-8-30"));
mDirector.construct();
testself();
}
}
三、生成器的演化
为了简化生成器模式的使用,慢慢发生了演变:
- 省略抽象生成器类
- 省略指导者类
参考:Java中的StringBuilder即为字符串的一种生成器
四、总结
- 将复杂对象的创建过程封装起来
- 允许对象通过几个步骤来创建,并且可以改变过程(工厂模式只有一个步骤)
- 只需指定具体生成器就能生成特定对象,隐藏类的内部结构
- 对象的实现可以被替换
Java设计模式所有示例代码,持续更新中
网友评论