Router — พื้นฐานของรูปแบบการกำหนดเส้นทางใน iOS และ Android

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-02-19 เวลาอ่าน: 9 นาที

Router (เราเตอร์) — รูปแบบทางสถาปัตยกรรมที่รวมศูนย์ตรรกะการนำทางระหว่างหน้าจอของแอปพลิเคชัน Router กำหนดว่าจะนำทางไปที่ไหนและอย่างไรเมื่อเกิดเหตุการณ์ ใน iOS Router ทำนามธรรมของ UINavigationController และ segue ใน Android — FragmentManager และ NavController จาก Jetpack Navigation Router สามารถทำงานเป็นรูปแบบอิสระหรือเป็นส่วนประกอบของ Coordinator (Router-per-Coordinator) และ VIPER (Router-per-module) รายละเอียดเพิ่มเติม — ใน Android Navigation Component Guide

ประเด็นสำคัญ

  • Router — รูปแบบการกำหนดเส้นทางที่รวมศูนย์การนำทางระหว่างหน้าจอ
  • สองระดับ — Router สามารถเป็นส่วนประกอบของ Coordinator หรือรูปแบบอิสระ
  • iOS Router — นามธรรมเหนือ UINavigationController ด้วยเมธอด push/present/pop
  • Android Router — Jetpack Navigation Component พร้อม NavController และ deep links
  • URL Routing — การกำหนดเส้นทางตามโครงร่าง URL (deeplink, universal link)

Router คืออะไร: แก่นแท้ของรูปแบบการกำหนดเส้นทาง

Router — รูปแบบที่ห่อหุ้มตรรกะการเปลี่ยนระหว่างหน้าจอ แนวคิดหลัก: ViewController (หรือ Presenter/ViewModel) ไม่ได้เรียก navigationController.pushViewController โดยตรง แต่แจ้ง Router ถึงความตั้งใจที่จะนำทาง Router ตัดสินใจว่าจะสร้าง ViewController ใดและจะแสดงอย่างไร Router สามารถเรียบง่าย (ชุดของเมธอดการนำทาง) หรือซับซ้อน (พร้อมการกำหนดเส้นทางโครงร่าง URL, deep links และการแจ้งเตือนแบบ push)

สามแนวทางสำหรับ Router — Router ในฐานะบริการ (Navigator singleton ทั่วโลก), Router ในฐานะส่วนประกอบโมดูล (แนวทาง VIPER), Router ในฐานะโปรโตคอล (นามธรรมสำหรับ Coordinator) Router ทั่วโลก — ความเรียบง่าย (หนึ่งอินสแตนซ์ต่อแอป) — เป็นที่นิยมในโปรเจกต์ขนาดเล็ก Router แบบโมดูล — แต่ละฟีเจอร์มี Router ของตัวเอง — มาตรฐาน VIPER และ Clean Architecture Router แบบโปรโตคอล — ใช้ใน Coordinator: RouterProtocol พร้อมเมธอด push/present/pop/dismiss

แนวทางโครงสร้างเมื่อใดควรใช้
Navigator ทั่วโลกSingleton พร้อมเมธอดการนำทางโปรเจกต์ขนาดเล็ก, ต้นแบบ
Router แบบโมดูลRouter ภายในแต่ละโมดูลVIPER, Clean Architecture
Router แบบโปรโตคอลโปรโตคอล + การใช้งานสำหรับ CoordinatorMVVM-C, Coordinator pattern

ประวัติของรูปแบบ — Router ปรากฏในเว็บเฟรมเวิร์ก (URL Router — Rails Routes, Express.js) และถูกปรับใช้สำหรับการพัฒนาโมบายล์ ใน iOS Router ได้รับความนิยมจากการเติบโตของ VIPER (2015-2017) ใน Android Router เป็นส่วนหนึ่งของ Jetpack Navigation (2018) โซลูชันการนำทางมาตรฐานของ Google ปัจจุบัน Router เป็นส่วนสำคัญของสถาปัตยกรรมแอปพลิเคชันโมบายล์แบบโมดูล

Router ใน iOS: การใช้งานด้วย Swift

iOS Router — โปรโตคอลพร้อมเมธอดสำหรับการนำทางประเภทต่างๆ การใช้งานพื้นฐานห่อหุ้ม UINavigationController Router สามารถจัดการการแสดงผลแบบโมดอล (present/dismiss), push/pop ในสแต็กการนำทาง, showDetail สำหรับ Split View Controller และการแสดงผลแบบเต็มหน้าจอ (iOS 13+) Router ไม่ได้สร้าง ViewControllers — รับอินสแตนซ์ที่พร้อมแล้วและแสดงผล การสร้าง ViewController จัดการโดยโรงงาน (Assembly, ตัวบรรจุ DI) หรือ Coordinator

swift
// RouterProtocol สำหรับ iOS
protocol RouterProtocol {
    func push(_ viewController: UIViewController, animated: Bool)
    func pop(animated: Bool)
    func popToRoot(animated: Bool)
    func present(_ viewController: UIViewController, animated: Bool)
    func dismiss(animated: Bool)
    func setViewControllers(_: [UIViewController], animated: Bool)
}

// การใช้งาน Router ผ่าน UINavigationController
class NavigationRouter: RouterProtocol {
    private let navigationController: UINavigationController

    init(navigationController: UINavigationController) {
        self.navigationController = navigationController
    }

    func push(_ vc: UIViewController, animated: Bool) {
        if navigationController.presentedViewController {
            navigationController.dismiss(animated: false)
        }
        navigationController.pushViewController(vc, animated: animated)
    }

    func pop(animated: Bool) {
        navigationController.popViewController(animated: animated)
    }

    func popToRoot(animated: Bool) {
        navigationController.popToRootViewController(animated: animated)
    }

    func present(_ vc: UIViewController, animated: Bool) {
        navigationController.present(vc, animated: animated)
    }

    func dismiss(animated: Bool) {
        navigationController.dismiss(animated: animated)
    }

    func setViewControllers(_ vcs: [UIViewController], animated: Bool) {
        navigationController.setViewControllers(vcs, animated: animated)
    }
}

// Assembly — การสร้างโมดูลด้วย Router
protocol ProfileModuleFactory {
    func makeProfileView() -> UIViewController
}

Router ใน VIPER — แต่ละโมดูล VIPER มี Router ของตัวเอง ซึ่งรู้ว่าหน้าจอใดควรเปิดจากโมดูลปัจจุบัน Router สร้าง ViewController ของโมดูลถัดไปผ่านโรงงานและส่งต่อการควบคุม Router ใน VIPER เป็นส่วนประกอบเดียวที่มี import UIKit (ยกเว้น View) ซึ่งทำให้การทดสอบ Presenter และ Interactor ง่ายขึ้น: ไม่ขึ้นอยู่กับ UIKit

Router ใน Android: Jetpack Navigation Component

Jetpack Navigation Component — เราเตอร์มาตรฐานสำหรับ Android ที่ Google แนะนำตั้งแต่ปี 2018 การนำทางถูกกำหนดในกราฟ XML (nav_graph.xml): โหนด (fragments, activities, destinations) และขอบ (actions) NavController จัดการการเปลี่ยน: เรียก FragmentManager.replace/add และจัดการสแต็กย้อนกลับ Navigation Component รองรับ deep links, อาร์กิวเมนต์, แอนิเมชันการเปลี่ยน และ Safe Args สำหรับการส่งข้อมูลแบบ type-safe

kotlin
// nav_graph.xml — กราฟการนำทาง
<!-- @xml/nav_graph.xml -->
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/nav_graph"
    app:startDestination="@id/loginFragment">

    <fragment android:id="@+id/loginFragment"
        android:name=".ui.login.LoginFragment">
        <action android:id="@+id/to_home"
            app:destination="@id/homeFragment" />
    </fragment>

    <fragment android:id="@+id/homeFragment"
        android:name=".ui.home.HomeFragment">
        <argument android:name="userId"
            android:defaultValue="0"
            app:argType="integer" />
        <deepLink app:uri="myapp://home/{userId}" />
    </fragment>
</navigation>

// Kotlin — การนำทางผ่าน NavController
class LoginFragment : Fragment() {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding.loginButton.setOnClickListener {
            val action = LoginFragmentDirections.toHome(userId = 42)
            findNavController().navigate(action)
        }
    }
}

// Safe Args — อาร์กิวเมนต์แบบ type-safe
class HomeFragmentArgs : NavArgs {
    val userId: Int get() = arguments?.getInt("userId") ?: 0
}

// NavigationUI — การรวมกับ Toolbar, BottomNav, Drawer
class MainActivity : AppCompatActivity() {
    private lateinit var navController: NavController

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val navHost = supportFragmentManager
            .findFragmentById(R.id.nav_host_fragment) as NavHostFragment
        navController = navHost.navController
        NavigationUI.setupActionBarWithNavController(this, navController)
    }
}

Deep links ใน Android Navigation — Navigation Component รองรับ deep links แบบชัดแจ้ง (PendingIntent + NavDeepLinkBuilder) และโดยนัย (ผ่าน intent-filter ในแมนิเฟสต์) deep link สามารถนำไปยังโหนดใดๆ ใน nav_graph การจัดการการแจ้งเตือน push: Notification สร้าง PendingIntent ด้วย NavDeepLinkBuilder ซึ่งกู้คืนสแต็กย้อนกลับและเปิดหน้าจอที่ต้องการ Navigation Component จัดการปุ่ม Up/Back โดยอัตโนมัติและส่งผู้ใช้กลับไปยังหน้าจอก่อนหน้า

URL Routing: การกำหนดเส้นทาง Deeplink และ Universal Link

URL Routing — การกำหนดเส้นทางตามโครงร่าง URL, deep links และ universal links แอปลงทะเบียนโครงร่าง (myapp://profile/42) หรือ universal link (https://example.com/profile/42) Router แยกวิเคราะห์ URL, ดึงพารามิเตอร์ (userId=42) และเปิดหน้าจอที่เกี่ยวข้อง URL Routing ช่วยให้เปิดแอปจากภายนอก: ผ่านลิงก์จากเว็บไซต์, อีเมล, การแจ้งเตือน push, QR โค้ด iOS ใช้ NSUserActivity + universal link, Android — intent-filter + deep link

swift
// URL Router — การแยกวิเคราะห์ deep link และการนำทาง
protocol URLRoute {
    var pattern: String { get }
    func navigate(parameters: [String: String], router: RouterProtocol)
}

struct ProfileRoute: URLRoute {
    let pattern = "myapp://profile/{userId}"

    func navigate(parameters: [String: String], router: RouterProtocol) {
        guard let userId = parameters["userId"] else { return }
        let profileVC = ProfileViewController(userId: userId)
        router.push(profileVC, animated: true)
    }
}

// URL Router — การจับคู่ URL กับเส้นทาง
class URLRouter {
    private var routes: [URLRoute] = []

    func handle(_ url: URL, router: RouterProtocol) {
        for route in routes {
            if let params = matchPattern(route.pattern, url: url) {
                route.navigate(parameters: params, router: router)
                return
            }
        }
    }
}

การกำหนดเส้นทาง deep link ในทางปฏิบัติ — แอปต้องจัดการ deep links ในสามสถานะ: ยังไม่เริ่มทำงาน (เริ่มด้วย deep link), ในพื้นหลัง (กู้คืนจากพื้นหลัง), กำลังทำงาน (onNewIntent/SceneDelegate) URL Router ต้องกู้คืนสแต็กย้อนกลับอย่างถูกต้อง: เมื่อ deep link ไปยังหน้าจอโปรไฟล์ ผู้ใช้ควรสามารถกด Back และกลับไปยังหน้าจอก่อนหน้าได้ iOS และ Android จัดการสแต็กย้อนกลับต่างกัน — Router ต้องคำนึงถึงลักษณะเฉพาะของแต่ละแพลตฟอร์ม

การเปรียบเทียบ Router กับ Coordinator และ Navigator

Router vs Coordinator — Router ตอบคำถาม "จะแสดงหน้าจออย่างไร?" (push/present), Coordinator — "ควรแสดงหน้าจอใด?" (เริ่มโฟลว์ใด) Router เป็นเครื่องมือนำทาง Coordinator เป็นผู้จัดระเบียบโฟลว์ Coordinator ใช้ Router ใน VIPER Router ทำหน้าที่ทั้งสอง: ตัดสินใจว่าจะไปที่ไหนและจะแสดงอย่างไร ใน MVVM-C Router เป็นโปรโตคอลแยกต่างหากที่ Coordinator ใช้ รูปแบบไม่ได้แยกจากกันแต่เสริมซึ่งกันและกัน

ลักษณะRouterCoordinatorNavigator
จุดเน้นกลไกการนำทางโฟลว์การนำทางการเข้าถึงทั่วโลก
ระดับUI framework (push/present)ตรรกะทางธุรกิจ (โฟลว์)โครงสร้างพื้นฐาน
การสร้างหน้าจอรับ VC ที่พร้อมแล้วสร้าง VC ผ่านโรงงานสร้าง VC
วงจรชีวิตหนึ่งครั้งต่อการนำทางchildCoordinatorsSingleton

Router vs Navigator — Navigator เป็นชื่อเก่าของ Router ในชุมชน iOS ในการใช้งานแรกเริ่ม Navigator เป็นคลาส Singleton พร้อมเมธอดการนำทาง Navigator เป็น Router singleton ทั่วโลก Navigator ง่ายกว่าแต่สร้างการพึ่งพาที่ซ่อนอยู่ Router ที่ใช้โปรโตคอลสามารถทดสอบได้และเป็นโมดูลมากกว่า Navigator เหมาะสำหรับโปรเจกต์ที่ไม่มีสถาปัตยกรรมที่เคร่งครัด Router — สำหรับ Clean Architecture และ VIPER

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

ความแตกต่างระหว่าง Router และ Coordinator คืออะไร?

Router เป็นนามธรรมเหนือ UINavigationController (push/present/pop) Coordinator เป็นชั้นเหนือ Router ที่จัดการโฟลว์ (หน้าจอใดจะแสดงถัดไป) Router จัดการกลไก Coordinator จัดการตรรกะการนำทาง Coordinator ใช้ Router เพื่อดำเนินการเปลี่ยน ใน VIPER Router รวมทั้งสองหน้าที่ ใน MVVM-C แยกกัน

จำเป็นต้องใช้ Router ในแอปพลิเคชันโมบายล์หรือไม่?

ไม่ สำหรับแอปที่มี 3-5 หน้าจอ การเรียก navigationController.pushViewController โดยตรงเป็นวิธีที่ยอมรับได้ Router จะมีประโยชน์เมื่อมี 10+ หน้าจอ, deep links, การแจ้งเตือน push และสถาปัตยกรรมแบบโมดูล Router ช่วยให้การทดสอบการนำทางง่ายขึ้นและช่วยให้จัดการการเปลี่ยนจากแหล่งใดๆ (ปุ่ม, deep link, การแจ้งเตือน push) ได้จากส่วนกลาง

Router เกี่ยวข้องกับ Deep Links อย่างไร?

URL Router เป็นส่วนขยายของ Router ที่แยกวิเคราะห์ deep links และ universal links URL Router กำหนดการจับคู่ระหว่าง URL และหน้าจอของแอป ตัวอย่างเช่น เส้นทาง myapp://profile/42 → ProfileViewController(userId: 42) URL Router รวมศูนย์การจัดการ deep links จากแหล่งต่างๆ: การแจ้งเตือน push, QR โค้ด, ลิงก์อีเมล, ลิงก์สากล

สามารถใช้ Router โดยไม่มี Coordinator ได้หรือไม่?

ได้ Router สามารถทำงานอิสระ — ในฐานะ Navigator ทั่วโลกหรือเป็นส่วนประกอบโมดูล VIPER Router ที่ไม่มี Coordinator เป็นเพียงการห่อหุ้ม UINavigationController ไว้ด้านหลังโปรโตคอล Coordinator ที่ไม่มี Router ซับซ้อนกว่า (ViewController เรียก push/present โดยตรง) แต่เป็นไปได้ แนวทางปฏิบัติที่ดีที่สุดคือใช้ Router + Coordinator ร่วมกัน

Router ใน Android เหมือนกับ iOS Router หรือไม่?

ในแง่การทำงาน — ใช่ ทั้งคู่รวมศูนย์การนำทาง การใช้งานต่างกัน: iOS Router — โปรโตคอล + คลาสรอบ UINavigationController; Android — Jetpack Navigation Component พร้อมกราฟ XML และ NavController Android Router ถูกสร้างในเฟรมเวิร์ก (Navigation Component), iOS Router เป็นการใช้งานของบุคคลที่สาม Android Router รองรับ Safe Args, iOS Router ไม่รองรับ (ต้องการ generics หรือ Codable)

สรุป

  • Router — รูปแบบการกำหนดเส้นทางที่ห่อหุ้มตรรกะการเปลี่ยนระหว่างหน้าจอ
  • iOS Router — โปรโตคอลพร้อมเมธอด push/present/pop รอบ UINavigationController
  • Android Router — Jetpack Navigation Component พร้อม XML nav_graph และ NavController
  • URL Routing — การกำหนดเส้นทางผ่าน deep links และ universal links
  • Router vs Coordinator — Router จัดการกลไก Coordinator จัดการโฟลว์การนำทาง
  • การประยุกต์ใช้ — สถาปัตยกรรมแบบโมดูล, deep links, การทดสอบการนำทาง

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม