lego-00
วันนี้นั่งดูและเขียน code ด้วยภาษา Swift สำหรับพัฒนา iOS app
พบว่าในหลาย ๆ ส่วนการทำงานใช้ Delegate pattern
เพื่อเชื่อมต่อการทำงานในแต่ละส่วน เช่น

  • User Interface
  • Data model
  • Networking layer
  • Service layer
  • Helper class

มีเป้าหมายเพื่อไม่ให้ code ผูกติดกันมากจนเกินไป หรือ เรียกว่า Loose coupling
แต่ละส่วนแยกกันทำงานชัดเจน
แต่ทำให้ code ที่พัฒนาด้วยภาษา Swift เต็มไปด้วย protocol !!

คำถามที่น่าสนใจคือ มันมีวิธีการอื่นที่ดีกว่านี้ไหม ?

ก่อนอื่นมาทำความรู้จักกับ Delegator หรือ Listener

ว่า code ที่พัฒนาด้วยภาษา Swift มันมีรูปแบบอย่างไรบ้าง ?

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

ดังนั้นเราจำเป็นต้องมีคนกลางหรือตัวแทน
ของ Network layer เพื่อมาเชื่อมการทำงานกับ ViewController
หรือเรียกส่วนนี้ว่า Delegator นั่นเอง

เพื่อความไม่งง มาดู code ตัวอย่างกันดีกว่า
ซึ่งมักจะสร้าง Delegator ด้วย protocol ดังนี้

จากนั้นในส่วนของ Network ที่ทำหน้าที่ดึงข้อมูลจาก API
ก็ทำการสร้างตัวแปรสำหรับ delegator มาซะ ดังนี้

สุดท้ายทาง View Controller ก็ทำการ implement protocol NetworkDelegator ซะ
จากนั้นจึงเริ่มใช้งาน

ทำให้เราสามารถแยกส่วนการทำงานต่าง ๆ ออกจากกันอย่างชัดเจน คือ

  • ViewController ทำหน้าที่แสดงผล และ ดักจับการใช้งานจากผู้ใช้งาน
  • Network ทำหน้าที่ดึงข้อมูลจาก API ผ่านระบบ Network
  • Delegator คือตัวกลางที่ช่วยทำให้ทั้ง ViewController และ Network ทำงานร่วมกับแบบหลวม ๆ และทำงานแบบ Asynchronuous

ทุกอย่างทำงานได้ดี ปกติ ไม่มีปัญหาอะไรเลย

แต่เมื่อมานั่งคิดดู
ถ้าไม่อยากส่งค่าของ delegator จาก ViewController ไปยัง Network ได้หรือไม่ ?
ถ้าใน ViewController มี delegator จำนวนมาก ก็ไม่น่าจะสนุก หรือ ดีนะ ?
เพราะว่า ต้องส่ง object reference ของ delegator ไป
ดังนั้นมีวิธีอะไรที่ดีกว่านี้หรือไม่ ?

หนึ่งในแนวคิดที่น่าสนใจคือ Callback

ซึ่งมีแนวคิดคล้าย ๆ กับ Delegate เลย
ต่างกันเพียงแทนที่จะส่ง object reference ไป
ก็ให้ส่ง function กันไปเลย
โดยในภาษา Swift นั้น function คือ first class อยู่แล้ว
จะรอช้าไปทำไมเขียน code กันดีกว่า

เริ่มจากการแก้ไขไฟล์ MyNetwork.swift
ด้วยการสร้าง callback function ชื่อว่า onSuccess ขึ้นมา
เพื่อให้ทาง ViewController เรียกใช้งาน

จากนั้นทางฝั่ง ViewController ก็เรียกใช้ง่าย ๆ
โดยเรียกตรงมายัง MyNetwork เลย
ไม่จำเป็นต้องมี Delegator อีกต่อไป ดังนี้

จะเห็นได้ว่าเราสามารถนำ callback มาใช้แทน delegator ได้เลย
แถมมันเป็นสิ่งที่มีมาใน swift อยู่แล้ว
แถมลดจำนวน code ลงไปอีกนะ
แถมนำไปใช้กับ property observer ของตัวแปรต่าง ๆ ได้อีกด้วย
รวมทั้งช่วยทำให้สามารถทดสอบระบบงานได้ง่ายกว่าเดิมอีก
ลองใช้แล้วจะติดใจ !!

ปล. ทั้งสองเรื่องนี้คือพื้นฐานที่นักพัฒนาไม่ควรพลาด
แถมมันยังเป็นพื้นฐานของ Reactive Programming อีกด้วย

วันนี้ Swift developer ใช้แบบไหนกันอยู่บ้าง ?

Source code ตัวอย่างอยู่ที่ Github :: Up1