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