Cocoa Programming: Delegate

Delegate

คือ object ที่ทำหน้าที่เสมือนตัวแทนของ object อื่น เหมือนเวลาเราไปกินข้าวนอกบ้าน สมมติว่าเราอยากกินข้าวผัด เราก็อาจจะไปสั่งให้พ่อครัวทำให้เรา หรือเราก็สั่งข้าวผัดจากพนักงาน พนักงานก็จะไปบอกคนทำเก็บเงินว่าเราสั่งรายการอะไรไป และก็เดินไปบอกพ่อครัวอีกทีว่าให้ทำข้าวผัด สุดท้ายก็ได้ข้าวผัดมาเหมือนกัน อธิบายในแบบรูปภาพอาจจะมองได้เป็นแบบนี้

ลองดูตัวอย่าง Code ภาษา C/C++ ต่อไปนี้

สมมติว่าเรามี Class Chef ดังตัวอย่างข้างล่าง

และมี Class Waiter ดังตัวอย่างข้างล่าง

จากตัวอย่างจะเห็นว่าถ้าหากประกาศ Waiter แล้วเรียกใช้ servFood ก็ได้ผลลัพธ์เหมือนกับ Chef

ทีนี้ลองดูตัวอย่าง ที่ยากขึ้นหน่อย โดยเราทำการแก้ไข Waiter ใหม่ เพื่อให้เป็น delegate ในลักษณะแบบนี้

และเราก็มี class เพิ่มขึ้นมาอีก 1 สมมติให้ชื่อว่า PizzaChef โดย inherit จาก Chef

และเราก็เขียนโปรแกรมขึ้นมาทดสอบ ดังตัวอย่าง

และก็จะได้ผลลัพธ์ แบบนี้

Hamburger for you
Pizza for you

ในการเขียน Program ด้วย Cocoa มีการใช้ delegate instance เป็นลักษณะของ Helper Object โดยจุดประสงค์หลักๆคืิอ เพื่อให้ class ที่ inherit ไปนั้นสามารถเพิ่มเติมและแก้ไขการตอบสนองต่อ event ได้ง่ายขึ้น ยกตัวอย่างเช่นว่า ในการ close window เมื่อ event เกิดขึ้น object ต่างๆที่อยู่บน window นั้นมีข้อจำกัดในการรับรู้ว่า ส่วนอื่นๆมีการเปลี่ยนแปลงหรือไม่ ลองดูภาพข้างล่าง

จากรูปเมื่อเรา กด close หน้าต่าง window จะส่ง WindowShouldClose ไปถาม delegate ว่าควรจะทำอะไร ถ้าหากว่าไม่ได้ทำการ implement อะไรไว้ก็จะ ส่งค่ากลับมาทันที  แต่ถ้าเกิดว่าได้ implement ไว้อย่างเช่นเป็นต้นว่า มีการตรวจสอบก่อนว่าต้องการ ที่จะ save file ก่อนหรือไม่ ก็จะทำงานตรงนี้ก่อนแล้วค่อยส่งค่ากลับไป ต่อไปก็คือการนำไปใช้ ตัวอย่างที่เห็นได้ชัดๆใน Cocoa Programming คือการใช้งาน กับ NSTableView เดี๋ยวครั้งหน้าผมจะเขียนการใช้งาน delegate และ NSTableView น่าจะเข้าใจมากขึ้น

5 thoughts on “Cocoa Programming: Delegate”

  1. มีแต่คนเก่ง ๆ -*- ทำไมผมเขียนโปรแกรมแบบ Obj ไม่เป็นเลยเนี่ย งงๆๆ

  2. พอดี งงๆ ครับ
    ตรง class waiter ตัวใหม่ที่ถูกปรับเป็น delegate นี่
    method void foo() มันควรจะเป็น servFood() รึเปล่าครับ
    ถ้าเสร็จแล้วก็เป็นแบบนี้
    class Waiter {
    public:
    Waiter(Chef* new_chef) : Waiter(new_chef) {}
    Chef* c;
    void servFood() {
    c->servFood();
    }
    };

    ที่ผมคิดถูกมั้ยครับ

  3. ไม่เหมือนครับ ถ้าเป็นลักษณะ listener จะเป็น notification ครับ

  4. ก็เหมือนกับพวก onMouseOver, onDialogClose ใน VC++ ใช่มั้ยครับ แบบ ติด listener เอาไว้

Leave a Reply