设计模式之Builder

设计模式之Builder

原文:http://www.vincehuston.org/dp/builder.html

定义:

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

也就是说将产品的内部表象和产品的生成过程分割开来,从而使一个建造过程生成具有不同的内部表象的产品对象。建造模式使得产品内部表象可以独立的变化,客户不必知道产品内部组成的细节。建造模式可以强制实行一种分步骤进行的建造过程。

事例:

1.  定义一个创造复杂对象的步骤,并在抽象基类中定义这些步骤的接口。

2.  在派生类中实现这些步骤。

3.  定义一个包裹类,持有这个抽象基类类型的一个实例。

4.  包裹类通过解析输入格式,然后委派目标对象来实现。


上图说明:假设一个复杂对象是由多个部件组成的,Builder模式是把复杂对象的创建和部件的创建分别开来,分别用Builder类和Director类来表示.

1public 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 ();

。。。
  }

}

3Builder的具体实现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强调的是产品簇。

它通常用来建造复合对象。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值