生成器模式也叫建造者模式。目的是将一个复杂的构建与其表示相分离,是同样的构建过程可以创建不同的表示。
下面来一个实例:
比如我们建造一个界面要加入 按钮,标签,文本输入框这个控件。
1.创建一个PanelProduct 就称它为一个产品,产品有不同的类型。
1 import javax.swing.*;
2
3 public class PanelProduct extends JPanel
4 {
5 JButton button;
6 JLabel label;
7 JTextField textField;
8 }
2.创建一个生成器接口Builder
1 import javax.swing.*;
2
3 public interface Builder {
4 public abstract void buildButton();
5 public abstract void buildLable();
6 public abstract void buildTextField();
7 public abstract JPanel getPanel();
8 }
3.创建产品
3.1穿件第一种产品类型ConcreteBuilderOne
1 import javax.swing.*;
2 // 这是第一个产品
3 public class ConcreteBuilderOne implements Builder {
4 private PanelProduct panel; //提供一个产品属性,目的是为了生产这个产品
5
6 ConcreteBuilderOne() { //初始化类 创建了一个产品的实例
7 panel = new PanelProduct();
8 }
9
10 // 完成接口方法的方法体 复写他们的方法
11 @Override
12 public void buildButton() {
13 panel.button = new JButton("按钮");
14 }
15
16 @Override
17 public void buildLable() {
18 panel.label = new JLabel("标签");
19 }
20
21 @Override
22 public void buildTextField() {
23 panel.textField = new JTextField("文本框");
24 }
25
26 @Override
27 // 将三个方法(功能)综合在一起 (或产生联系)
28 public JPanel getPanel() {
29 panel.add(panel.button);
30 panel.add(panel.label);
31 panel.add(panel.textField);
32 return panel;
33 }
34
35 }
3.2创建第二种产品的类型ConcreteBuilderTwo
1 import javax.swing.*;
2 // 这是第二个产品 为了便于讲解功能实现类似于第一个产品(但实际情况可以更加不同)
3 public class ConcreteBuilderTwo implements Builder {
4 private PanelProduct pannel;//需要具体容器
5 public ConcreteBuilderTwo() {
6 pannel=new PanelProduct();
7 }
8 @Override
9 public void buildButton() {
10 pannel.button=new JButton("button");
11 }
12 @Override
13 public void buildLable() {
14 pannel.label=new JLabel("label");
15 }
16 @Override
17 public void buildTextField() {
18 pannel.textField=new JTextField("textField");
19 }
20 @Override
21 public JPanel getPanel() {
22 pannel.add(pannel.button);
23 pannel.add(pannel.label);
24 pannel.add(pannel.textField);
25
26 return pannel;
27 }
28
29 }
4.创建指挥者Director
1 import javax.swing.JPanel;
2
3 //指挥者,指挥建造产品
4 public class Director {
5 private Builder builder;
6 // 将生成器实例化 里面的参数是为了接收传过来的是哪一个产品的建造方法,
7 // 在这里可以接收ConcreteBuilderone,two.
8 public Director(Builder builder) {
9 //假设传进来的是ConcreteBuilderOne的实例
10 //这个builder是ConcreteBuilderOne(它实现了接口Builder的方法)
11 this.builder = builder;
12 }
13
14 public JPanel constructProduct() {
15 builder.buildButton(); //builder1创建一个按钮
16 builder.buildLable(); //builder1创建一个标签
17 builder.buildTextField(); //builder1穿件一个文本输入框
18 JPanel product = builder.getPanel();//将builder1的三个功能联系起来
19 return product; //返回成品
20
21 }
22 }
5.创建一个测试类Test
1 import javax.swing.*;
2
3 public class Test {
4
5 public static void main(String[] args) {
6 Builder builder1 = new ConcreteBuilderOne(); //建造第一种产品
7 Director director = new Director(builder1); //初始化指挥者
8 JPanel panel = director.constructProduct(); //得到建造好的产品,下面就开始使用
9 JFrame frameOne = new JFrame();
10 frameOne.add(panel);
11 //下面这些就无关紧要
12 frameOne.setBounds(12, 12, 200, 120);
13 frameOne.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
14 frameOne.setVisible(true);
15
16 Builder builder2 = new ConcreteBuilderTwo();
17 director = new Director(builder2);
18 panel = director.constructProduct();
19 JFrame frametwo = new JFrame();
20 frametwo.add(panel);
21 frametwo.setBounds(212, 12, 200, 120);
22 frametwo.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
23 frametwo.setVisible(true);
24 }
25
26 }
测试结果:
第一种:
第二种:
可以看出:如果再生产不同类型的同种产品,只需再写ConcreteBuilder3,4,5······,而不需修改其他的代码,这样提高维护,并且节约时间。
写代码时,创建产品类(Builder(实体类))要包含产品类(product),指挥者类(director)要包含被指挥的创建产品类(Builder)。
个人原创,能力有限,如有错误,烦请斧正!
可以配合这篇文章更加深刻的理解:生成器模式实践练习---加深理解