设计模式之Builder
原文:http://www.vincehuston.org/dp/builder.html
定义:
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示.
也就是说将产品的内部表象和产品的生成过程分割开来,从而使一个建造过程生成具有不同的内部表象的产品对象。建造模式使得产品内部表象可以独立的变化,客户不必知道产品内部组成的细节。建造模式可以强制实行一种分步骤进行的建造过程。
事例:

1. 定义一个创造复杂对象的步骤,并在抽象基类中定义这些步骤的接口。
2. 在派生类中实现这些步骤。
3. 定义一个包裹类,持有这个抽象基类类型的一个实例。
4. 包裹类通过解析输入格式,然后委派目标对象来实现。


上图说明:假设一个复杂对象是由多个部件组成的,Builder模式是把复杂对象的创建和部件的创建分别开来,分别用Builder类和Director类来表示.
1、public interface Builder { }//需要一个接口,它定义如何创建复杂对象的各个部件。
2、用Director构建最后的复杂对象,而在上面Builder接口中封装的是如何创建一个个部件(复杂对象是由这些部件组成的),也就是说Director的内容是如何将部件最后组装成成品:
public class Director {
private Builder builder;
public Director( Builder builder ) {
this.builder = builder;
}
// 将部件partA partB partC最后组成复杂对象
public void construct() {
builder.buildPart ();
。。。
}
}
3、Builder的具体实现ConcreteBuilder:通过具体完成接口Builder来构建产品,
定义并明确它所要创建的是什么具体东西,提供一个可以重新获取产品的接口:
public class ConcreteBuilder implements Builder {。。。}
// 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( "" )) {
m_builder.build_cell( cell );
cell = "";
m_builder.start_row();
} else if (tokens[i].equals( "" )) {
m_builder.build_cell( cell );
cell = "";
} else {
cell += " " + tokens[i];
}
}
m_builder.build_cell( cell );
br.close();
} catch( Exception ex ) { ex.printStackTrace(); }
} }
interface Builder {
void set_width_and_height( int width, int height );
void start_row();
void build_cell( String value );
Component get_result();
}
class JTable_Builder implements Builder {
private JTable m_table;
private TableModel m_model;
private int i = 0, j = 0;
public void set_width_and_height( int width, int height ) {
m_table = new JTable( height, width );
m_model = m_table.getModel();
}
public void start_row() {
++i;
j = 0;
}
public void build_cell( String value ) {
m_model.setValueAt( value, i, j++ );
}
public Component get_result() { return m_table; }
}
class GridLayout_Builder implements Builder {
private JPanel m_panel = new JPanel();
public void set_width_and_height( int width, int height ) {
m_panel.setLayout( new GridLayout( height, width ) );
m_panel.setBackground( Color.white );
}
public void start_row() { }
public void build_cell( String value ) {
m_panel.add( new Label( value ) );
}
public Component get_result() { return m_panel; }
}
class GridBagLayout_Builder implements Builder {
private JPanel m_panel = new JPanel();
private GridBagConstraints c = new GridBagConstraints();
private int i = 0, j = 0;
public void set_width_and_height( int width, int height ) {
m_panel.setLayout( new GridBagLayout() );
m_panel.setBackground( Color.white );
}
public void start_row() {
++i;
j = 0;
}
public void build_cell( String value ) {
c.gridx = j++;
c.gridy = i;
m_panel.add( new Label( value ), c );
}
public Component get_result() { return m_panel; }
}
public class BuilderDemo {
public static void main( String[] args ) {
Builder target = null;
try {
target = (Builder) Class.forName(
args[0] ).newInstance();
} catch( Exception ex ) { ex.printStackTrace(); }
Reader parser = new Reader( target );
parser.construct( "BuilderDemo.dat" );
JFrame frame = new JFrame( "BuilderDemo - " + args[0] );
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.getContentPane().add( target.get_result() );
frame.pack();
frame.setVisible( true );
} }
一些经验:
1. 有些时候这种模式作为一种补充,如它在其他模式中用来实现那些组建被建造。Abstract Factory, Builder, and Prototype在实现中可以使用单例模式。
2. 它的焦点是逐步建造复杂对象,Abstract Factory强调的是产品簇。
它通常用来建造复合对象。


90

被折叠的 条评论
为什么被折叠?



