Java设计模式--生成器模式

生成器模式

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

Builder Pattern

Separate the construction of a complex object from its representation so that the same construction process can create different representations.

类图

模式的结构与使用

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

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

简单的例子

Product的抽象类PanelProduct.java

1
2
3
4
5
6
7
8
9
package Builder;
import javax.swing.*;
public class PanelProduct extends JPanel {
JButton button;
JLabel label;
JTextField textField;
}

抽象生成器Builder接口类Builder.java

1
2
3
4
5
6
7
8
9
10
package Builder;
import javax.swing.JPanel;
public interface Builder {
public abstract void buildButton();
public abstract void buildLabel();
public abstract void buildTextField();
public abstract JPanel getPanel();
}

ConcreteBuilder的实现类ConcreteBuilderOne.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package Builder;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class ConcreteBuilderOne implements Builder {
private PanelProduct panel;
public ConcreteBuilderOne() {
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;
}
}

ConcreteBuilder的实现类ConcreteBuilderTwo.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package Builder;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class ConcreteBuilderTwo implements Builder {
private PanelProduct panel;
public ConcreteBuilderTwo() {
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("My文本框");
}
@Override
public JPanel getPanel() {
panel.add(panel.textField);
panel.add(panel.label);
panel.add(panel.button);
return panel;
}
}

指挥类Director.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package Builder;
import javax.swing.JPanel;
public class Director {
private Builder builder;
public Director(Builder builder) {
this.builder = builder;
}
public JPanel constructProduct() {
builder.buildButton();
builder.buildLabel();
builder.buildTextField();
JPanel product = builder.getPanel();
return product;
}
}

测试类Application.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
ppackage Builder;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Application {
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);
}
}

运行截图

生成器模式的优点

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

适用生成器模式的情景

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

下载源码请到

MyGitHub

文章目录
  1. 1. 生成器模式
  2. 2. Builder Pattern
  3. 3. 类图
  4. 4. 模式的结构与使用
  5. 5. 简单的例子
    1. 5.1. Product的抽象类PanelProduct.java
    2. 5.2. 抽象生成器Builder接口类Builder.java
    3. 5.3. ConcreteBuilder的实现类ConcreteBuilderOne.java
    4. 5.4. ConcreteBuilder的实现类ConcreteBuilderTwo.java
    5. 5.5. 指挥类Director.java
    6. 5.6. 测试类Application.java
  6. 6. 运行截图
  7. 7. 生成器模式的优点
  8. 8. 适用生成器模式的情景
  9. 9. 下载源码请到