基本概念

生成器模式是一种创建型设计模式,它把对象的创建步骤抽象成生成器,并且可以通过指导类(director)对所有生成步骤的先后顺序进行控制;客户端使用指导类并传入相应的生成器,通过指导类的接口便可以得到相应的对象;

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

具体代码演示

假设场景

出去旅游都要制定旅游计划,包括旅游天数、定酒店等,如果去专业公司定制旅游行程,公司就如同一个生成器,根据游客需求定制计划;游计划中有公共部分,那么设计一个大类,把所有可能会在计划中的项目都在这大类中构造创建方法;同时这个大类应该传入一个旅游计划对象,用于存储这个旅游计划,相对应的旅游计划类,则是一个标准的JavaBean,拥有setter和getter方法。然后客户类会建立一个方法,在这个方法中根据需求,调用相应的生成类中方法,将创建过程给封装了。这就是生成器模式,使用使用生成器模式封装一个产品的构造过程,并允许按步骤构造;

本文以一个旅游计划的例子,通过封装旅游计划制定的过程来实现目标。首先有一个完整的计划类,即所有计划项目都包括其中,然后有一个表示创建过程的类,然后生成器类负责封装制作过程,客户类只需要调用相应的生成方法即可;

基本代码演示

首先是builder接口,定义一个创建产品过程的接口;

public interface Builder {
	void buildDay(int day);
	void addHotel(String hotel);
	void addTickets(String tickets);
	void addDestination(String destination);
	Planner getVacationPlanner();
}

然后是该接口的实现,这里是旅游计划创建过程的实现;

public class VacationBuilder implements Builder {
	Planner pl;
	public VacationBuilder()
	{
		pl=new VacationPlanner();//建立一个VacationPlanner对象
	}
	@Override
	public void buildDay(int day) {
		// TODO Auto-generated method stub
		pl.setDay(day);
	}
	@Override
	public void addHotel(String hotel) {
		// TODO Auto-generated method stub
		pl.setHotel(hotel);
	}
	@Override
	public void addTickets(String tickets) {
		// TODO Auto-generated method stub
		pl.setTickets(tickets);
	}
	@Override
	public void addDestination(String destination) {
		// TODO Auto-generated method stub
		pl.setDestination(destination);
	}
	@Override
	public Planner getVacationPlanner() {
		// TODO Auto-generated method stub
		return this.pl;
	}
}

对应的是旅游计划对象,那么应该创建一个旅游计划类:

public class Planner {
	int day;//天数
	String hotel;//旅馆
	String tickets;//门票
	String destination;//目的地
	public void setDay(int day)
	{
		this.day=day;
	}
	public int getDay()
	{
		return this.day;
	}
	public void setHotel(String hotel)
	{
		this.hotel=hotel;
	}
	public String getHotel()
	{
		return this.hotel;
	}
	public void setTickets(String tickets)
	{
		this.tickets=tickets;
	}
	public String getTickets()
	{
		return this.tickets;
	}
	public void setDestination(String destination)
	{
		this.destination=destination;
	}
	public String getDestination()
	{
		return this.destination;
	}
}

接着是client类,这里是构造一个使用builder对象的类,并通过内部方法封装builder对象的方法

public class Client {
	public Planner constructPlanner(int day,String hotel,String tickets,String destination,Builder builder) {
		// TODO Auto-generated method stub
		builder.buildDay(day);
		builder.addHotel(hotel);
		builder.addTickets(tickets);
		builder.addDestination(destination);
		return builder.getVacationPlanner();
	}
}

最后,则是客户获得该自身的旅游计划:

public class Test {
	private static void showPlanner(Planner pl)
	{
		if(pl.getDay()!=0)
			System.out.println("旅游天数为"+pl.getDay()+"天");
		if(pl.getHotel()!=null)
			System.out.println("酒店定在"+pl.getHotel());
		if(pl.getTickets()!=null)
			System.out.println("买的门票是:"+pl.getTickets());
		if(pl.getDestination()!=null)
			System.out.println("旅游的目的地是:"+pl.getDestination());
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Builder builder=new VacationBuilder();
		Client c1=new Client();
		Planner pl1=c1.constructPlanner(10,null,"Gugong","Beijing",builder);
		System.out.println("您好,这里是旅游服务,我们会根据您的需求为您打造完美的旅游计划!");
		System.out.println("第一位游客的安排:");
		showPlanner(pl1);
		System.out.println("------------------");
		Client c2=new Client();
		Planner pl2=c2.constructPlanner(5,"Hilton","Disneland tickets","L.A",builder);
		System.out.println("第二位游客的安排:");
		showPlanner(pl2);
	}
}

以我的理解看,生成器模式的核心在于,生成器负责封装一个产品复杂的创建过程。而且产品创建将一类产品的创建步骤一般化,针对具体产品则调用相应的具体过程即可。这也是它与工厂模式的区别,工厂模式是直接创建一个对象,而生成器模式将创建过程细化到每一个步骤