五、另外一個實際應用Bridge模式的例子
該例子演示了業務對象(BusinessObject)通過Bridge模式與數據對象(DataObject)解耦。數據對象的實現可以在不改變客戶端代碼的情況下動態進行更換。
// Bridge pattern -- Real World example
using System;
using System.Collections;
// "Abstraction"
class BusinessObject
{
// FIElds
private DataObject dataObject;
protected string group;
// Constructors
public BusinessObject( string group )
{
this.group = group;
}
// PropertIEs
public DataObject DataObject
{
set{ dataObject = value; }
get{ return dataObject; }
}
// Methods
virtual public void Next()
{ dataObject.NextRecord(); }
virtual public void Prior()
{ dataObject.PriorRecord(); }
virtual public void New( string name )
{ dataObject.NewRecord( name ); }
virtual public void Delete( string name )
{ dataObject.DeleteRecord( name ); }
virtual public void Show()
{ dataObject.ShowRecord(); }
virtual public void ShowAll()
{
Console.WriteLine( "Customer Group: {0}", group );
dataObject.ShowAllRecords();
}
}
// "RefinedAbstraction"
class CustomersBusinessObject : BusinessObject
{
// Constructors
public CustomersBusinessObject( string group )
: base( group ){}
// Methods
override public void ShowAll()
{
// Add separator lines
Console.WriteLine();
Console.WriteLine( "------------------------" );
base.ShowAll();
Console.WriteLine( "------------------------" );
}
}
// "Implementor"
abstract class DataObject
{
// Methods
abstract public void NextRecord();
abstract public void PriorRecord();
abstract public void NewRecord( string name );
abstract public void DeleteRecord( string name );
abstract public void ShowRecord();
abstract public void ShowAllRecords();
}
// "ConcreteImplementor"
class CustomersDataObject : DataObject
{
// FIElds
private ArrayList customers = new ArrayList();
private int current = 0;
// Constructors
public CustomersDataObject()
{
// Loaded from a database
customers.Add( "Jim Jones" );
customers.Add( "Samual Jackson" );
customers.Add( "Allen Good" );
customers.Add( "Ann Stills" );
customers.Add( "Lisa Giolani" );
}
// Methods
public override void NextRecord()
{
if( current <= customers.Count - 1 )
current++;
}
public override void PriorRecord()
{
if( current > 0 )
current--;
}
public override void NewRecord( string name )
{
customers.Add( name );
}
public override void DeleteRecord( string name )
{
customers.Remove( name );
}
public override void ShowRecord()
{
Console.WriteLine( customers[ current ] );
}
public override void ShowAllRecords()
{
foreach( string name in customers )
Console.WriteLine( " " + name );
}
}
/**//// <summary>
/// ClIEnt test
/// </summary>
public class BusinessApp
{
public static void Main( string[] args )
{
// Create RefinedAbstraction
CustomersBusinessObject customers =
new CustomersBusinessObject(" Chicago ");
// Set ConcreteImplementor
customers.DataObject = new CustomersDataObject();
// Exercise the bridge
customers.Show();
customers.Next();
customers.Show();
customers.Next();
customers.Show();
customers.New( "Henry Velasquez" );
customers.ShowAll();
}
}
六、在什麼情況下應當使用橋梁模式
根據上面的分析,在以下的情況下應當使用橋梁模式:
如果一個系統需要在構件的抽象化角色和具體化角色之間增加更多的靈活性,避免在兩個層次之間建立靜態的聯系。
設計要求實現化角色的任何改變不應當影響客戶端,或者說實現化角色的改變對客戶端是完全透明的。
一個構件有多於一個的抽象化角色和實現化角色,系統需要它們之間進行動態耦合。
雖然在系統中使用繼承是沒有問題的,但是由於抽象化角色和具體化角色需要獨立變化,設計要求需要獨立管理這兩者。