程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> C#設計模式之建造者設計模式(Builder)

C#設計模式之建造者設計模式(Builder)

編輯:關於C#

一、建造者(Builder)模式

建造者模式可以將一個產品的內部表象與產品的生成過程分割開來,從而可以使一個建造過程生成具有不同的內部表象的產品對象。

對象性質的建造

有些情況下,一個對象會有一些重要的性質,在它們沒有恰當的值之前,對象不能作為一個完整的產品使用。比如,一個電子郵件有發件人地址、收件人地址、主題、內容、附錄等部分,而在最起碼的收件人地址未被賦值之前,這個電子郵件不能發出。

有些情況下,一個對象的一些性質必須按照某個順序賦值才有意義。在某個性質沒有賦值之前,另一個性質則無法賦值。這些情況使得性質本身的建造涉及到復雜的商業邏輯。

這時候,此對象相當於一個有待建造的產品,而對象的這些性質相當於產品的零件,建造產品的過程就是組合零件的過程。由於組合零件的過程很復雜,因此,這些"零件"的組合過程往往被"外部化"到一個稱作建造者的對象裡,建造者返還給客戶端的是一個全部零件都建造完畢的產品對象。

命名的考慮

之所以使用"建造者"而沒有用"生成器"就是因為用零件生產產品,"建造"更為合適,"創建"或"生成"不太恰當。

二、Builder模式的結構:

建造者(Builder)角色:給出一個抽象接口,以規范產品對象的各個組成成分的建造。一般而言,此接口獨立於應用程序的商業邏輯。模式中直接創建產品對象的是具體建造者(ConcreteBuilder)角色。具體建造者類必須實現這個接口所要求的方法:一個是建造方法,另一個是結果返還方法。

具體建造者(Concrete Builder)角色:擔任這個角色的是於應用程序緊密相關的類,它們在應用程序調用下創建產品實例。這個角色主要完成的任務包括:

實現Builder角色提供的接口,一步一步完成創建產品實例的過程。

在建造過程完成後,提供產品的實例。

指導者(Director)角色:擔任這個角色的類調用具體建造者角色以創建產品對象。導演者並沒有產品類的具體知識,真正擁有產品類的具體知識的是具體建造者對象。

產品(Product)角色:產品便是建造中的復雜對象。

指導者角色是於客戶端打交道的角色。導演者角色將客戶端創建產品的請求劃分為對各個零件的建造請求,再將這些請求委派給具體建造者角色。具體建造者角色是做具體建造工作的,但卻不為客戶端所知。

三、程序舉例:

該程序演示了Builder模式一步一步完成構件復雜產品的過程。用戶可以控制生成過程以及生成不同對象。

// Builder pattern -- Structural example 
using System;
using System.Collections;
// "Director"
class Director
{
 // Methods
 public void Construct( Builder builder )
 {
  builder.BuildPartA();
  builder.BuildPartB();
 }
}
// "Builder"
abstract class Builder
{
 // Methods
 abstract public void BuildPartA();
 abstract public void BuildPartB();
 abstract public Product GetResult();
}
// "ConcreteBuilder1"
class ConcreteBuilder1 : Builder
{
 // Fields
 private Product product;
 // Methods
 override public void BuildPartA()
 {
  product = new Product();
  product.Add( "PartA" );
 }
 override public void BuildPartB()
 {
  product.Add( "PartB" );
 }
 override public Product GetResult()
 {
  return product;
 }
}
// "ConcreteBuilder2"
class ConcreteBuilder2 : Builder
{
 // Fields
 private Product product;
 // Methods
 override public void BuildPartA()
 {
  product = new Product();
  product.Add( "PartX" );
 }
 override public void BuildPartB()
 {
  product.Add( "PartY" );
 }
 override public Product GetResult()
 {
  return product;
 }
}
// "Product"
class Product
{
 // Fields
 ArrayList parts = new ArrayList();
 // Methods
 public void Add( string part )
 {
  parts.Add( part );
 }
 public void Show()
 {
  Console.WriteLine( " Product Parts -------" );
  foreach( string part in parts )
   Console.WriteLine( part );
 }
}
/**//// <summary>
/// Client test
/// </summary>
public class Client
{
 public static void Main( string[] args )
 {
  // Create director and builders
  Director director = new Director( );
  Builder b1 = new ConcreteBuilder1();
  Builder b2 = new ConcreteBuilder2();
  // Construct two products
  director.Construct( b1 );
  Product p1 = b1.GetResult();
  p1.Show();
  director.Construct( b2 );
  Product p2 = b2.GetResult();
  p2.Show();
 }
}

五、建造者模式的實現:

下面的程序代碼演示了Shop對象使用VehicleBuilders來建造不同的交通工具。該例子使用了Builder模式順序建造交通工具的不同部分。

// Builder pattern -- Real World example 
using System;
using System.Collections;
// "Director"
class Shop
{
 // Methods
 public void Construct( VehicleBuilder vehicleBuilder )
 {
  vehicleBuilder.BuildFrame();
  vehicleBuilder.BuildEngine();
  vehicleBuilder.BuildWheels();
  vehicleBuilder.BuildDoors();
 }
}
// "Builder"
abstract class VehicleBuilder
{
 // Fields
 protected Vehicle vehicle;
 // Properties
 public Vehicle Vehicle
 {
  get{ return vehicle; }
 }
 // Methods
 abstract public void BuildFrame();
 abstract public void BuildEngine();
 abstract public void BuildWheels();
 abstract public void BuildDoors();
}
// "ConcreteBuilder1"
class MotorCycleBuilder : VehicleBuilder
{
 // Methods
 override public void BuildFrame()
 {
  vehicle = new Vehicle( "MotorCycle" );
  vehicle[ "frame" ] = "MotorCycle Frame";
 }
 override public void BuildEngine()
 {
  vehicle[ "engine" ] = "500 cc";
 }
 override public void BuildWheels()
 {
  vehicle[ "wheels" ] = "2";
 }
 override public void BuildDoors()
 {
  vehicle[ "doors" ] = "0";
 }
}
// "ConcreteBuilder2"
class CarBuilder : VehicleBuilder
{
 // Methods
 override public void BuildFrame()
 {
  vehicle = new Vehicle( "Car" );
  vehicle[ "frame" ] = "Car Frame";
 }
 override public void BuildEngine()
 {
  vehicle[ "engine" ] = "2500 cc";
 }
 override public void BuildWheels()
 {
  vehicle[ "wheels" ] = "4";
 }
 override public void BuildDoors()
 {
  vehicle[ "doors" ] = "4";
 }
}
// "ConcreteBuilder3"
class ScooterBuilder : VehicleBuilder
{
 // Methods
 override public void BuildFrame()
 {
  vehicle = new Vehicle( "Scooter" );
  vehicle[ "frame" ] = "Scooter Frame";
 }
 override public void BuildEngine()
 {
  vehicle[ "engine" ] = "none";
 }
 override public void BuildWheels()
 {
  vehicle[ "wheels" ] = "2";
 }
 override public void BuildDoors()
 {
  vehicle[ "doors" ] = "0";
 }
}
// "Product"
class Vehicle
{
 // Fields
 private string type;
 private Hashtable parts = new Hashtable();
 // Constructors
 public Vehicle( string type )
 {
  this.type = type;
 }
 // Indexers
 public object this[ string key ]
 {
  get{ return parts[ key ]; }
  set{ parts[ key ] = value; }
 }
 // Methods
 public void Show()
 {
  Console.WriteLine( " ---------------------------");
  Console.WriteLine( "Vehicle Type: "+ type );
  Console.WriteLine( " Frame : " + parts[ "frame" ] );
  Console.WriteLine( " Engine : "+ parts[ "engine"] );
  Console.WriteLine( " #Wheels: "+ parts[ "wheels"] );
  Console.WriteLine( " #Doors : "+ parts[ "doors" ] );
 }
}
/**//// <summary>
/// BuilderApp test
/// </summary>
public class BuilderApp
{
 public static void Main( string[] args )
 {
  // Create shop and vehicle builders
  Shop shop = new Shop();
  VehicleBuilder b1 = new ScooterBuilder();
  VehicleBuilder b2 = new CarBuilder();
  VehicleBuilder b3 = new MotorCycleBuilder();
  // Construct and display vehicles
  shop.Construct( b1 );
  b1.Vehicle.Show();
  shop.Construct( b2 );
  b2.Vehicle.Show();
  shop.Construct( b3 );
  b3.Vehicle.Show();
 }
}

六、建造者模式的演化

建造者模式在使用的過程中可以演化出多種形式。

省略抽象建造者角色

如果系統中只需要一個具體建造者的話,可以省略掉抽象建造者。這時代碼可能如下:

// "Director"
class Director
{
 private ConcreteBuilder builder;
 // Methods
 public void Construct()
 {
  builder.BuildPartA();
  builder.BuildPartB();
 }
}

省略指導者角色

在具體建造者只有一個的情況下,如果抽象建造者角色已經被省略掉,那麼還可以省略掉指導者角色。讓Builder角色自己扮演指導者與建造者雙重角色。這時代碼可能如下:

public class Builder
{
 private Product product = new Product();
 public void BuildPartA()
 {
  //Some code here
 }
 public void BuildPartB()
 {
  //Some code here
 }
 public Product GetResult()
 {
  return product;
 }
 public void Construct()
 {
  BuildPartA();
  BuildPartB();
 }
}

同時,客戶端也需要進行相應的調整,如下:

public class Client
{
 private static Builder builder;
 public static void Main()
 {
  builder = new Builder();
  builder.Construct();
  Product product = builder.GetResult();
 }
}

C#中的StringBuilder就是這樣一個例子。

七、在什麼情況下使用建造者模式

以下情況應當使用建造者模式:

1、需要生成的產品對象有復雜的內部結構。

2、需要生成的產品對象的屬性相互依賴,建造者模式可以強迫生成順序。

3、在對象創建過程中會使用到系統中的一些其它對象,這些對象在產品對象的創建過程中不易得到。

使用建造者模式主要有以下效果:

1、建造模式的使用使得產品的內部表象可以獨立的變化。使用建造者模式可以使客戶端不必知道產品內部組成的細節。

2、每一個Builder都相對獨立,而與其它的Builder無關。

3、模式所建造的最終產品更易於控制。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved