สถาปัตยกรรมของแอปเป็นรากฐานของแอปพลิเคชัน Android คุณภาพสูง สถาปัตยกรรมที่กำหนดไว้อย่างดีช่วยให้คุณสร้างแอปที่ปรับขนาดได้และบำรุงรักษาได้ ซึ่งปรับให้เข้ากับระบบนิเวศของอุปกรณ์ Android ที่ขยายตัวอย่างต่อเนื่องได้ รวมถึงโทรศัพท์, แท็บเล็ต, อุปกรณ์พับได้, อุปกรณ์ ChromeOS, จอแสดงผลในรถยนต์ และ XR
การจัดวางองค์ประกอบของแอป
โดยทั่วไปแล้ว แอป Android ประกอบด้วยคอมโพเนนต์ของแอปหลายรายการ เช่น บริการ ผู้ให้บริการเนื้อหา และตัวรับสัญญาณ การออกอากาศ คุณประกาศคอมโพเนนต์เหล่านี้ในไฟล์ Manifest ของแอป
อินเทอร์เฟซผู้ใช้ของแอปก็เป็นคอมโพเนนต์เช่นกัน ในอดีต UI สร้างขึ้นโดยใช้กิจกรรมหลายรายการ อย่างไรก็ตาม แอปสมัยใหม่ใช้
สถาปัตยกรรมแบบกิจกรรมเดียว Activity เดียวทำหน้าที่เป็นคอนเทนเนอร์สำหรับ
หน้าจอหรือปลายทาง Jetpack Compose
อุปกรณ์หลายรูปแบบ
แอปสามารถทำงานได้ในอุปกรณ์หลายรูปแบบ ซึ่งรวมถึงโทรศัพท์ แท็บเล็ต อุปกรณ์พับได้ อุปกรณ์ ChromeOS และอื่นๆ อย่าคิดไปเองว่าแอปจะอยู่ในแนวตั้งหรือแนวนอนเสมอ การเปลี่ยนแปลงการกำหนดค่า เช่น การหมุนอุปกรณ์ หรือการพับและกางอุปกรณ์แบบพับได้ จะบังคับให้แอป จัดองค์ประกอบ UI ใหม่ ซึ่งจะส่งผลต่อสถานะของแอป
ข้อจำกัดด้านทรัพยากร
อุปกรณ์เคลื่อนที่ แม้จะเป็นอุปกรณ์ที่มีหน้าจอขนาดใหญ่ก็มีข้อจำกัดด้านทรัพยากร ดังนั้นระบบปฏิบัติการอาจหยุดกระบวนการของแอปได้ทุกเมื่อเพื่อจัดสรร ทรัพยากรให้กับกระบวนการอื่นๆ
เงื่อนไขการเปิดตัวที่เปลี่ยนแปลงได้
ในสภาพแวดล้อมที่มีข้อจำกัดด้านทรัพยากร คอมโพเนนต์ของแอปอาจ เปิดตัวแยกกันและไม่เป็นไปตามลำดับ นอกจากนี้ ระบบปฏิบัติการหรือ ผู้ใช้ยังทำลายคอมโพเนนต์ได้ทุกเมื่อ ดังนั้นจึงไม่ควรจัดเก็บข้อมูลหรือสถานะของแอปพลิเคชันในคอมโพเนนต์ของแอป ทำให้คอมโพเนนต์ของแอปมีข้อมูลครบถ้วนในตัวเอง โดยไม่ขึ้นต่อกัน
หลักการสถาปัตยกรรมที่พบบ่อย
หากใช้คอมโพเนนต์ของแอปเพื่อจัดเก็บข้อมูลและสถานะของแอปพลิเคชันไม่ได้ คุณควรออกแบบแอปอย่างไร
เมื่อแอป Android มีขนาดใหญ่ขึ้น การกำหนดสถาปัตยกรรมที่ ช่วยให้แอปปรับขนาดได้จึงเป็นสิ่งสำคัญ สถาปัตยกรรมแอปที่ออกแบบมาอย่างดีจะกำหนดขอบเขต ระหว่างส่วนต่างๆ ของแอปและหน้าที่รับผิดชอบของแต่ละส่วน
การแยกความกังวล
ออกแบบสถาปัตยกรรมของแอปให้เป็นไปตามหลักการที่เฉพาะเจาะจง 2-3 ข้อ
หลักการที่สำคัญที่สุดคือการแยกความกังวล การแยกแอปออกเป็นเมธอด คลาส ไฟล์ แพ็กเกจ โมดูล และเลเยอร์ ที่มีความรับผิดชอบและขอบเขตที่กำหนดไว้อย่างชัดเจน
ข้อผิดพลาดที่พบบ่อยคือการเขียนโค้ดทั้งหมดใน Activity
บทบาทหลักของ Activity คือการโฮสต์ UI ของแอป
ระบบปฏิบัติการ Android จะควบคุมวงจรของ Fragment โดยมักจะทำลายและสร้าง Fragment ใหม่
เพื่อตอบสนองต่อการกระทำของผู้ใช้ เช่น การหมุนหน้าจอ หรือเหตุการณ์ของระบบ เช่น หน่วยความจำเหลือน้อย
ลักษณะชั่วคราวนี้ทำให้ไม่เหมาะสำหรับการจัดเก็บข้อมูลแอปพลิเคชันหรือสถานะ หากคุณจัดเก็บข้อมูลใน Activity ข้อมูลนั้นจะสูญหายเมื่อ
สร้างคอมโพเนนต์ขึ้นใหม่ อย่าฝากสถานะไว้กับคอมโพเนนต์ UI เหล่านี้เพื่อให้มั่นใจว่าข้อมูลจะยังคงอยู่และมอบประสบการณ์การใช้งานที่เสถียรแก่ผู้ใช้
เลย์เอาต์แบบปรับขนาดได้
สร้างแอปที่จัดการการเปลี่ยนแปลงการกำหนดค่าได้อย่างราบรื่น เช่น การเปลี่ยนแปลงการวางแนวของอุปกรณ์หรือการเปลี่ยนแปลงขนาดหน้าต่างของแอป ใช้เลย์เอาต์ Canonical แบบปรับเปลี่ยนได้เพื่อมอบประสบการณ์การใช้งานที่ดีที่สุดในอุปกรณ์หลากหลายรูปแบบ
ขับเคลื่อน UI จากโมเดลข้อมูล
หลักการสำคัญอีกอย่างคือการขับเคลื่อน UI จากโมเดลข้อมูล โดยเฉพาะโมเดลที่คงอยู่ โมเดลข้อมูลแสดงถึงข้อมูลของแอป โดยจะ แยกจากองค์ประกอบ UI และคอมโพเนนต์อื่นๆ ในแอป ซึ่งหมายความว่า โมเดลข้อมูลจะไม่เชื่อมโยงกับวงจรของ UI และคอมโพเนนต์ของแอป แต่จะยังคง ถูกทำลายเมื่อระบบปฏิบัติการนำกระบวนการของแอปออกจากหน่วยความจำ
โมเดลแบบถาวรเหมาะอย่างยิ่งด้วยเหตุผลต่อไปนี้
ผู้ใช้จะไม่สูญเสียข้อมูลหากระบบปฏิบัติการ Android ทำลายแอปเพื่อเพิ่มพื้นที่ว่าง ให้กับทรัพยากร
แอปจะยังคงทำงานต่อไปในกรณีที่การเชื่อมต่อเครือข่าย ไม่สม่ำเสมอหรือใช้งานไม่ได้
สร้างสถาปัตยกรรมแอปตามคลาสโมเดลข้อมูลเพื่อให้แอปมีความแข็งแกร่งและ ทดสอบได้
แหล่งข้อมูลที่เชื่อถือได้เพียงแหล่งเดียว
เมื่อกำหนดประเภทข้อมูลใหม่ในแอป ให้กำหนดแหล่งข้อมูลที่เชื่อถือได้เพียงแหล่งเดียว (SSOT) ให้กับประเภทข้อมูลนั้น SSOT เป็นเจ้าของข้อมูลนั้น และมีเพียง SSOT เท่านั้นที่ แก้ไขหรือเปลี่ยนแปลงข้อมูลได้ เพื่อให้เป็นไปตามนี้ SSOT จะแสดงข้อมูลโดยใช้ ประเภทที่เปลี่ยนแปลงไม่ได้ หากต้องการแก้ไขข้อมูล SSOT จะแสดงฟังก์ชันหรือรับ เหตุการณ์ที่ประเภทอื่นๆ เรียกได้
รูปแบบนี้มีประโยชน์หลายประการ ดังนี้
- รวมการเปลี่ยนแปลงทั้งหมดของข้อมูลประเภทหนึ่งๆ ไว้ในที่เดียว
- ปกป้องข้อมูลเพื่อไม่ให้ข้อมูลประเภทอื่นๆ ดัดแปลงได้
- ทำให้การเปลี่ยนแปลงข้อมูลติดตามได้ง่ายขึ้น จึงทำให้พบข้อบกพร่องได้ง่ายขึ้น
ในแอปพลิเคชันที่เน้นการทำงานแบบออฟไลน์เป็นหลัก แหล่งข้อมูลที่เชื่อถือได้สำหรับข้อมูลแอปพลิเคชันมักจะเป็นฐานข้อมูล ในบางกรณี แหล่งข้อมูลที่เชื่อถือได้อาจเป็นViewModel
โฟลว์ข้อมูลแบบทางเดียว
โดยมักจะใช้หลักการแหล่งข้อมูลที่ถูกต้องแห่งเดียว ร่วมกับรูปแบบการไหลของข้อมูลแบบทิศทางเดียว (UDF) ใน UDF state จะไหลไปในทิศทางเดียวเท่านั้น ซึ่งโดยปกติแล้วจะไหลจากคอมโพเนนต์หลักไปยังคอมโพเนนต์ย่อย เหตุการณ์ ที่แก้ไขโฟลว์ข้อมูลในทิศทางตรงกันข้าม
ใน Android สถานะหรือข้อมูลมักจะไหลจากประเภทที่มีขอบเขตสูงกว่าใน ลำดับชั้นไปยังประเภทที่มีขอบเขตต่ำกว่า โดยปกติแล้ว ระบบจะทริกเกอร์เหตุการณ์จากประเภทที่มีขอบเขตต่ำกว่าจนกว่าจะถึง SSOT สำหรับประเภทข้อมูลที่เกี่ยวข้อง เช่น ข้อมูลแอปพลิเคชันมักจะไหลจากแหล่งข้อมูลไปยัง UI เหตุการณ์ของผู้ใช้ เช่น การกดปุ่ม จะไหลจาก UI ไปยัง SSOT ซึ่งมีการแก้ไขข้อมูลแอปพลิเคชันและแสดงในประเภทที่ไม่เปลี่ยนแปลง
รูปแบบนี้ช่วยรักษาความสอดคล้องของข้อมูลได้ดีขึ้น มีแนวโน้มที่จะเกิดข้อผิดพลาดน้อยลง ดีบักได้ง่ายขึ้น และให้ประโยชน์ทั้งหมดของรูปแบบ SSOT
ดูข้อมูลเพิ่มเติมเกี่ยวกับ UDF ได้ที่ โฟลว์ข้อมูลแบบทิศทางเดียวใน Jetpack Compose
สถาปัตยกรรมแอปที่แนะนำ
เมื่อพิจารณาหลักการออกแบบทั่วไป ให้ออกแบบแต่ละแอปพลิเคชันโดยมีเลเยอร์อย่างน้อย 2 เลเยอร์ ดังนี้
- เลเยอร์ UI: แสดงข้อมูลแอปพลิเคชันบนหน้าจอ
- เลเยอร์ข้อมูล: มีตรรกะทางธุรกิจของแอปและแสดงข้อมูลแอปพลิเคชัน
คุณสามารถเพิ่มเลเยอร์อีกชั้นหนึ่งที่เรียกว่าเลเยอร์โดเมนเพื่อลดความซับซ้อนและนำการโต้ตอบระหว่าง UI กับเลเยอร์ข้อมูลกลับมาใช้ใหม่
สถาปัตยกรรมแอปสมัยใหม่
สถาปัตยกรรมแอป Android สมัยใหม่ใช้เทคนิคต่อไปนี้ (รวมถึงเทคนิคอื่นๆ)
- สถาปัตยกรรมแบบปรับได้และแบบเลเยอร์
- การไหลของข้อมูลแบบทางเดียว (UDF) ในทุกเลเยอร์ของแอป
- เลเยอร์ UI ที่มีตัวยึดสถานะเพื่อจัดการความซับซ้อนของ UI
- โครูทีนและโฟลว์
- แนวทางปฏิบัติแนะนำสำหรับการแทรก Dependency
- การเพิ่มประสิทธิภาพโดยใช้ R8 และโปรไฟล์พื้นฐาน รวมถึงการวัดด้วย Macrobenchmark
ดูข้อมูลเพิ่มเติมได้ที่ คำแนะนำสำหรับสถาปัตยกรรม Android
เลเยอร์ UI
บทบาทของเลเยอร์ UI (หรือเลเยอร์การนำเสนอ) คือการแสดงข้อมูลแอปพลิเคชัน บนหน้าจอ เมื่อใดก็ตามที่ข้อมูลมีการเปลี่ยนแปลง ไม่ว่าจะเป็นเนื่องจากการโต้ตอบของผู้ใช้ (เช่น การกดปุ่ม) หรืออินพุตภายนอก (เช่น การตอบกลับของเครือข่าย) UI จะอัปเดตเพื่อแสดงการเปลี่ยนแปลง
เลเยอร์ UI ประกอบด้วยโครงสร้าง 2 ประเภท ได้แก่
- องค์ประกอบ UI ที่แสดงข้อมูลบนหน้าจอ คุณสร้างองค์ประกอบเหล่านี้ โดยใช้ฟังก์ชัน Jetpack Compose เพื่อรองรับเลย์เอาต์ที่ปรับเปลี่ยนตามอุปกรณ์
- ผู้ถือสถานะ (เช่น
ViewModel) ที่ถือข้อมูล แสดงข้อมูล ต่อ UI และจัดการตรรกะ State Holder ควรมีอายุการใช้งานเท่ากับองค์ประกอบ UI ที่ระบุสถานะ ตัวอย่างเช่น ViewModel สำหรับหน้าจอควรจะยังคงอยู่ในหน่วยความจำจนกว่าจะนำหน้าจอออกจาก Back Stack การนำทางย้อนกลับของแอป ดูข้อมูลเพิ่มเติมได้ที่อายุการใช้งานของสถานะ
สำหรับ UI แบบปรับเปลี่ยนได้ ตัวยึดสถานะ เช่น ออบเจ็กต์ ViewModel จะแสดงสถานะ UI ที่
ปรับให้เข้ากับคลาสขนาดหน้าต่างต่างๆ คุณใช้
currentWindowAdaptiveInfo() เพื่อสร้างสถานะ UI นี้ได้ จากนั้นคอมโพเนนต์ต่างๆ เช่น
NavigationSuiteScaffold จะใช้ข้อมูลนี้เพื่อสลับโดยอัตโนมัติ
ระหว่างรูปแบบการนำทางต่างๆ (เช่น NavigationBar
NavigationRail หรือ NavigationDrawer) ตามพื้นที่หน้าจอที่มี
ดูข้อมูลเพิ่มเติมได้ที่เลเยอร์ UI และ สถาปัตยกรรม Compose UI
ดูข้อมูลเพิ่มเติมเกี่ยวกับแอปและการนำทางแบบปรับอัตโนมัติได้ที่ สร้างแอปแบบปรับอัตโนมัติและ สร้างการนำทางแบบปรับอัตโนมัติ
ชั้นข้อมูล
เลเยอร์ข้อมูลของแอปมีตรรกะทางธุรกิจ ตรรกะทางธุรกิจคือสิ่งที่ สร้างมูลค่าให้กับแอปของคุณ ซึ่งประกอบด้วยกฎที่กำหนดวิธีที่แอป สร้าง จัดเก็บ และเปลี่ยนแปลงข้อมูล
เลเยอร์ข้อมูลประกอบด้วยที่เก็บ ซึ่งแต่ละที่เก็บอาจมีแหล่งข้อมูลตั้งแต่ 0 ถึงหลายแหล่ง สร้างคลาสที่เก็บสำหรับข้อมูลแต่ละประเภทที่คุณจัดการในแอป เช่น คุณอาจสร้างMoviesRepositoryคลาสสำหรับข้อมูลที่เกี่ยวข้องกับภาพยนตร์หรือPaymentsRepositoryคลาสสำหรับข้อมูลที่เกี่ยวข้องกับการชำระเงิน
คลาส Repository มีหน้าที่รับผิดชอบในเรื่องต่อไปนี้
- การเปิดเผยข้อมูลต่อส่วนอื่นๆ ของแอป
- รวมการเปลี่ยนแปลงข้อมูลไว้ในที่เดียว
- การแก้ไขความขัดแย้งระหว่างแหล่งข้อมูลหลายแหล่ง
- แยกแหล่งข้อมูลออกจากส่วนอื่นๆ ของแอป
- มีตรรกะทางธุรกิจ
คลาสแหล่งข้อมูลแต่ละคลาสมีหน้าที่รับผิดชอบในการทำงานกับแหล่งข้อมูลเพียงแหล่งเดียว ซึ่งอาจเป็นไฟล์ แหล่งข้อมูลเครือข่าย หรือฐานข้อมูลในเครื่อง คลาสแหล่งข้อมูลเป็นตัวเชื่อมระหว่างแอปพลิเคชันกับระบบสำหรับการดำเนินการข้อมูล
ดูข้อมูลเพิ่มเติมได้ที่หน้า Data Layer
เลเยอร์โดเมน
เลเยอร์โดเมนเป็นเลเยอร์ที่ไม่บังคับซึ่งอยู่ระหว่าง UI กับเลเยอร์ข้อมูล
เลเยอร์โดเมนมีหน้าที่ห่อหุ้มตรรกะทางธุรกิจที่ซับซ้อนหรือตรรกะทางธุรกิจที่ง่ายกว่าซึ่งโมเดลมุมมองหลายรายการนำกลับมาใช้ใหม่ เลเยอร์โดเมน เป็นเลเยอร์ที่ไม่บังคับ เนื่องจากไม่ใช่ทุกแอปที่มีข้อกำหนดเหล่านี้ ใช้เฉพาะเมื่อจำเป็น เช่น เพื่อจัดการความซับซ้อนหรือต้องการนำกลับมาใช้ใหม่
โดยทั่วไปแล้ว คลาสในเลเยอร์โดเมนเรียกว่า Use Case หรือ Interactor
กรณีการใช้งานแต่ละรายการมีหน้าที่รับผิดชอบฟังก์ชันเดียว ตัวอย่างเช่น แอปของคุณอาจมีคลาส GetTimeZoneUseCase หาก View Model หลายรายการต้องอาศัยเขตเวลาเพื่อแสดงข้อความที่เหมาะสมบนหน้าจอ
ดูข้อมูลเพิ่มเติมได้ที่หน้าเลเยอร์โดเมน
จัดการการขึ้นต่อกันระหว่างคอมโพเนนต์
คลาสในแอปของคุณต้องอาศัยคลาสอื่นๆ เพื่อให้ทำงานได้อย่างถูกต้อง คุณสามารถใช้รูปแบบการออกแบบต่อไปนี้เพื่อรวบรวมการอ้างอิงของคลาสหนึ่งๆ ได้
- การแทรกทรัพยากร Dependency (DI): การแทรกทรัพยากร Dependency ช่วยให้คลาสกำหนดทรัพยากร Dependency ได้โดยไม่ต้องสร้างทรัพยากร Dependency ในเวลาเรียกใช้ คลาสอื่น จะมีหน้าที่จัดเตรียมทรัพยากร Dependency เหล่านี้
- ตัวระบุตำแหน่งบริการ: รูปแบบตัวระบุตำแหน่งบริการ มีรีจิสทรีที่คลาสสามารถรับทรัพยากร Dependency แทนการสร้างได้
รูปแบบเหล่านี้ช่วยให้คุณปรับขนาดโค้ดได้เนื่องจากมีรูปแบบที่ชัดเจน สำหรับการจัดการการอ้างอิงโดยไม่ต้องทำโค้ดซ้ำหรือเพิ่มความซับซ้อน รูปแบบยังช่วยให้คุณสลับไปมาระหว่างการใช้งานจริงและการทดสอบได้อย่างรวดเร็ว
แนวทางปฏิบัติแนะนำโดยทั่วไป
การเขียนโปรแกรมเป็นสาขาที่ต้องใช้ความคิดสร้างสรรค์ และการสร้างแอป Android ก็เช่นกัน การแก้ปัญหามีหลายวิธี คุณอาจสื่อสารข้อมูลระหว่าง กิจกรรมหรือ Fragment หลายรายการ ดึงข้อมูลจากระยะไกลและบันทึกไว้ในเครื่อง สำหรับโหมดออฟไลน์ หรือจัดการสถานการณ์ทั่วไปอื่นๆ ที่แอปที่ซับซ้อน พบเจอ
แม้ว่าคำแนะนำต่อไปนี้จะไม่ใช่ข้อบังคับ แต่ในกรณีส่วนใหญ่ การทำตามคำแนะนำจะช่วยให้ฐานของโค้ดมีความแข็งแกร่ง ทดสอบได้ และบำรุงรักษาได้มากขึ้น
อย่าจัดเก็บข้อมูลในคอมโพเนนต์ของแอป
หลีกเลี่ยงการกำหนดจุดแรกเข้าของแอป เช่น กิจกรรม บริการ และ Broadcast Receiver เป็นแหล่งข้อมูล สร้างจุดแรกเข้า ให้สอดคล้องกับคอมโพเนนต์อื่นๆ เพื่อดึงเฉพาะชุดข้อมูลย่อยที่ เกี่ยวข้องกับจุดแรกเข้านั้น คอมโพเนนต์ของแอปแต่ละรายการจะมีอายุสั้น ขึ้นอยู่กับการโต้ตอบของผู้ใช้กับอุปกรณ์และความจุของระบบ
ลดการขึ้นอยู่กับคลาส Android
ทำให้คอมโพเนนต์ของแอปเป็นคลาสเดียวที่ต้องอาศัย API ของ Android Framework SDK เช่น Context หรือ Toast การแยกคลาสอื่นๆ ในแอปออกจากคอมโพเนนต์ของแอปจะช่วยให้ทดสอบได้ง่ายขึ้นและลดการเชื่อมโยงภายในแอป
กำหนดขอบเขตความรับผิดชอบที่ชัดเจนระหว่างโมดูลในแอป
อย่ากระจายโค้ดที่โหลดข้อมูลจากเครือข่ายไปยังหลายคลาส หรือแพ็กเกจในโค้ดเบส ในทำนองเดียวกัน อย่ากำหนดความรับผิดชอบหลายอย่างที่ไม่เกี่ยวข้อง เช่น การแคชข้อมูลและการเชื่อมโยงข้อมูล ในคลาสเดียวกัน ทำตามสถาปัตยกรรมแอปที่แนะนำ
เปิดเผยให้น้อยที่สุดเท่าที่จะทำได้จากแต่ละโมดูล
อย่าสร้างทางลัดที่เปิดเผยรายละเอียดการใช้งานภายใน คุณอาจประหยัดเวลาได้เล็กน้อยในระยะสั้น แต่มีแนวโน้มที่จะก่อให้เกิดหนี้ทางเทคนิคหลายครั้งเมื่อโค้ดเบสมีการพัฒนา
มุ่งเน้นที่แกนหลักที่เป็นเอกลักษณ์ของแอปเพื่อให้แอปโดดเด่นจากแอปอื่นๆ
อย่าเสียเวลาเขียนโค้ด Boilerplate เดิมซ้ำแล้วซ้ำเล่า แต่ให้ใช้เวลาและพลังงานไปกับสิ่งที่ทำให้แอปของคุณไม่เหมือนใครแทน ปล่อยให้ ไลบรารี Jetpack และไลบรารีอื่นๆ ที่แนะนำจัดการ บอยเลอร์เพลตที่ซ้ำกัน
ใช้เลย์เอาต์ Canonical และรูปแบบการออกแบบแอป
ไลบรารี Jetpack Compose มี API ที่มีประสิทธิภาพสำหรับการสร้างอินเทอร์เฟซผู้ใช้แบบปรับอัตโนมัติ ใช้เลย์เอาต์มาตรฐานในแอปเพื่อ เพิ่มประสิทธิภาพประสบการณ์ของผู้ใช้ในรูปแบบของอุปกรณ์และขนาดการแสดงผลที่หลากหลาย ดูแกลเลอรีรูปแบบการออกแบบแอปเพื่อเลือกเลย์เอาต์ที่เหมาะกับกรณีการใช้งานของคุณมากที่สุด
คงสถานะ UI ไว้เมื่อมีการเปลี่ยนแปลงการกำหนดค่า
เมื่อออกแบบเลย์เอาต์แบบปรับเปลี่ยนได้ ให้คงสถานะ UI ไว้เมื่อมีการเปลี่ยนแปลงการกำหนดค่า เช่น การปรับขนาดจอแสดงผล การพับ และการเปลี่ยนแปลงการวางแนว สถาปัตยกรรมของคุณควรยืนยันว่าระบบจะรักษาสถานะปัจจุบันของผู้ใช้ไว้ เพื่อมอบประสบการณ์ที่ราบรื่น
ออกแบบคอมโพเนนต์ UI ที่นำกลับมาใช้ใหม่และประกอบกันได้
สร้างคอมโพเนนต์ UI ที่นำกลับมาใช้ใหม่และประกอบกันได้เพื่อรองรับการออกแบบที่ปรับเปลี่ยนได้ ซึ่งช่วยให้คุณรวมและจัดเรียงคอมโพเนนต์ใหม่ให้เหมาะกับขนาดหน้าจอและ ท่าทางต่างๆ ได้โดยไม่ต้องทำการปรับโครงสร้างใหม่มากนัก
พิจารณาว่าจะทำให้แต่ละส่วนของแอปทดสอบได้โดยแยกกันอย่างไร
API ที่กำหนดไว้อย่างดีสำหรับการดึงข้อมูลจากเครือข่ายช่วยให้ทดสอบโมดูลที่จัดเก็บข้อมูลนั้นไว้ในฐานข้อมูลในเครื่องได้ ในทางกลับกัน หากคุณรวมตรรกะจากฟังก์ชันทั้ง 2 นี้ไว้ในที่เดียว หรือกระจายโค้ดเครือข่ายไปทั่วทั้งฐานของโค้ด การทดสอบจะยากขึ้นมาก หรืออาจเป็นไปไม่ได้เลย
ประเภทมีหน้าที่รับผิดชอบนโยบายการทำงานพร้อมกัน
หากประเภทใดกำลังทำงานที่บล็อกเป็นเวลานาน ประเภทนั้นควรมีหน้าที่ย้ายการคำนวณดังกล่าวไปยังเธรดที่เหมาะสม โดยประเภทจะทราบ ประเภทการคำนวณที่กำลังทำและเธรดที่จะใช้ในการคำนวณ ประเภทควรเป็น main-safe ซึ่งหมายความว่าเรียกใช้จากเทรดหลักได้อย่างปลอดภัยโดยไม่บล็อกเทรดหลัก
คงข้อมูลที่เกี่ยวข้องและใหม่ให้มากที่สุด
เพื่อให้ผู้ใช้เพลิดเพลินกับฟังก์ชันการทำงานของแอปได้แม้ว่าอุปกรณ์จะอยู่ในโหมดออฟไลน์ก็ตาม โปรดทราบว่าผู้ใช้บางรายอาจไม่ได้ใช้การเชื่อมต่อที่รวดเร็วและเสถียร และแม้ว่าผู้ใช้จะมีการเชื่อมต่อดังกล่าว แต่ก็อาจรับสัญญาณได้ไม่ดี ในสถานที่ที่มีผู้คนหนาแน่น
สิทธิประโยชน์ของสถาปัตยกรรม
การใช้สถาปัตยกรรมที่ดีในแอปจะช่วยให้ทีมวิศวกรรมและทีมโปรเจ็กต์ได้รับประโยชน์มากมาย ดังนี้
- ปรับปรุงความสามารถในการบำรุงรักษา คุณภาพ และความแข็งแกร่งของแอปโดยรวม
- ช่วยให้แอปปรับขนาดได้ ผู้คนและทีมจำนวนมากขึ้นสามารถมีส่วนร่วมในฐานของโค้ดเดียวกันโดยมีข้อขัดแย้งของโค้ดน้อยที่สุด
- ช่วยในการเริ่มต้นใช้งาน เนื่องจากสถาปัตยกรรมช่วยให้โปรเจ็กต์มีความสอดคล้องกัน สมาชิกใหม่ในทีมจึงสามารถติดตามความคืบหน้าได้อย่างรวดเร็วและทำงานได้อย่างมีประสิทธิภาพมากขึ้น ในเวลาที่น้อยลง
- ทดสอบได้ง่ายขึ้น สถาปัตยกรรมที่ดีจะสนับสนุนประเภทที่เรียบง่ายกว่า ซึ่งโดยทั่วไปแล้วจะทดสอบได้ง่ายกว่า
- ช่วยให้คุณตรวจสอบข้อบกพร่องอย่างเป็นระบบด้วยกระบวนการที่กำหนดไว้อย่างดี
แม้ว่าสถาปัตยกรรมที่ดีจะต้องใช้เวลาในการลงทุนตั้งแต่แรกเริ่ม แต่ก็ส่งผลโดยตรงต่อผู้ใช้ด้วย ผู้ใช้จะได้รับประโยชน์จากแอปพลิเคชันที่เสถียรมากขึ้นและฟีเจอร์ที่มากขึ้นเนื่องจากทีมวิศวกรทำงานได้อย่างมีประสิทธิภาพมากขึ้น
ตัวอย่าง
ตัวอย่างต่อไปนี้แสดงสถาปัตยกรรมแอปที่ดี