แชร์เรื่องนี้
MVVM ใน Kotlin Android Architecture
โดย Seven Peaks เมื่อ 9 ธ.ค. 2020, 10:31:00
Kotlin, Koin, Room และอื่นๆ ที่เกี่ยวข้อง

ในบทความนี้เราจะเจาะลึกเกี่ยวกับเรื่อง Android development โดยเน้นไปที่แนวทางปฏิบัติ MVVM ที่ดีที่สุดใน Kotlin โดยจะอธิบายการผสานรวมของส่วนประกอบที่จำเป็น เช่น Retrofit, Coroutines, Room, Koin และอื่นๆ ซึ่งได้รับการกล่าวถึงอย่างละเอียดในงาน Seven Peaks Speak: Android Meetup
ตลอดทั้งบทความนี้ เราจะแนะนำคุณผ่านโปรเจกต์ Android ที่ตรงไปตรงมา พร้อมการสาธิตที่ครอบคลุมและคำอธิบายอย่างละเอียดสำหรับแต่ละขั้นตอน
Model, View, และ ViewModel
MVVM ใน Kotlin คือการรวมตัวกันของคำว่า Model, View, และ ViewModel ซึ่งสถาปัตยกรรมแบบ structural-design-pattern ใหม่นี้สามารถตอบสนองข้อจำกัดที่มีอยู่ใน design pattern แบบดั้งเดิม เช่น MVP (Model-View-Presenter) และ MVC (Model-View-Controller) อย่างไรก็ตาม สิ่งนี้ยังคงมีลักษณะเฉพาะบางประการคล้ายกับ design pattern แบบ MVP (Model, View, Presenter) โดยเฉพาะอย่างยิ่ง ViewModel ใน MVVM ที่จะรับบทบาทเป็นตัวเอกใน MVP
วิธีเริ่มโปรเจกต์ใหม่
เรามาเริ่มกระบวนการเริ่มต้นโปรเจกต์ใหม่ โดยเลือกตั้งค่าภาษาที่ใช้เป็น Kotlin และคลิกเลือก "Use androidx libraries" เพื่อให้สอดคล้องกับเทรนด์ล่าสุดของ Android
ต่อไป เราจะทำให้แอปพลิเคชันทำงานสำหรับการทดสอบอย่างรวดเร็ว ทางด้านซ้ายเรามี empty activity ในขณะที่ทางด้านขวาจะเป็นบริเวณที่แจ้งว่า activity ถูกจัดเก็บเรียบร้อยแล้ว
เพื่อปรับปรุงแอปพลิเคชัน เราจะผสานรวม ViewModel และ Data Binding โดย ViewModel จะเก็บเฉพาะ LiveData object ซึ่งเป็นเพียงค่าที่สามารถสังเกตได้จาก view ด้วยวิธีการ observe ด้วยการใช้ประโยชน์จาก DataBinding เราจะส่งการอ้างอิง ViewModel ไปยัง view และ TextView จะแสดงข้อความจาก object ที่ observable ได้ของ ViewModel
ตอนนี้ ได้เวลาสร้าง instance ของ ViewModel และเชื่อมต่อกับ layout โดยใช้ไลบรารีการเชื่อมโยงข้อมูล สำหรับสิ่งนี้ เราจะใช้ class ที่เป็นประโยชน์ซึ่งจัดทำโดยไลบรารี Jetpack ซึ่งตอนนี้เรากำลังใช้ ViewModelProviders ซึ่งสร้าง ViewModel instance และใช้การเชื่อมโยงข้อมูลเพื่อผูกเข้ากับ layout ได้อย่างราบรื่น
Coroutines และ Retrofit (แบบจำลองและการติดตั้งเพิ่มเติม)
เราจะทำการรวมไลบรารี Retrofit และ Coroutines เพื่อเพิ่มประสิทธิภาพของโปรเจกต์ โดยชุดติดตั้งเพิ่มเติมจะประกอบด้วยไลบรารี 3 รายการ อย่างแรกคือไลบรารีหลักที่อนุญาตให้คุณดำเนินการตามคำขอใน REST API ต่อมาคือ converter-moshi ที่ช่วยให้เราแปลง JSON เป็นหนึ่งในโมเดลของแอปพลิเคชันของเรา และ logging-interceptor ที่ใช้เพื่อวัตถุประสงค์ในการ debug
ถัดไป สร้าง Retrofit service โดยเปิดใช้งาน HTTP method ไปยัง API โดยจุดนี้คำว่า "suspend" จะเข้ามามีบทบาทสำคัญ ซึ่งบ่งบอกถึงการรวมเข้ากับ coroutines เพื่อดำเนินการตามคำขอที่ทำงานอยู่เบื้องหลัง สิ่งสำคัญคือต้องหลีกเลี่ยงการใช้ฟังก์ชัน Suspend โดยตรงใน UI thread เมื่อใช้ coroutines เนื่องจากการเรียก API อาจใช้เวลาพอสมควร
ใน ViewModel เราใช้ ViewModelScope ที่จัดทำโดยวงจรชีวิตของ KTX library และภายใน scope นั้น เราจะใช้การเรียกเครือข่ายบน IO thread
อย่างไรก็ตาม เป็นที่น่าสังเกตว่าบริการ API ที่สร้าง instance โดยตรงใน ViewModel ไม่ถือเป็นแนวทางปฏิบัติที่ดีนัก ตัวอย่างเช่น หากมีสิบโมเดล การสร้าง Retrofit instance สำหรับแต่ละโมเดลทีละรายการจะไม่มีประสิทธิภาพ เพื่อแก้ไขปัญหานี้ เราขอแนะนำให้ใช้ injection library ต่อกัน ซึ่งช่วยปรับปรุงโครงสร้างโค้ดและเพิ่มประสิทธิภาพได้อย่างมาก
Koin
หากต้องการเพิ่ม Koin library ให้รวมไว้ในไฟล์ build.gradle ของโมดูลเอาไว้
ต่อไปจะแนะนำโมดูลเครือข่ายที่เราได้จัดเตรียม Retrofit instance เอาไว้ สิ่งนี้จะเกี่ยวข้องกับการสร้างโมดูลเครือข่ายเฉพาะด้วยวิธี value provider โมดูลนี้จะมี Retrofit เพียงชุดเดียวเพื่อหลีกเลี่ยงการสร้างซ้ำซ้อน จะใช้ builder pattern เพื่อตั้งค่า URL พื้นฐานและตัวแปลงเพื่อจัดการแปลง JSON ให้ใช้งานกับโมเดลของเราได้
ใช้ instance นี้เพื่อรับ instance เดียวของบริการ API และ Retrofit เพื่อการทำงานที่ราบรื่นโดยใช้ provider อื่นๆ ซึ่งจำเป็นต้องตั้งค่าประเภทของ object แล้วจึงจะสร้างได้โดยไม่ต้องมี API service instance
เข้าไปที่ Koin ใน application class โดยตั้งค่าบริบทที่ใช้สำหรับการวิเคราะห์ข้อมูลเป็นแอปพลิเคชันเองและกำหนดรายการของโมดูล สิ่งนี้ทำให้มั่นใจได้ว่าเมื่อเรามีโมดูลเครือข่าย มันจะถูกนำมาใช้
เพิ่มโมดูล MostViewed ซึ่งมีหน้าที่จัดเตรียมโมเดล MostViewed Android จะจัดการการสร้าง instance ของโมเดลใหม่โดยอัตโนมัติเมื่อจำเป็น และเราสามารถใช้ ViewModel provider เพื่อให้มั่นใจถึงความมั่นคงในการสร้าง instance ใหม่
BaseActivity จะทำหน้าที่เป็น extended activity เพื่อตั้งค่าโมดูลใน constructor เนื่องจากเรามีโมดูลปัจจุบันในแอปพลิเคชัน เราจึงจำเป็นต้องมีโมเดลปัจจุบันที่ขึ้นอยู่กับ activity ด้วย
ใน MostViewedModule เราโหลดโมดูลสำหรับหน้าจอ โดยแชร์ไว้ใน constructor ของ activity ซึ่งเราจะโหลดโมดูลใน onCreate method และยกเลิกการโหลดใน onDestroy เพื่อให้แน่ใจว่ามีการโหลดโมดูลที่สมดุล
สุดท้าย ในการเรียกใช้ API เจ้า API service นี้จะกลายเป็น argument ของ constructor และ property ของ class ซึ่งช่วยให้เข้าถึงข้อมูลที่ต้องการได้ง่ายโดยไม่ต้องสร้างข้อมูลนั้นอีกครั้ง
Room
รวม library ของ Room ที่ runtime ของ Room ทำหน้าที่เป็นองค์ประกอบหลัก นอกจากนี้ KTX ยังจำเป็นสำหรับ Room เพื่อทำงานร่วมกับ coroutine เนื่องจากช่วยให้สามารถใช้ฟังก์ชัน suspend และ light data ได้ นอกจากนี้ ยังใช้ประโยชน์จาก KAPT ซึ่งเป็นตัวประมวลผลคำอธิบายประกอบได้ด้วย
ต่อไป เราจะแนะนำ DAO (Database Access Object) ซึ่งเรากำหนดวิธีการแทรก article, อัปเดต article, ทำเครื่องหมายบทความว่าอ่านแล้ว, และอัปเดตข้อมูลเชิงตรรกะที่ได้รับจาก API โดยข้อดีของ Room คือเราสามารถดำเนินการสิ่งเหล่านี้ได้โดยไม่ต้องเขียน SQL querie ที่ชัดเจน
มาถึงการสร้างฐานข้อมูล ซึ่งจะเป็น abstract class ที่มีวิธีการเข้าถึง DAO class โดยการใช้ abstract class แทนอินเทอร์เฟซช่วยให้เรามีวิธีการ non-abstract สำหรับการเติมข้อมูลของ calss ในฐานข้อมูล
ถัดมาคือการเพิ่ม Repository เนื่องจากโมเดลใหม่จำเป็นต้องรวบรวมข้อมูลจาก ViewModel โดยใช้บริการ API อย่างไรก็ตาม การรับข้อมูลโดยตรงจากเครือข่ายหรือ API นั้นไม่ใช่แนวปฏิบัติที่ดี เนื่องจากอาจมาจากแหล่งที่มาที่แตกต่างกัน เพื่อแก้ไขปัญหานี้ เราจะสร้าง class แยกต่างหากที่ทำหน้าที่เป็น data provider และจัดการแหล่งที่มาต่างๆ เช่น database instance ซึ่งโมเดลจะใช้ class นี้เพื่อแปลงข้อมูลเป็นรายการของ object
สำหรับการอัปเดตโมดูลโดยเพิ่ม Repository Module ซึ่งใช้ Retrofit instance จะแนะนำให้รู้จักกับ Router ที่ช่วยให้เราย้ายจาก activity หนึ่งไปยังอีก activity หนึ่งได้ ดังนั้นควรวาง router logic ไว้ใน ViewModel และเพื่อให้บรรลุเป้าหมายนี้ เราจะสร้าง router interface และนำไปใช้กับ class ที่รับ activity เป็น argument และใช้เพื่อแทนที่ openWebView method โดยใช้ activity instance
เริ่มต้นด้วยการกำหนดพารามิเตอร์ของ activity ในโมดูล ตั้งเป็น argument และใช้เพื่อยกตัวอย่างองค์ประกอบที่จำเป็นภายใน activity
สรุปทิ้งท้าย
นักพัฒนาซอฟต์แวร์มักให้ความสำคัญกับรูปแบบสถาปัตยกรรมซอฟต์แวร์เมื่อต้องเริ่มสร้างแอปพลิเคชัน Android เนื่องจากรูปแบบนี้ทำให้ไฟล์ที่ใช้ในโปรเจกต์มีความเป็นโมดูลที่แยกส่วนกันและยังทำให้มั่นใจได้ว่าโค้ดทั้งหมดจะได้รับการทดสอบในทุก unit
นั่นคือเหตุผลว่าทำไม MVVM ถึงโดดเด่นในฐานะหนึ่งในรูปแบบสถาปัตยกรรม Android ที่ได้รับความนิยมสูงสุดที่นักพัฒนาเลือกใช้ เพราะแสดงให้เห็นถึงวิวัฒนาการที่ดีขึ้นจากรุ่น MVC และ MVP แบบดั้งเดิม โดย MVVM แยกตรรกะการนำเสนอ (Views หรือ UI) ออกจากตรรกะทางธุรกิจได้อย่างมีประสิทธิภาพ และช่วยส่งเสริม codebase ให้เป็นระเบียบและบำรุงรักษาได้ง่ายขึ้น
แชร์เรื่องนี้
- การพัฒนาซอฟต์แวร์ (8)
- Cloud (5)
- อาชีพการงาน (5)
- Agile (4)
- JavaScript (4)
- Trend (4)
- seven peaks (3)
- การออกแบบ UX (3)
- Android Developer (2)
- CSR (2)
- InsurTech (2)
- Iot (2)
- Kotlin (2)
- Mixpanel (2)
- Product-Centric Mindset (2)
- QA (2)
- ReactJS (2)
- การธนาคาร (2)
- การพัฒนาแอปฯ (2)
- การพัฒนาแอปฯ Android (2)
- บริษัท (2)
- .NET (1)
- 5g (1)
- Android (1)
- AndroidX Biometric (1)
- Biometrics (1)
- Data (1)
- DevOps (1)
- Digital Healthcare (1)
- Digital Landscape (1)
- Digital Product (1)
- Expert Spotlight (1)
- GraphQL (1)
- Hybrid App (1)
- IT outsourcing (1)
- MVVM (1)
- Metaverse (1)
- Morphosis (1)
- Native App (1)
- Node.js (1)
- Recruitment (1)
- SCB (1)
- Software Engineer (1)
- Software Tester (1)
- Stripe (1)
- Swift (1)
- SwiftUI (1)
- Tech Meetup (1)
- Turnkey (1)
- UI (1)
- azure (1)
- digital transformation (1)
- partner (1)
- waterfall (1)
- การจ้างงาน (1)
- การพัฒนาด้วย RabbitMQ (1)
- การพัฒนาระบบคลาวด์ (1)
- การพัฒนาแอปพลิเคชัน iOS (1)
- การออกแบบ Decorator Pattern (1)
- การใช้งาน C# (1)
- งาน Product Manager (1)
- งาน Product Owner (1)
- ทำ Context API (1)
- ฟินเทค (1)
- ระบบการชำระเงิน (1)
- สร้าง brand loyalty (1)
- อีคอมเมิร์ซ (1)
- เขียนโค้ด React (1)
- เครื่องมือ web debugging (1)
- เทคโนโลยี React (1)
- เพิ่ม conversion (1)
- เฟรมเวิร์ก (1)
- แดชบอร์ด (1)
- กันยายน 2023 (7)
- กรกฎาคม 2023 (4)
- มิถุนายน 2023 (3)
- พฤษภาคม 2023 (3)
- เมษายน 2023 (1)
- มีนาคม 2023 (1)
- พฤศจิกายน 2022 (1)
- สิงหาคม 2022 (4)
- กรกฎาคม 2022 (1)
- มิถุนายน 2022 (4)
- เมษายน 2022 (6)
- มีนาคม 2022 (3)
- กุมภาพันธ์ 2022 (5)
- มกราคม 2022 (2)
- ธันวาคม 2021 (1)
- ตุลาคม 2021 (1)
- กันยายน 2021 (1)
- สิงหาคม 2021 (3)
- มิถุนายน 2021 (2)
- พฤษภาคม 2021 (1)
- มีนาคม 2021 (4)
- กุมภาพันธ์ 2021 (4)
- ธันวาคม 2020 (3)
- พฤศจิกายน 2020 (1)
- มิถุนายน 2020 (1)
- เมษายน 2020 (1)