Quantcast
Channel: cc :: somkiat
Viewing all articles
Browse latest Browse all 2036

ว่าด้วยเรื่องของ Delegator และ Callback ใน Swift

$
0
0

lego-00

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 ดังนี้ [gist id="c4801f76d04041bfeb645392645431ac" file="NetworkDelegator.swift"] จากนั้นในส่วนของ Network ที่ทำหน้าที่ดึงข้อมูลจาก API ก็ทำการสร้างตัวแปรสำหรับ delegator มาซะ ดังนี้ [gist id="c4801f76d04041bfeb645392645431ac" file="MyNetwork.swift"] สุดท้ายทาง View Controller ก็ทำการ implement protocol NetworkDelegator ซะ จากนั้นจึงเริ่มใช้งาน [gist id="c4801f76d04041bfeb645392645431ac" file="MainViewController.swift"] ทำให้เราสามารถแยกส่วนการทำงานต่าง ๆ ออกจากกันอย่างชัดเจน คือ
  • 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 เรียกใช้งาน [gist id="c4801f76d04041bfeb645392645431ac" file="MyNetwork2.swift"] จากนั้นทางฝั่ง ViewController ก็เรียกใช้ง่าย ๆ โดยเรียกตรงมายัง MyNetwork เลย ไม่จำเป็นต้องมี Delegator อีกต่อไป ดังนี้ [gist id="c4801f76d04041bfeb645392645431ac" file="MainViewController2.swift"] จะเห็นได้ว่าเราสามารถนำ callback มาใช้แทน delegator ได้เลย แถมมันเป็นสิ่งที่มีมาใน swift อยู่แล้ว แถมลดจำนวน code ลงไปอีกนะ แถมนำไปใช้กับ property observer ของตัวแปรต่าง ๆ ได้อีกด้วย รวมทั้งช่วยทำให้สามารถทดสอบระบบงานได้ง่ายกว่าเดิมอีก ลองใช้แล้วจะติดใจ !! ปล. ทั้งสองเรื่องนี้คือพื้นฐานที่นักพัฒนาไม่ควรพลาด แถมมันยังเป็นพื้นฐานของ Reactive Programming อีกด้วย
วันนี้ Swift developer ใช้แบบไหนกันอยู่บ้าง ?
Source code ตัวอย่างอยู่ที่ Github :: Up1

Viewing all articles
Browse latest Browse all 2036

Trending Articles