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

ว่าด้วยเรื่อง Android Application Architecture ที่ดี

$
0
0

Screen Shot 2558-11-26 at 10.38.29 AM

Screen Shot 2558-11-26 at 10.38.29 AM จากงาน Android Dev Summit 2015 นั้น มีหัวข้อที่น่าสนใจเยอะเลย หนึ่งในนั้นคือ Android Application Architecture ได้อธิบายสิ่งต่าง ๆ ที่น่าสนใจสำหรับการพัฒนา Android application แต่หัวข้อที่ชอบมาก ๆ คือ โครงสร้างการทำงานของระบบ มาดูกันว่าเป็นอย่างไร

เริ่มต้นได้อย่างน่าคิด

อะไรที่คุณตัดสินใจไปแล้วมันจะอยู่กับคุณไปตลอด ดังนั้นคิดให้ดี ๆ โดยโครงสร้างของ app ที่คิดขึ้นมานั้น มันจะง่าย หรือ ยาก ให้คิดถึงปัญหาที่ต้องการแก้ไขเป็นหลัก ไม่ใช่คิดถึง วิธีการแก้ไขปัญหา หรือ framework หรือ library เป็นหลัก !! คำถามต่อมา น่าคิดมาก ๆ คือ แล้วโครงสร้างของระบบจะเป็นแบบไหนดีล่ะ ?
  • MVC
  • MVP
  • MVP-I
  • MVVM
  • MVVM-I
  • VIPER
  • Clean Architecture
  • Reactive
  • Flux
  • ...
พบว่ามันมีหลายแนวทางมาก ๆ !! (Paradox of choices) แต่แนะนำว่า อย่าไปยึดติดกับ desing pattern อย่าไปยึดติดกับ Library อย่าไปยึดติดกับ Framework เพราะว่ามันจะจำกัดกรอบความคิดของเรามากเกินไป ให้เน้นไปที่การแก้ไขปัญหาดีกว่า ทุกแนวทางนั้น ล้วนมีเป้าหมายเดียวกัน คือ สามารถเปลี่ยนแปลงได้รวดเร็ว นั่นคือ สามารถ refactoring ได้ง่าย รวมไปถึงทดสอบการทำงานแต่ละส่วนได้ง่าย เพื่อป้องกันไม่ให้เกิดสิ่งที่เรียกว่า Lava flow

สิ่งที่แนะนำในการออกแบบ คือ Architect for UX (User Experience)

มันเป็นอย่างไรล่ะ ? ตัวอย่าง App ต้องทำการส่งข้อมูลไปยัง server คำถามคือ จะขึ้นรูป loading ทำไม ? แถมบางครั้งถ้า network มีปัญหา รูป loading มันไม่หายไปด้วย ทำให้ app ปิดตัวเองอีก ซึ่งเป็นประสบการณ์การใช้งานที่ไม่ดีเลยใช่ไหม ? แสดงการทำงานดังรูป Screen Shot 2558-11-26 at 10.53.04 AM ปัญหาจากรูปแบบการทำงานนี้ คือ View จะรอไปจนกว่าจะได้ข้อมูลจาก ViewController และ Network นั่นคือ ViewController มันผูกติดกับ Network อย่างมาก !! สามารถแก้ไขด้วยการแยก ViewController ออกจาก Network ซะ ด้วยการเพิ่มอีกหนึ่งส่วน หรือ อีกหนึ่ง layer นั่นคือ Model เนื่องจาก ViewController นั้นต้องการเพียงข้อมูลเพื่อส่งไปแสดงผลที่ View เท่านั้น ไม่ได้ต้องการ Network เลย แสดงการทำงานดังรูป Screen Shot 2558-11-26 at 10.55.30 AM แต่จากรูปแบบนี้ก็ยังคงมีปัญหากับ Network อยู่ใช่ไหม ? เนื่องจากเราเพียงย้ายให้ Network ไปทำงานกับ Model เท่านั้นเอง ดังนั้น จะแก้ไขปัญหานี้อย่างไรดีล่ะ ? สิ่งที่ต้องทำก็คือ Model นั้นให้เป็น Persistent model ที่อยู่บนเครื่อง หรือ Local ซะ และเพิ่มส่วนของ Application Logic ขึ้นมา เพื่อทำงานร่วมกับ Network แทน โดยแบ่งการทำงานเป็นส่วน ๆ ดังนี้ ส่วนที่ 1 เมื่อ Application logic ได้ข้อมูลจาก Network หรือ sync data เรียบร้อยแล้ว จะทำการส่ง หรือ จัดเก็บไปที่ Persistent Model แสดงการทำงานดังรูป Screen Shot 2558-11-26 at 11.06.54 AM ส่วนที่ 2 ส่วนของ ViewController เมื่อต้องการข้อมูลไปแสดงผลที่ View ก็ให้ทำการดึงข้อมูลจาก Persistent Model แทน ซึ่งไม่ต้องรออะไรเลย แสดงการทำงานดังรูป Screen Shot 2558-11-26 at 11.09.24 AM ส่วนที่ 3 เมื่อมีการร้องขอ หรือ ส่งข้อมูลมาจากผู้ใช้งานผ่าน View จะทำการส่งการร้องขอมายัง ViewController จากนั้นจะส่งการร้องขอไปยัง Application Logic เพื่อทำงาน ซึ่งจะทำงาน 2 อย่าง คือ
  1. ทำการ update ข้อมูลที่ Persistent Model
  2. ทำการส่งข้อมูลไปยัง Network
จากนั้นเมื่อฝั่ง Network ส่งข้อมูลกลับมายัง Application Logic แล้ว จะทำการ update ข้อมูลที่ Persistent Model และแจ้งกลับไปยัง ViewController ว่าคำร้องขอเสร็จเรียบร้อยแล้ว แสดงการทำงานดังรูป Screen Shot 2558-11-26 at 11.10.50 AM

มาถึงตรงนี้อาจจะงงอีกว่า จะแจ้งกลับไปยัง ViewController ยังไงว่าทำงานเสร็จแล้ว ?

น่าคิดมาก ๆ ดังนั้นในขั้นตอนการส่งคำร้องขอตั้งแต่แรก ต้องมีการจัดการ event หรือ เหตุการณ์ต่าง ๆ ไว้ก่อนนะ นั่นคือมีการ register event และ subscribe ไว้ เมื่อมีการทำการเสร็จสิ้นก็ให้ทำการส่ง notify ไปยัง subscribe นั้น ๆ จากนั้นก็ทำการ unsubscribe ซะ เป็นอันพบขั้นตอนการทำงาน แนวคิดพวกนี้มันคือ EventBus นั่นเอง แต่ทำมาเยอะขนาดนี้ มันก็ยังไม่ปัญหาตามมาอีก นั่นคือ เรื่องของ Background process ถ้า queue การทำงานมันค้าง และ เต็ม ทำให้ process อื่น ๆ ที่อยู่ใน queue รอไปเรื่อย ๆ จะส่งผลให้ app ค้าง หรือ ปิดตัวไปอีก แสดงการทำงานดังรูป Screen Shot 2558-11-26 at 11.24.26 AM การแก้ไขปัญหานี้คือ ก็ให้แยก queue ของการทำงานให้ทำงานคนละ Thread ไป นั่นคือ
  • Network task queue
  • Local task queue
ส่งผลให้ app ของเราทำงานได้รวดเร็ว (Responsive) แสดงการทำงานดังรูป Screen Shot 2558-11-26 at 11.28.45 AM

สามารถสรุปการทำงานในส่วนของ Activity สำหรับการ Notify ได้ดังนี้ ( Activity State Machine )

  • onCreate() ทำการ setup พวก User Interface ต่าง ๆ
  • onStart() ทำการ register event เช่น การดึงข้อมูล
  • เมื่อเกิด event ขึ้นมา หรือ onEvent() หรือ ดึงข้อมูลเสร็จแล้ว จะทำการ refesh ข้อมูลใหม่
  • onStop() ทำการ unregister event
ซึ่งจะเห็นได้ว่ามันเรียบง่าย และง่ายต่อการทำความเข้าใจอย่างมาก

Key Takeaway มีดังนี้

  • Design for offline เนื่องจากเรื่องของ network มันไม่เคยเป็นมิตรกับใครเลย
    • ให้ส่วนของ User Interface ใช้ข้อมูลจาก model
    • ส่วนของ network และการ update model ให้ Application Logic จัดการ
    • ให้แต่ละส่วนทำงานเป็นอิสระจากกัน อาจจะใช้งาน Event, Callback หรืออะไรก็ได้ที่จำเป็น
  • Decoupling แต่ละส่วนแยกกันทำงาน
    • สามารถนำ Dependency Injection มาใช้งานได้
    • มันมีทั้งข้อดีและข้อเสีย ต้องทำความเข้าใจก่อน ไม่ใช่ทำตาม ๆ กันไป
    • อย่าใช้ Reflection API โดยเด็ดขาด เพราะว่ามันทำให้ performance ต่ำลงไปมาก ดังนั้นเลือก library ให้ระวังกันด้วย
  • Design API
    • ออกแบบ API เพื่อฝั่ง client หรือ ผู้ใช้งานนะ
    • ให้ฝั่ง client ทำงานน้อยที่สุด
    • ให้ฝั่ง server ทำงานมากที่สุด
  • Act locally, Sync Globally !!
และยังมีเรื่องอื่น ๆ อีกมากมาย ลองดูต่อจาก VDO ข้างต้นได้เลยครับ มีสิ่งที่น่าสนใจให้เราเรียนรู้อีกมากมาย

Viewing all articles
Browse latest Browse all 1997

Trending Articles