Router (রাউটার) — একটি আর্কিটেকচারাল প্যাটার্ন যা অ্যাপ্লিকেশন স্ক্রিনের মধ্যে নেভিগেশন লজিককে কেন্দ্রীভূত করে। Router নির্ধারণ করে কোন ঘটনা发生时 কোথায় এবং কীভাবে নেভিগেট করতে হবে। iOS-এ, Router UINavigationController এবং segue-কে অ্যাবস্ট্র্যাক্ট করে; Android-এ — FragmentManager এবং Jetpack Navigation-এর NavController-কে। Router একটি স্বাধীন প্যাটার্ন হিসাবে বা Coordinator (Router-per-Coordinator) এবং VIPER (Router-per-module)-এর উপাদান হিসাবে কাজ করতে পারে। আরও বিস্তারিত — Android Navigation Component Guide-এ।
মুখ্য বিষয়
Router — একটি প্যাটার্ন যা স্ক্রিনের মধ্যে স্থানান্তরের লজিককে এনক্যাপসুলেট করে। মূল ধারণা: ViewController (বা Presenter/ViewModel) সরাসরি navigationController.pushViewController কল করে না, বরং নেভিগেট করার অভিপ্রায় সম্পর্কে Router-কে জানায়। Router সিদ্ধান্ত নেয় কোন ViewController তৈরি করতে হবে এবং কীভাবে এটি প্রদর্শন করতে হবে। Router সহজ (নেভিগেশন পদ্ধতির সেট) বা জটিল (URL স্কিম রাউটিং, deep links এবং push বিজ্ঞপ্তি সহ) হতে পারে।
Router-এর তিনটি পদ্ধতি — পরিষেবা হিসাবে Router (গ্লোবাল Navigator সিঙ্গলটন), মডিউল উপাদান হিসাবে Router (VIPER পদ্ধতি), প্রোটোকল হিসাবে Router (Coordinator-এর জন্য অ্যাবস্ট্র্যাকশন)। গ্লোবাল Router — সরলতা (প্রতি অ্যাপে একটি ইনস্ট্যান্স) — ছোট প্রকল্পে জনপ্রিয়। মডিউলার Router — প্রতিটি ফিচারের নিজস্ব Router — VIPER এবং Clean Architecture মান। প্রোটোকল Router — Coordinator-এ ব্যবহৃত: push/present/pop/dismiss পদ্ধতি সহ RouterProtocol।
| পদ্ধতি | গঠন | কখন ব্যবহার করবেন |
|---|---|---|
| গ্লোবাল Navigator | নেভিগেশন পদ্ধতি সহ সিঙ্গলটন | ছোট প্রকল্প, প্রোটোটাইপ |
| মডিউলার Router | প্রতিটি মডিউলের ভিতর Router | VIPER, Clean Architecture |
| প্রোটোকল Router | Coordinator-এর জন্য প্রোটোকল + বাস্তবায়ন | MVVM-C, Coordinator pattern |
প্যাটার্নের ইতিহাস — Router ওয়েব ফ্রেমওয়ার্কে (URL Router — Rails Routes, Express.js) আবির্ভূত হয়েছিল এবং মোবাইল ডেভেলপমেন্টের জন্য অভিযোজিত হয়েছিল। iOS-এ, VIPER (2015-2017) এর উত্থানের সাথে Router জনপ্রিয় হয়েছিল। Android-এ, Router Jetpack Navigation (2018) এর অংশ, Google-এর মানক নেভিগেশন সমাধান। আজ, Router যেকোনো মডিউলার মোবাইল অ্যাপ্লিকেশন আর্কিটেকচারের একটি অবিচ্ছেদ্য অংশ।
iOS Router — বিভিন্ন নেভিগেশন প্রকারের জন্য পদ্ধতি সহ একটি প্রোটোকল। মৌলিক বাস্তবায়ন UINavigationController-কে র্যাপ করে। Router মডেল প্রেজেন্টেশন (present/dismiss), নেভিগেশন স্ট্যাকে push/pop, Split View Controller-এর জন্য showDetail এবং ফুল-স্ক্রিন প্রেজেন্টেশন (iOS 13+) পরিচালনা করতে পারে। Router ViewControllers তৈরি করে না — এটি একটি প্রস্তুত ইনস্ট্যান্স গ্রহণ করে এবং এটি প্রদর্শন করে। ViewController তৈরি একটি ফ্যাক্টরি (Assembly, DI কন্টেইনার) বা Coordinator দ্বারা পরিচালিত হয়।
// iOS-এর জন্য RouterProtocol
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)
}
// UINavigationController-এর মাধ্যমে Router বাস্তবায়ন
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
}
VIPER-এ Router — প্রতিটি VIPER মডিউলের নিজস্ব Router থাকে, যা জানে বর্তমান মডিউল থেকে কোন স্ক্রিন খুলতে হবে। Router একটি ফ্যাক্টরির মাধ্যমে পরবর্তী মডিউলের ViewController তৈরি করে এবং নিয়ন্ত্রণ হস্তান্তর করে। VIPER-এ Router হল একমাত্র উপাদান যাতে import UIKit রয়েছে (View ছাড়া)। এটি Presenter এবং Interactor-এর পরীক্ষা সহজ করে: তারা UIKit-এর উপর নির্ভর করে না।
Jetpack Navigation Component — Android-এর জন্য মানক রাউটার, 2018 থেকে Google দ্বারা সুপারিশকৃত। নেভিগেশন XML গ্রাফে (nav_graph.xml) সংজ্ঞায়িত করা হয়েছে: নোড (fragments, activities, destinations) এবং প্রান্ত (actions)। NavController স্থানান্তর পরিচালনা করে: FragmentManager.replace/add কল করে এবং ব্যাক স্ট্যাক পরিচালনা করে। Navigation Component deep links, আর্গুমেন্ট, স্থানান্তর অ্যানিমেশন এবং type-safe ডেটা পাসিংয়ের জন্য Safe Args সমর্থন করে।
// 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)
}
}
Android Navigation-এ Deep links — Navigation Component স্পষ্ট deep links (PendingIntent + NavDeepLinkBuilder) এবং অন্তর্নিহিত (ম্যানিফেস্টে intent-filter এর মাধ্যমে) সমর্থন করে। একটি deep link যেকোনো nav_graph নোডে নিয়ে যেতে পারে। push বিজ্ঞপ্তি পরিচালনা: Notification NavDeepLinkBuilder-এর সাথে PendingIntent তৈরি করে, যা ব্যাক স্ট্যাক পুনরুদ্ধার করে এবং কাঙ্ক্ষিত স্ক্রিন খোলে। Navigation Component স্বয়ংক্রিয়ভাবে Up/Back বাটন পরিচালনা করে এবং ব্যবহারকারীকে পূর্ববর্তী স্ক্রিনে ফিরিয়ে দেয়।
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।
// 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 — URLs-কে রুটে ম্যাপ করা
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 vs Coordinator — Router প্রশ্নের উত্তর দেয় "কীভাবে স্ক্রিন দেখাবেন?" (push/present), Coordinator — "কোন স্ক্রিন দেখাবেন?" (কোন ফ্লো শুরু করবেন)। Router একটি নেভিগেশন টুল, Coordinator একটি ফ্লো সংগঠক। Coordinator Router ব্যবহার করে। VIPER-এ, Router উভয় কার্য সম্পাদন করে: কোথায় যেতে হবে এবং কীভাবে দেখাতে হবে তা সিদ্ধান্ত নেয়। MVVM-C-তে, Router একটি পৃথক প্রোটোকল যা Coordinator ব্যবহার করে। প্যাটার্নগুলি একে অপরকে বাদ দেয় না বরং পরিপূরক করে।
| বৈশিষ্ট্য | Router | Coordinator | Navigator |
|---|---|---|---|
| ফোকাস | নেভিগেশন মেকানিক্স | নেভিগেশন ফ্লো | গ্লোবাল অ্যাক্সেস |
| স্তর | UI ফ্রেমওয়ার্ক (push/present) | ব্যবসায়িক লজিক (ফ্লো) | অবকাঠামো |
| স্ক্রিন তৈরি | প্রস্তুত VC গ্রহণ করে | ফ্যাক্টরির মাধ্যমে VC তৈরি করে | VC তৈরি করে |
| জীবনচক্র | প্রতি নেভিগেশনে একটি | childCoordinators | Singleton |
Router vs Navigator — Navigator হল iOS সম্প্রদায়ে Router-এর পুরানো নাম। প্রাথমিক বাস্তবায়নে, Navigator ছিল নেভিগেশন পদ্ধতি সহ একটি Singleton ক্লাস। Navigator একটি গ্লোবাল Router সিঙ্গলটন। Navigator সহজ কিন্তু লুকানো নির্ভরতা তৈরি করে। প্রোটোকল-ভিত্তিক Router বেশি পরীক্ষাযোগ্য এবং মডিউলার। Navigator কঠোর আর্কিটেকচার ছাড়া প্রকল্পের জন্য উপযুক্ত, Router — Clean Architecture এবং VIPER-এর জন্য।
সচরাচর জিজ্ঞাসিত প্রশ্ন
Router হল UINavigationController (push/present/pop) এর উপর একটি অ্যাবস্ট্র্যাকশন। Coordinator হল Router-এর উপরের একটি স্তর যা ফ্লো পরিচালনা করে (এরপরে কোন স্ক্রিন দেখাতে হবে)। Router মেকানিক্স পরিচালনা করে, Coordinator নেভিগেশন লজিক পরিচালনা করে। Coordinator স্থানান্তর সম্পাদনের জন্য Router ব্যবহার করে। VIPER-এ, Router উভয় ফাংশন একত্রিত করে; MVVM-C-তে, সেগুলি পৃথক।
না। 3-5 স্ক্রিনের অ্যাপ্লিকেশনের জন্য, navigationController.pushViewController-এর সরাসরি কল একটি সম্পূর্ণ গ্রহণযোগ্য সমাধান। Router 10+ স্ক্রিন, deep links, push বিজ্ঞপ্তি এবং মডিউলার আর্কিটেকচারের সাথে উপযোগী হয়। Router নেভিগেশন পরীক্ষা সহজ করে এবং যেকোনো উৎস (বাটন, deep link, push বিজ্ঞপ্তি) থেকে স্থানান্তর কেন্দ্রীয়ভাবে পরিচালনা করার অনুমতি দেয়।
URL Router হল Router-এর একটি এক্সটেনশন যা deep links এবং universal links পার্স করে। URL Router URL এবং অ্যাপ স্ক্রিনের মধ্যে ম্যাপিং নির্ধারণ করে। উদাহরণস্বরূপ, রুট myapp://profile/42 → ProfileViewController(userId: 42)। URL Router বিভিন্ন উৎস থেকে deep link হ্যান্ডলিং কেন্দ্রীভূত করে: push বিজ্ঞপ্তি, QR কোড, ইমেল লিঙ্ক, ইউনিভার্সাল লিঙ্ক।
হ্যাঁ। Router স্বাধীনভাবে কাজ করতে পারে — গ্লোবাল Navigator হিসাবে বা VIPER মডিউল উপাদান হিসাবে। Coordinator ছাড়া Router কেবল একটি প্রোটোকলের পিছনে UINavigationController এনক্যাপসুলেট করছে। Coordinator ছাড়া Router আরও জটিল (ViewController সরাসরি push/present কল করে), কিন্তু সম্ভব। সর্বোত্তম অনুশীলন হল Router + Coordinator একসাথে।
কার্যকরীভাবে — হ্যাঁ, উভয়ই নেভিগেশন কেন্দ্রীভূত করে। বাস্তবায়ন ভিন্ন: iOS Router — UINavigationController-এর চারপাশে প্রোটোকল + ক্লাস; Android — XML গ্রাফ এবং NavController সহ Jetpack Navigation Component। Android Router ফ্রেমওয়ার্কে (Navigation Component) নির্মিত, iOS Router একটি তৃতীয় পক্ষের বাস্তবায়ন। Android Router Safe Args সমর্থন করে, iOS Router করে না (generics বা Codable প্রয়োজন)।
সারাংশ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন