標籤

2012年4月8日 星期日

Delegate

http://seruziu.blogspot.com/search/label/Delegate
| 11/26/2011

這種設計原則的作法,是讓 reciver 授權委託給 delegatee 物件來處理所接收到的訊息。如此一來,就可以模糊化 reciver 介面設計。這種設計方法大量被 Cocoa Framework 所使用,原因就在於將所屬職責委託出去,可以減少 reciver 負擔工作的種類,並且可以因為 delegatee 的設計的適應各種不同的狀況,增加程式設計上面的彈性。

在這裡舉一個例子:今天,SDK 裡面設計了表格物件。表格大概是我們最常見到用來分類、統整項目的方法。可是,根據需求不同,表格顯示資料的過濾方式、算法、資料的取得都會有所不同。設計表格物件的設計師不可能有辦法先把所有的狀況建立在表格物件裡面。所以設計便成為,當表格需要顯示資料的時候,它會向表格所授權的 delegatee 要求、取得資料之後,再自行顯示。


下面用一個比較簡單的實作例子,我們要求一個區塊物件,去繪製一個圖型:

@protocol FrameDelegate
@required
- (void)draw;
@end

@interface Frame : NSObject {
    uint32 bound_x;   // 相對整個畫面的座標
    uint32 bound_y;
    uint32 width;    // 框架的長、寬
    uint32 height;

    id delegate;
}
- (void)draw;
- (void)setDelegate:(id <FrameDelegate>)obj;
@end

我們可以看到,Frame 物件具有一個方法:draw。這個方法可以在框架所決定的區塊裡面繪製東西,可是我們並不知道到底要會製成什麼東西,所以我們就建立兩個物件:

Shape <----- Circle
Shape <----- Square

我們這裡,Shape 可以當做是一個母物件,並且遵守 FrameDelegate 協定,必須要有 draw 方法。如此一來,框架的實作本身就可以很簡單的:

@implementation
... (do something)

- (void)draw {
// some work here
    [delegate draw];
}
... (do something)
@end



在實際應用上面,就成了以下這個樣子:

Frame *f1;
Frame *f2;
Circle *c;
Square *s;

[f1 setDelegate:c];
[f2 setDelegate:s];

[f1 draw];   // 畫出圓形
[f2 draw];   // 畫出方形


Delegate 是 Cocoa Framework 裡面常用的技法,這得要記得喔!

沒有留言:

張貼留言