Delegate

Delegate 中文叫「委派」。

將某些操作(例如是否相等)的細節交給 object 自己處理。

用一點簡單的 code 來說明。首先是沒有 delegate 的寫法(這裡先不管 member 放在 public 不是好習慣的問題):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Foo
{
public:
Foo(int x, int y) : m_x(x), m_y(y) { };

int m_x;
int m_y;
};

int main()
{
Foo foo1(10, 20), foo2(200, 300);

if (foo1.m_x == foo2.m_x && foo1.m_y == foo2.m_y)
{
// do sth.
}

return 0;
}

這種方式,當在任何地方需要比較兩個 Foo object 時,都要像上面第 14 行這樣寫。不覺得這樣都把 Foo 肚子裡的東西挖出來到處亂放嗎?如果之後 Foo 要多加一個 member,所有比較 Foo object 的地方都要改,光是有 20 個地方要改就有得受了,更何況還可能漏掉勒。所以啦,delegate 的觀念就可以在這裡拯救可憐的工程師,以下是有 delegate 觀念的版本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Foo
{
public:
Foo(int x, int y) : m_x(x), m_y(y) { };

bool IsEqual(const Foo& rFoo) const
{
return (m_x == rFoo.m_x && m_y == rFoo.m_y);
};

int m_x;
int m_y;
};

int main()
{
Foo foo1(10, 20), foo2(200, 300);

if (foo1.IsEqual(foo2))
{
// do sth.
}

return 0;
}

增加 IsEqual() 後,我們就可以把判斷放進 class Foo,由 Foo 自己處理如何判斷相等的這件事。外面只需要 call IsEqual() 就可以比較兩個 Foo object,也就是外界將判斷相等的事情「委派」給 Foo。這時候如果多加一個 member m_z,只需要改 IsEqual() 的 implement 就可以了,外面 20 個比較的地方都不用改!世界變得一片美好。

文言一點來說,delegate 有助於保持 loosely coupled。loosely coupled 表示 object 彼此獨立(也可以看成 object 跟其他 code),對一 object 的修改不會引起一連串其他 object 或 code 的修改。

問題時間

  • 為什麼不用 C++ 的 operator==

    operator== 也可以。這裡想表達的是 delegate 的觀念,如何實作不是重點。反過來說,不同語言也有不同的特性跟用法,而一個觀念可以用很多種方式實作。

  • 為什麼感覺有封裝的味道?

    我也這麼覺得。一些 OO 原則跟觀念彼此根本一家親,運用 A 的同時也運用了 B。我暫時想不出更好的範例了,就先這樣吧!:P