2013年11月25日 星期一

Design Pattern : Mediator

Design Pattern : Mediator


Definition :
Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.
 
















IMediator : 存放多個要處理的IColleague物件,並定義這些IColleague物件交流、溝通的方法。
IColleague 必須知道對應的IMediator是誰。 另外裡面也可定義各自溝通方法的細節。

底下的範例是透過Mediator的架構,將三種不同型別的車子物件互相轉換(ICar, ICarMidRange, ICarEliteRange)。 定義好車子後,將車子放入各自的ConcreteColleague物件及定義轉換方法,Clinet存取時只要由Mediator去做轉換即可。

1.  IColleague:

public interface IColleague<T>
{
    
/// <summary>
     ///
Mediator
    
/// </summary>
    
IMediator<T> mediator { get;set; }
    
/// <summary>
     ///
實際要處理的物件
    
/// </summary>
    
T obj {get;set;}
}

2.  IMediator:

public interface IMediator<T>
{
   
/// IColleague集合
   
List<IColleague<T>> ColleagueList { get; }
   
/// 加入IColleague物件
   
void Register(IColleague<T> colleague);
   
/// 轉換方法
   
void Transfer(String newTypeName);
}


3.  ConcreteColleague :
=>
ToCarMidRange ToCarEliteRange 是轉換的細節方法,故省略之。

public class CarColleague<T> : IColleague<T>
{

   
public T obj {get;set;}

   
public IMediator<T> mediator { get; set; }

   
public CarColleague(IMediator<T> _mediator)
    {
       
this.mediator = _mediator;
    }
   
public ICarMidRange ToCarMidRange()
    {
//Skip the inside codes }
   
public ICarEliteRange ToCarEliteRange()
    {
//Skip the inside codes }
}

4.  ConcreteMediator:
=>
CarMediator 實作了IMediator,重點在於Transfer這個方法中必須確保集合中已有物件,另外轉換的實際的方法是寫在ConcreteClleague裡面,但也可以選擇放在其他類別。

public
class CarMediator<T> : IMediator<T>
{

   
private List<IColleague<T>> colleagueList = null;
   
public CarMediator()
    {
      
this.colleagueList = new List<IColleague<T>>();
    }
   
public List<IColleague<T>> ColleagueList
    {
get { return this.colleagueList; } }
   
   
public void Transfer(String newTypeName)
    {
        
if (this.colleagueList.Count == 2)
         {
            
if (newTypeName == typeof(ICarMidRange).Name)
             {
               
object newCar = (this.colleagueList[0] as CarColleague<T>).ToCarMidRange() as object;
               
this.colleagueList[1].obj = (T)newCar;
             }
            
else if (newTypeName == typeof(ICarEliteRange).Name)
             {
               
object newCar = (this.colleagueList[0] as CarColleague<T>).ToCarEliteRange() as object;
               
this.colleagueList[1].obj = (T)newCar;
             }
            
else {
               
throw new Exception("無法轉換,因為尚未定義轉換方法!");
             }
         }
        
else { throw new Exception("尚未加入任何Colleague物件!"); }
    }
  
   
public void Register(IColleague<T> colleague)
    {
      
this.colleagueList.Add(colleague);
    }
}

5.  主程式: 這邊列出從ICar轉換為ICarMidRange的部分

ICar focus = new Focus();
focus.Color =
Color.Blue;
focus.Name =
"胖兔二號";
focus.Equipment =
"FHD行車紀錄器,倒車雷達";

//Mediator
IMediator<ICar> mediator = new CarMediator<ICar>();

//
建立一個要轉換的CarColleague
IColleague<ICar> colleagueBefore = new CarColleague<ICar>(mediator);
colleagueBefore.obj = focus;

//建立一個轉換後的CarColleague
IColleague<ICar> colleagueAfter = new CarColleague<ICar>(mediator);
colleagueAfter.obj =
new CarMidRangePrototype();

//註冊ColleagueMediator
mediator.Register(colleagueBefore);
mediator.Register(colleagueAfter);

mediator.Transfer(
typeof(ICarMidRange).Name);

6.  Reference
Mediator Design Pattern


沒有留言:

張貼留言