0Pricing
Android Academy · บทเรียน

เหตุใดจึงควรแยกเป็นโมดูล

ความเร็วในการสร้าง ความเป็นเจ้าของ และการนำกลับมาใช้ใหม่

เหตุใดจึงควรแยกเป็นโมดูล เป็นบทเรียน Android Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Android Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Android Academy มีบทเรียนทั้งหมด 4 บทเรียน

ปัญหาของโมโนลิธ

เมื่อแอป Android เติบโตขึ้น โค้ดทั้งหมดมักจะอยู่ในโมดูล app เดียว นี่คือ โมโนลิธ ช่วงแรกจะสะดวก แต่เมื่อเวลาผ่านไปจะเริ่มยุ่งยาก: การเปลี่ยนแปลงทุกอย่างกระทบโมดูลเดียวกัน การสร้างใช้เวลานานขึ้น และสมาชิกในทีมก็รบกวนงานของกันและกันอยู่เสมอ

การทำให้เป็นโมดูล หมายถึงการแบ่งโมดูลขนาดใหญ่นั้นออกเป็นโมดูล Gradle ขนาดเล็กที่มุ่งเน้นหน้าที่หลายโมดูล ในบทเรียนนี้ คุณจะเรียนรู้ว่าทำไมทีมจึงทำเช่นนี้และมีประโยชน์ที่เป็นรูปธรรมอย่างไร

โมดูลคืออะไรในทางปฏิบัติ

ใน Gradle โมดูล คือหน่วยโค้ดที่สร้างแยกจากกันได้และมีไฟล์ build.gradle.kts ของตัวเอง แอปของคุณมีอย่างน้อยหนึ่งโมดูลอยู่แล้ว นั่นคือโมดูล :app คุณประกาศทุกโมดูลไว้ใน settings.gradle.kts

การเพิ่มโมดูลทำได้ง่ายเพียงแค่เพิ่มโมดูลนั้นเข้าไป แต่ละโมดูลจะสร้างผลลัพธ์การสร้างของตัวเอง และสามารถพึ่งพาโมดูลอื่นได้

// settings.gradle.kts
include(":app")
include(":core:designsystem")
include(":core:data")
include(":feature:home")
include(":feature:profile")

ประโยชน์ข้อที่ 1: สร้างได้เร็วขึ้น

ประโยชน์ที่เห็นได้ชัดที่สุดคือ ความเร็วในการสร้าง Gradle สามารถสร้างโมดูลแบบ ขนาน และที่สำคัญคือ แคชและข้าม โมดูลที่อินพุตไม่เปลี่ยนแปลงได้

หากคุณแก้ไขเฉพาะ :feature:profile Gradle จะนำผลลัพธ์ที่สร้างไว้แล้วของโมดูลอื่นทั้งหมดกลับมาใช้ ในโมโนลิธ การเปลี่ยนแปลงใด ๆ อาจบังคับให้คอมไพล์แอปทั้งหมดใหม่

  • การทำงานแบบขนานระหว่างโมดูล
  • การสร้างแบบเพิ่มทีละส่วน: สร้างใหม่เฉพาะส่วนที่เปลี่ยนแปลง
  • อัตราการใช้แคชระยะไกลและแคชการสร้างได้ดีขึ้น
// gradle.properties
org.gradle.parallel=true
org.gradle.caching=true
org.gradle.configuration-cache=true

ประโยชน์ข้อที่ 2: ขอบเขตที่ชัดเจน

โมดูลช่วยกำหนด ขอบเขต โค้ดในโมดูลหนึ่งจะมองเห็นได้เฉพาะสิ่งที่อีกโมดูลจงใจเปิดเผยเท่านั้น วิธีนี้ป้องกันโค้ดพันกันยุ่งเหยิงที่ทุกคลาสเข้าถึงคลาสอื่นไปหมด

คุณควบคุมการมองเห็นได้ด้วยการกำหนดค่า Gradle แบบ api และ implementation โดย implementation จะทำให้การพึ่งพาเป็นส่วนตัวภายในโมดูล ผู้ใช้โมดูลจึงไม่สามารถนำไปใช้โดยไม่ตั้งใจได้

// feature/profile/build.gradle.kts
dependencies {
    // Exposed to whoever depends on :feature:profile
    api(project(":core:model"))

    // Private: hidden from consumers of this module
    implementation(project(":core:network"))
}

ประโยชน์ข้อที่ 3: การนำกลับมาใช้ใหม่

เมื่อย้ายตรรกะมาไว้ในโมดูลที่มุ่งเน้นหน้าที่แล้ว คุณสามารถ นำกลับมาใช้ใหม่ ได้ทุกที่ โมดูล :core:designsystem ที่เก็บธีม สี และ composable ที่นำกลับมาใช้ใหม่ได้ สามารถแชร์ให้ทุกฟีเจอร์ใช้ร่วมกัน

แนวคิดเดียวกันนี้ขยายไปยังหลายแอปได้ บริษัทสามารถแชร์โมดูล :core:network ระหว่างผลิตภัณฑ์หลายรายการ แทนการคัดลอกโค้ด

// Any feature can pull in shared building blocks
// feature/home/build.gradle.kts
dependencies {
    implementation(project(":core:designsystem"))
    implementation(project(":core:data"))
}

ประโยชน์ข้อที่ 4: ความรับผิดชอบของทีม

โมดูลสอดคล้องกับ ความรับผิดชอบของทีม ได้เป็นอย่างดี ทีมชำระเงินรับผิดชอบ :feature:payments ส่วนทีมโปรไฟล์รับผิดชอบ :feature:profile ทั้งสองทีมทำงานขนานกันได้โดยมีข้อขัดแย้งตอนรวมโค้ดน้อยลง เพราะโค้ดอยู่ในโฟลเดอร์และไฟล์การสร้างคนละชุด

เครื่องมืออย่างไฟล์ CODEOWNERS สามารถขอให้ทีมที่เหมาะสมตรวจสอบโดยอัตโนมัติ ตามเส้นทางของโมดูล

# .github/CODEOWNERS
/feature/payments/   @org/payments-team
/feature/profile/    @org/profile-team
/core/designsystem/  @org/platform-team

ประโยชน์ข้อที่ 5: การห่อหุ้มด้วยการมองเห็น

ภายในโมดูล ตัวปรับแต่ง internal ของ Kotlin มีประโยชน์อย่างมาก คลาสหรือฟังก์ชันที่เป็น internal จะมองเห็นได้ เฉพาะภายในโมดูลของตัวเองเท่านั้น โมดูลอื่นไม่สามารถอ้างอิงสิ่งนั้นได้โดยตรง

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

// In :core:data
// Public API other modules may use
fun interface UserRepository {
    suspend fun loadUser(id: String): User
}

// Hidden from other modules
internal class DefaultUserRepository(
    private val api: UserApi
) : UserRepository {
    override suspend fun loadUser(id: String) = api.fetch(id).toUser()
}

ต้นทุน: ค่าใช้จ่ายเพิ่มเติมบางส่วน

การทำให้เป็นโมดูลไม่ได้ไม่มีต้นทุน แต่ละโมดูลเพิ่มไฟล์ build.gradle.kts ที่ต้องดูแล และคุณต้องคิดว่าโค้ดแต่ละส่วนควรเป็นของโมดูลใด การแบ่งโมดูลมากเกินไปในแอปขนาดเล็กจะเพิ่มงานจุกจิกโดยไม่ได้ประโยชน์คุ้มค่า

หลักทั่วไปคือ ควรทำให้เป็นโมดูลเมื่อเวลาสร้างนานจนเป็นปัญหา เมื่อทีมทำงานทับซ้อนกัน หรือเมื่อมีชั้นโค้ดที่นำกลับมาใช้ใหม่ได้อย่างชัดเจน แอปงานอดิเรกที่ทำช่วงสุดสัปดาห์แทบไม่จำเป็นต้องมี 30 โมดูล

โครงสร้างโมดูลทั่วไป

โครงสร้างที่พบได้บ่อยและขยายต่อได้จะแบ่งโมดูลออกเป็นชั้น app, feature และ core โมดูล :app เชื่อมทุกอย่างเข้าด้วยกัน ฟีเจอร์เก็บหน้าจอที่ผู้ใช้มองเห็น ส่วนโมดูล core เก็บโครงสร้างพื้นฐานที่ใช้ร่วมกัน

// Conceptual project tree
// app/                  <- single entry point, wires features
// feature/
//   home/
//   profile/
//   settings/
// core/
//   designsystem/       <- theme + reusable composables
//   data/               <- repositories
//   network/            <- Retrofit/Ktor
//   model/              <- shared data classes

ปลั๊กอินตามแบบแผนช่วยให้จัดการได้ง่าย

เมื่อมีหลายโมดูล การคัดลอกการตั้งค่า Gradle เดิม ๆ ไปไว้ทุกแห่งเป็นกับดัก ทีมจึงแยกการตั้งค่าที่ใช้ร่วมกันออกมาเป็น ปลั๊กอินตามแบบแผน (ในโมดูล build-logic) จากนั้นแต่ละโมดูลจริงจะใช้ปลั๊กอินเพียงหนึ่งตัว แทนการเขียนซ้ำหลายสิบบรรทัด

คุณจะเห็นรูปแบบนี้ในแอปโอเพนซอร์สขนาดใหญ่อย่าง Now in Android สำหรับตอนนี้ ขอให้เข้าใจเป้าหมายไว้ว่า ต้องทำให้ไฟล์การสร้างมีขนาดเล็กและสอดคล้องกัน

// feature/home/build.gradle.kts
plugins {
    // One convention plugin sets up Android + Compose + Kotlin
    id("myapp.android.feature")
}

android { namespace = "com.myapp.feature.home" }

แนวคิด: คิดเป็นชั้น

แบบจำลองทางความคิดที่มีประโยชน์ที่สุดคือ การพึ่งพาควรไหล ลงด้านล่าง ฟีเจอร์พึ่งพา core ส่วน core ไม่พึ่งพาฟีเจอร์ โมดูล :app อยู่บนสุดและพึ่งพาทุกสิ่งที่จำเป็นต่อการประกอบแอป

หากรักษาทิศทางนี้ให้สม่ำเสมอ กราฟโมดูลจะสะอาดและคุณจะหลีกเลี่ยงการวนซ้ำ ซึ่งคุณจะได้ศึกษาในบทเรียนถัดไป

// Allowed:  app -> feature -> core
// Forbidden: core -> feature (upward) or feature -> feature (sideways)
// app/build.gradle.kts
dependencies {
    implementation(project(":feature:home"))
    implementation(project(":feature:profile"))
}

ตรวจสอบความเข้าใจ

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

สรุป: ทำไมต้องทำให้เป็นโมดูล

คุณได้เรียนรู้ว่าทำไมทีมจึงแบ่งโมโนลิธออกเป็นโมดูล:

  • สร้างได้เร็วขึ้น ด้วยการทำงานแบบขนานและการแคชแบบเพิ่มทีละส่วน
  • ขอบเขตที่ชัดเจน ด้วย api/implementation และ internal
  • การนำกลับมาใช้ใหม่ ของชั้น core เช่น ระบบการออกแบบและเครือข่าย
  • ความรับผิดชอบของทีม พร้อมข้อขัดแย้งตอนรวมโค้ดที่น้อยลง

คุณยังได้เห็นต้นทุน (ไฟล์การสร้างที่เพิ่มขึ้น) และกฎทองคำว่า การพึ่งพาไหลลงด้านล่าง app -> feature -> core ขั้นต่อไป คุณจะวาดขอบเขตจริงระหว่างโมดูล feature และ core

คำถามที่พบบ่อย

บทเรียน “เหตุใดจึงควรแยกเป็นโมดูล” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “เหตุใดจึงควรแยกเป็นโมดูล” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Android Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Android Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “เหตุใดจึงควรแยกเป็นโมดูล”

ความเร็วในการสร้าง ความเป็นเจ้าของ และการนำกลับมาใช้ใหม่ คุณปฏิบัติ Android Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Android Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Android Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน

บทเรียน “เหตุใดจึงควรแยกเป็นโมดูล” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Android Academy นี้ได้ไหม

ได้ บทเรียน Android Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. เหตุใดจึงควรแยกเป็นโมดูล
  2. โมดูลฟีเจอร์และโมดูลแกนกลาง
  3. การจัดการการพึ่งพาระหว่างโมดูล
  4. การนำทางข้ามโมดูล
← กลับไปที่ Android Academy