The "director" invokes "builder" services as it interprets the external format. The "builder" creates part of the complex object each time it is called and maintains all intermediate state. When the product is finished, the client retrieves the result from the "builder".
Affords finer control over the construction process. Unlike creational patterns that construct products in one shot, the Builder pattern constructs the product step by step under the control of the "director".
The Reader encapsulates the parsing of the common input. The Builder hierarchy makes possible the polymorphic creation of many peculiar representations or targets.
Before | After | |
---|---|---|
// BEFORE - This implementation is arguably preferable. Each // table class encapsulates a different layout. class JTable_Table { private JTable m_table; public JTable_Table( String[][] matrix ) { m_table = new JTable( matrix[0].length, matrix.length ); TableModel model = m_table.getModel(); for (int i=0; i < matrix.length; ++i) for (int j=0; j < matrix[i].length; ++j) model.setValueAt( matrix[i][j], j, i ); } public Component get_table() { return m_table; } } class GridLayout_Table { private JPanel m_table = new JPanel(); public GridLayout_Table( String[][] matrix ) { m_table.setLayout( new GridLayout( matrix[0].length, matrix.length ) ); m_table.setBackground( Color.white ); for (int i=0; i < matrix[i].length; ++i) for (int j=0; j < matrix.length; ++j) m_table.add( new Label( matrix[j][i] ) ); } public Component get_table() { return m_table; } } class GridBagLayout_Table { private JPanel m_table = new JPanel(); public GridBagLayout_Table( String[][] matrix ) { GridBagConstraints c = new GridBagConstraints(); m_table.setLayout( new GridBagLayout() ); m_table.setBackground( Color.white ); for (int i=0; i < matrix.length; ++i) for (int j=0; j < matrix[i].length; ++j) { c.gridx = i; c.gridy = j; m_table.add( new Label( matrix[i][j] ), c ); } } public Component get_table() { return m_table; } } public class BuilderDemo { public static String[][] read_data_file( String file_name ) { String[][] matrix = null; try { BufferedReader br = new BufferedReader( new FileReader( file_name ) ); String line, cell = ""; String[] tokens; boolean first_line = true; int row=0, col=0; while ((line = br.readLine()) != null) { // Use "whitespace" to tokenize each line // java.sun.com/docs/books/tutorial/extra/ // regex/pre_char_classes.html tokens = line.split( "\\s" ); int i = 0; if (first_line) { matrix = new String[Integer.parseInt( tokens[0] )] [Integer.parseInt( tokens[1] )]; i = 2; first_line = false; } for ( ; i < tokens.length; ++i) if (tokens[i].equals( " | // AFTER - The main() creates a reader/parser, and configures // it with a builder (an object that implements a standard // interface and knows how to create one of many possible // "results". The reader reads and parses the common input // and delegates the construction to the configured builder. // This implementation demonstrates the spirit of the Builder // pattern -- but -- it is more intricate, and probably cannot // be justified for this fairly limited context. class Reader { private Builder m_builder; public Reader( Builder b ) { m_builder = b; } public void construct( String file_name ) { try { BufferedReader br = new BufferedReader( new FileReader( file_name ) ); String line, cell = ""; String[] tokens; boolean first_line = true; while ((line = br.readLine()) != null) { tokens = line.split( "\\s" ); int i = 0; if (first_line) { m_builder.set_width_and_height( Integer.parseInt( tokens[0] ), Integer.parseInt( tokens[1] ) ); i = 2; first_line = false; } for ( ; i < tokens.length; ++i) if (tokens[i].equals( " |
Builder focuses on constructing a complex object step by step. Abstract Factory emphasizes a family of product objects (either simple or complex). Builder returns the product as a final step, but as far as the Abstract Factory is concerned, the product gets returned immediately. [GoF, p105]
Builder often builds a Composite. [GoF, p106]
Often, designs start out using Factory Method (less complicated, more customizable, subclasses proliferate) and evolve toward Abstract Factory, Prototype, or Builder (more flexible, more complex) as the designer discovers where more flexibility is needed. [GoF, p136]