23个java设计模式(十二)-- 生成器模式

2016年03月20日 原创
关键词: java 设计模式
摘要 生成器模式将一个复杂对象的构建与它的表示分离,使同样的构建过程可以创建不同的表示。

一、概述。

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

当系统准备为用户提供一个内部结构复杂的对象时,就可以使用生成器模式,使用该模式可以逐步地构造对象,使对象的创建更具弹性。生成器模式的关键是将一个含有多个组件对象的创建分成若干个步骤,并将这些步骤封装在一个称作生成器的接口中。

二、生成器模式的结构。

生成器模式的结构中包括四种角色。

  • 产品(Product):具体生成器要构造的复杂对象。
  • 抽象生成器(Builder):抽象生成器是一个接口,该接口除了为创建一个Product对象的各个组件定义了若干方法外,还要定义返回Product对象的方法。
  • 具体生成器(ConcreteBuilder):实现Builder接口的类,具体生成器将实现Builder接口所定义的方法。
  • 指挥者(Director):指挥者是一个类,该类需含有Builder接口声明的变量。指挥者的职责是负责向用户提供具体生成器,即指挥者将请求具体生成器来构造用户所需要的Product对象,如果所请求的具体生成器成功地构造出Product对象,指挥者就可以让该具体生成器返回所构造的Product对象。

三、示例程序。

产品(Product)

public class PanelProduct extends JPanel{
	JButton button;
	JLabel label;
	JTextField textField;
}

抽象生成器(Builder)

public interface Builder {
	public abstract void buildButton();
	public abstract void buildLabel();
	public abstract void buildTextField();
	public abstract JPanel getPanel();
}

具体生成器(ConcreteBuilder)

public class ConcreteBuilderOne implements Builder{
	private PanelProduct panel;
	
	public ConcreteBuilderOne() {
		super();
		panel = new PanelProduct();
	}

	@Override
	public void buildButton() {
		panel.button = new JButton("按钮");
	}

	@Override
	public void buildLabel() {
		panel.label = new JLabel("标签");
	}

	@Override
	public void buildTextField() {
		panel.textField = new JTextField("文本框");
	}

	@Override
	public JPanel getPanel() {
		panel.add(panel.button);
		panel.add(panel.label);
		panel.add(panel.textField);
		return panel;
	}
	
}
public class ConcreteBuilderTwo implements Builder{
	private PanelProduct panel;
	
	public ConcreteBuilderTwo() {
		super();
		panel = new PanelProduct();
	}

	@Override
	public void buildButton() {
		panel.button = new JButton("button");
	}

	@Override
	public void buildLabel() {
		panel.label = new JLabel("label");
	}

	@Override
	public void buildTextField() {
		panel.textField = new JTextField("textField");
	}

	@Override
	public JPanel getPanel() {
		panel.add(panel.textField); //与ConcreteBuilderOne顺序不同
		panel.add(panel.label);
		panel.add(panel.button);
		return panel;
	}
	
}

指挥者(Director)

public class Director {
	private Builder builder;

	public Director(Builder builder) {
		this.builder = builder;
	}
	public JPanel constructProduct() {
		builder.buildButton();
		builder.buildLabel();
		builder.buildTextField();
		return builder.getPanel();
	}
}

测试程序

public class Example1Test {
	public static void main(String[] args) {
		
		Builder builder = new ConcreteBuilderOne();
		Director director = new Director(builder);
		JPanel panel = director.constructProduct();
		JFrame frameOne = new JFrame();
		frameOne.add(panel);
		frameOne.setBounds(12, 12, 200, 120);
		frameOne.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		frameOne.setVisible(true);
		builder = new ConcreteBuilderTwo();
		director = new Director(builder);
		panel = director.constructProduct();
		JFrame frameTwo = new JFrame();
		frameTwo.add(panel);
		frameTwo.setBounds(212, 12, 200, 120);
		frameTwo.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		frameTwo.setVisible(true);
	}
}

四、生成器模式的优点。

  1. 生成器模式将对象的构造过程封装在具体生成器中,用户使用不同的具体生成器就可以得到该对象的不同表示。
  2. 生成器模式将对象的构造过程从创建该对象的类中分离出来,使用户无需了解该对象的具体组件。
  3. 可以更加精细有效地控制对象的构造过程。生成器将对象的构造过程分解成若干步骤,这就使程序可以更加精细,有效地控制整个对象的构造。
  4. 生成器模式将对象的构造过程与创建该对象类解耦,使对象的创建更加灵活有弹性。
  5. 当增加新的具体生成器时,不必修改指挥者的代码,即该模式满足“开-闭原则”。

五、适合使用生成器模式的情景。

  1. 当系统准备为用户提供一个内部结构复杂的对象,而且在构造方法中编写创建该对象的代码无法满足用户需求时,就可以使用生成器模式来构造这样的对象。
  2. 当某些系统要求对象的构造过程必须独立于创建该对象的类时。