您的位置:首页 > 编程语言 > Java开发

java 开发模式之十六 : 生成器模式

2017-12-24 20:01 169 查看

原理或定義

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

结构

Builder:生成器接口,定义创建一个Product对象所需要的各个部件的操作。

ConcreteBuilder:具体的生成器实现,实现各个部件的创建,并负责组装Product对象的各个部件,同时还提供一个让用户获取组装完成后的产品对象的方法。

Director:指导者,也被称导向者,主要用来使用Builder接口,以一个统一的过程来构建所需要的Product对象。

Product:产品,表示被生成器构建的复杂对象,包含多个部件

 

類圖



案例与代码

本文使用度假计划生成项目来介绍

度假计划生成项目介绍

度假计划的因素:时间、门票、餐厅、住宿、特殊活动等

生成器模式设计方案:

类图:



Product:

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) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

public void setStDate(String std) {

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
mStDate = sdf.parse(std);
} catch (ParseException e) {
// TODO Auto-generated catch block
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();
}
}

Builder

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() {

4000
return mVacation;

}

}

ConcreteBuilder

public class Builder3d extends AbsBuilder {

public Builder3d(String std) {
super(std);
// TODO Auto-generated constructor stub

}

@Override
public void buildDay(int i) {
// TODO Auto-generated method stub

mVacation.setVacationDay(i);

}

@Override
public void addHotel(String hotel) {
// TODO Auto-generated method stub
mVacation.setHotel(hotel);
}

@Override
public void addTicket(String ticket) {
// TODO Auto-generated method stub
mVacation.addTicket(ticket);
}

@Override
public void addEvent(String event) {
// TODO Auto-generated method stub
mVacation.addEvent(event);
}

@Override
public void buildvacation() {
// TODO Auto-generated method stub
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");

}

}
public class Builder4d extends AbsBuilder {

public Builder4d(String std) {
super(std);
// TODO Auto-generated constructor stub

}

@Override
public void buildDay(int i) {
// TODO Auto-generated method stub

mVacation.setVacationDay(i);

}

@Override
public void addHotel(String hotel) {
// TODO Auto-generated method stub
mVacation.setHotel(hotel);
}

@Override
public void addTicket(String ticket) {
// TODO Auto-generated method stub
mVacation.addTicket(ticket);
}

@Override
public void addEvent(String event) {
// TODO Auto-generated method stub
mVacation.addEvent(event);
}

@Override
public void buildvacation() {
// TODO Auto-generated method stub
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");
}

}
public class BuilderSelf {
public Vacation mVacation;

public BuilderSelf(String std) {
mVacation = new Vacation(std);
// TODO Auto-generated constructor stub

}

public BuilderSelf addDay() {
// TODO Auto-generated method stub

mVacation.addDay();
return this;
}

public BuilderSelf buildDay(int i) {
// TODO Auto-generated method stub

mVacation.setVacationDay(i);
return this;
}

public BuilderSelf addHotel(String hotel) {
// TODO Auto-generated method stub
mVacation.setHotel(hotel);
return this;
}

public BuilderSelf addTicket(String ticket) {
// TODO Auto-generated method stub
mVacation.addTicket(ticket);
return this;
}

public BuilderSelf addEvent(String event) {
// TODO Auto-generated method stub
mVacation.addEvent(event);
return this;
}

public Vacation getVacation() {

return mVacation;

}
}

Director

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();
}
}


测试类:

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() ;
}

public static void testself() {
BuilderSelf builder = new BuilderSelf("2015-9-29");

builder.addTicket("Plane Ticket").addEvent("Fly to Destination")
.addEvent("Supper").addHotel("Hilton");

builder.addDay().addTicket("Zoo Ticket").addEvent("Bus to Zoo")
.addEvent("Feed animals").addHotel("Home Inn");

builder.addDay();
builder.addTicket("Beach");
builder.addEvent("Swimming");
builder.addHotel("Home inn");

builder.addDay().addTicket("Plane Ticket").addEvent("Fly to Home");
builder.getVacation().showInfo();
}

}


封装一个复杂对象构造过程,并允许按步骤构造。

生成器模式2种演化形式:

省略抽象生成器类
省略指导者类

使用場景

1. 需要生成一个产品对象有复杂的内部结构。每一个内部成分本身可以是对象,也可以使一个对象的一个组成部分。

        2、生成的产品对象的属性相互依赖。建造模式可以强制实行一种分步骤进行的建造过程。

        3、在对象创建过程中会使用到系统中的其他一些对象,这些对象在产品对象的创建过程中不易得到

優缺點

主要优点有:

1. 生成器模式正是把产品构建的过程独立出来,使它和具体产品的表现分松散耦合,从而使得构建算法可以复用,而具体产品表现也可以很灵活地、方便地扩展和切换。

2. 由于Builder对象只是提供接口给Director使用,那么具体部件创建和装配方式是被Builder接口隐藏了的,Director并不知道这些具体的实现细节。

3. 生成器模式很好的实现构建算法和具体产品实现的分离。这样一来,使得构建产品的算法可以复用。同样的道理,具体产品的实现也可以复用,同一个产品的实现,可以配合不同的构建算法使用

4. 分离整体构建算法和部件构造

 

缺点主要有:

建造者模式的“加工工艺”是暴露的,这样使得建造者模式更加灵活,也使得工艺变得对客户不透明。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息