กำลังพิจารณาการทำให้เป็นโมดูลของโปรเจ็กต์ Android
เผยแพร่แล้ว: 2019-08-21เมื่อโปรเจ็กต์ถึงขนาดที่กำหนด การทำงานเพิ่มเติมกับโปรเจ็กต์ในโมดูลเดียวจะมีประสิทธิภาพน้อยลง การทำให้เป็นโมดูลกลายเป็นโซลูชันที่มีประสิทธิภาพ
ข้อดี 4 ข้อของการทำให้เป็นโมดูล
ก่อนตัดสินใจทำโมดูลาร์ ควรมีความชัดเจนว่าเกี่ยวข้องอย่างไร ข้อดีของโครงสร้างโปรเจ็กต์ Android แบบแยกส่วน ได้แก่:
การแยกโค้ดที่ดีขึ้น
ทุกโมดูลสามารถเปิดเผยอินเทอร์เฟซ API สาธารณะและซ่อนรายละเอียดการใช้งานได้ ด้วยโมดูลเดียว คุณไม่สามารถแน่ใจได้อย่างสมบูรณ์ว่าการใช้งานนั้นถูกซ่อนไว้อย่างดี (โดยเฉพาะใน Kotlin ซึ่งไม่มีตัวแก้ไขการมองเห็นแพ็คเกจ)
การประเมินเทคโนโลยีใหม่ที่ง่ายขึ้น
เมื่อคุณสร้างโมดูล คุณสามารถตรวจสอบรูปแบบสถาปัตยกรรมใหม่หรือไลบรารีใหม่ได้โดยไม่กระทบต่อโมดูลอื่นๆ
ลดเวลาในการสร้างโครงการ
การปรับเปลี่ยนโมดูลจำเป็นต้องสร้างโมดูลนั้นใหม่และโมดูลอื่นๆ ที่ขึ้นอยู่กับโมดูลนั้น ดูว่ามันทำงานอย่างไรโดยอ่านเอกสารนี้: นักพัฒนา Android การกำหนดค่าการพึ่งพา
ทำงานสะดวกขึ้น
การวิเคราะห์/ดีบัก/รีแฟกเตอร์ส่วนต่างๆ ของโค้ดที่เล็กกว่าและแยกออกมาจะง่ายขึ้น นอกจากนี้ การเริ่มต้นใช้งานของนักพัฒนาใหม่จะดำเนินไปอย่างรวดเร็วยิ่งขึ้น
ประโยชน์เหล่านี้ฟังดูเพียงพอที่จะโน้มน้าวให้คุณเริ่มกระบวนการทำให้เป็นโมดูล แต่คุณจะเริ่มต้นอย่างไร
#1: ระบุโมดูลและความสัมพันธ์ของคุณ
มีสองวิธีในการจดจำโมดูลของคุณ: ตามคุณสมบัติและตามเลเยอร์
ภายใต้โมดูลคุณลักษณะ คุณสามารถทำความเข้าใจบางพื้นที่ของแอปที่ผู้ใช้สามารถใช้ได้ (เช่น การเข้าสู่ระบบ แดชบอร์ด โปรไฟล์ ฯลฯ) พื้นที่เหล่านี้อาจประกอบด้วยหน้าจอเดียวหรือโฟลว์ของหน้าจอที่ครอบคลุมบางกระบวนการ โมดูลประเภทนี้ไม่สามารถขึ้นอยู่กับโมดูลประเภทเดียวกันได้
หลังจากระบุคุณสมบัติแล้ว คุณจะต้อง แยกฟังก์ชันทั่วไป ที่จำเป็นสำหรับโมดูลบางส่วนหรือทั้งหมด โมดูลเหล่านั้นสามารถรับผิดชอบสำหรับชั้นสถาปัตยกรรมที่แยกจากกัน (เช่น ที่เก็บข้อมูลถาวร เครือข่าย การนำทาง ส่วนประกอบ UI …) หรือตรรกะทางธุรกิจของการประมวลผลข้อมูลบางอย่างที่ใช้โดยชุดคุณสมบัติ โมดูลประเภทนี้มักจะเรียกว่า ไลบรารี โมดูลไลบรารีสามารถสร้างแผนผังการพึ่งพาได้
นอกจากโมดูลคุณลักษณะและไลบรารีแล้ว ยังจำเป็นต้องมีโมดูลหนึ่งโมดูลเพื่อจัดการการเชื่อมต่อในแนวนอนระหว่างโมดูลอื่นๆ (เพิ่มเติมเกี่ยวกับเรื่องนี้ในประเด็นถัดไป) โมดูลนี้จะมีคลาสแอปพลิเคชันที่กำหนดเองและการตั้งค่าการฉีดพึ่งพา ไม่มีโมดูลอื่นใดที่สามารถพึ่งพาโมดูลนี้ได้ แต่โมดูลนี้ขึ้นอยู่กับโมดูลอื่นๆ ทั้งหมดในโปรเจ็กต์

ลำดับชั้นของโมดูลสามารถมีลักษณะดังนี้:
#2: การตั้งค่าการฉีดพึ่งพา
แม้จะขึ้นต่อกันระหว่างโมดูลโปรเจ็กต์ คุณก็ควรตั้งค่าการพึ่งพากริชด้วย กริชเสนอสองวิธีในการประกาศการพึ่งพา: ส่วนประกอบย่อย และ การพึ่งพาส่วนประกอบ
การพึ่งพาองค์ประกอบย่อยของ Dagger ต้องการให้ผู้ปกครองประกาศรายการย่อยที่อยู่ในความอุปการะทั้งหมด ระหว่างโมดูลโครงการ ความสัมพันธ์ประเภทนี้จะไม่ทำงาน เพราะมันตรงกันข้ามกับทิศทางของการพึ่งพาโมดูลโครงการ แต่สามารถใช้ได้ภายในโมดูลโครงการแยกต่างหาก
การพึ่งพาองค์ประกอบกริชมีความยืดหยุ่นมากกว่า เนื่องจากเด็กสามารถประกาศได้ว่าขึ้นอยู่กับพาเรนต์ ทำให้สามารถใช้การพึ่งพาประเภทนี้ระหว่างโมดูลโครงการที่แยกจากกัน

ในบางจุด คุณอาจพบว่าโมดูลมากกว่าหนึ่งโมดูลต้องการความรู้ที่จำกัดเกี่ยวกับโมดูลอื่น ตัวอย่างที่ดีของสิ่งนี้คือการนำทางระหว่างโมดูลคุณลักษณะ การให้ความสัมพันธ์ประเภทนี้มักเรียกว่า การพึ่งพาแนวนอน ในการสร้างช่องทางการสื่อสารระหว่างโมดูลที่แยกจากกัน จำเป็นต้องมีโมดูลเพิ่มเติมพร้อมอินเทอร์เฟซที่อธิบายการสื่อสารและโมดูลซึ่งจะผูกการใช้งานกับอินเทอร์เฟซที่ประกาศไว้
การตั้งค่าการพึ่งพาโมดูลโครงการเพื่อจัดการการพึ่งพาแนวนอนแสดงในภาพด้านล่าง:

ตัวอย่างรหัสสำหรับความสัมพันธ์ดังกล่าวมีอยู่ในโครงการท้ายบทความ
#3: การตั้งค่า Gradle
ทุกโมดูลโครงการมี gradle.build ซึ่งค่อนข้างเหมือนกันยกเว้นการพึ่งพาและปลั๊กอินที่เพิ่มเข้ามา ดังนั้นจึงเป็นเรื่องดีที่จะแยกการกำหนดค่าซ้ำ ๆ ไปยังไฟล์ gradle หนึ่งไฟล์ที่รูทไดเร็กทอรีโปรเจ็กต์ ไฟล์ดังกล่าวยังสามารถลงทะเบียนงาน gradle ทั่วไปเพื่อดำเนินการวิเคราะห์รหัสคงที่หรือเรียกใช้การทดสอบหน่วย
พบข้อมูลโค้ดของการตั้งค่าทั่วไปดังกล่าวที่นี่:
afterEvaluate { project -> def isAndroid = project.plugins.hasPlugin('com.android.library') || project.plugins.hasPlugin('com.android.application') setupModule(isAndroid) setupCommonTestDependencies(isAndroid) setupCommonTasks(isAndroid) } def setupModule(isAndroid) { if (isAndroid) { android { compileSdkVersion projectCompileSdk defaultConfig { minSdkVersion projectMinSdk targetSdkVersion projectTargetSdk } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } lintOptions { abortOnError true checkReleaseBuilds false checkAllWarnings true warningsAsErrors true def lintBaseline = file("quality/lint-baseline.xml") if (lintBaseline.exists()) baseline lintBaseline } } } else { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } } def setupCommonTestDependencies(isAndroid) { dependencies { testImplementation "junit:junit:${junitVersion}" testImplementation "org.assertj:assertj-core:${assertJVersion}" testImplementation "org.mockito:mockito-core:${mockitoVersion}" testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:${mockitoKotlinVersion}" if (isAndroid) { androidTestImplementation "androidx.test.ext:junit:${axTestJUnitVersion}" androidTestImplementation "androidx.test.espresso:espresso-core:${axEspressoLibVersion}" } } } def setupCommonTasks(isAndroid) { if (isAndroid) { tasks.register("unitTest") { task -> task.dependsOn(testDebugUnitTest) } } else { tasks.register("unitTest") { task -> task.dependsOn(test) } } }
บทสรุป
บทความนี้ไม่ละเอียดถี่ถ้วนหรือเป็นคู่มือฉบับสมบูรณ์สำหรับการทำให้เป็นโมดูลของโปรเจ็กต์ Android แต่ฉันคิดว่ามันจัดการกับแง่มุมที่คุณควรพิจารณาเมื่อเริ่มต้นการทำโมดูลาร์ของโครงการ
โค้ดสำหรับแสดงการพึ่งพาแนวนอนอยู่ที่ลิงก์
ต้องการสร้างแอปพลิเคชันดั้งเดิมสำหรับ Android หรือไม่? เลือกมิกิโด!