VIPER: मुख्य अवधारणाएँ, View-Interactor-Presenter-Entity-Router पैटर्न

लेखक: IT Sectr प्रकाशित: 2026-02-16 पढ़ने का समय: 9 मिनट

VIPER (View-Interactor-Presenter-Entity-Router) — Mutual Mobile कंपनी द्वारा iOS ऐप्स के लिए विकसित एक मॉड्यूलर आर्किटेक्चर। VIPER एप्लिकेशन को पाँच परतों में विभाजित करता है: View प्रदर्शन के लिए, Interactor व्यावसायिक तर्क के लिए, Presenter डेटा तैयार करने के लिए, Entity डेटा मॉडल के लिए, Router मॉड्यूल के बीच नेविगेशन के लिए जिम्मेदार है। VIPER मोबाइल आर्किटेक्चर में एकल जिम्मेदारी सिद्धांत का सबसे विस्तृत कार्यान्वयन है। objc.io पर लेख में और पढ़ें।

मुख्य बातें

  • VIPER — पाँच घटक: View, Interactor, Presenter, Entity, Router स्पष्ट जिम्मेदारी सीमाओं के साथ
  • मॉड्यूलरिटी — प्रत्येक स्क्रीन (मॉड्यूल) पृथक है, प्रोटोकॉल के माध्यम से संचार
  • Router — नेविगेशन को Presenter से बाहर ले जाता है, iOS नेविगेशन समस्या का समाधान
  • Interactor — व्यावसायिक तर्क रखता है और UIKit पर निर्भर नहीं करता, यूनिट टेस्ट से परीक्षण योग्य
  • iOS-native — VIPER SwiftUI से पहले UIKit के लिए बनाया गया था और बड़े iOS प्रोजेक्ट्स के लिए मानक बना हुआ है

VIPER क्या है: मॉड्यूलर आर्किटेक्चर के पाँच घटक

VIPER (View-Interactor-Presenter-Entity-Router) — 2013–2014 में Mutual Mobile में बड़े iOS प्रोजेक्ट्स के लिए विकसित एक आर्किटेक्चरल पैटर्न। एप्लिकेशन की प्रत्येक स्क्रीन पाँच घटकों का एक अलग मॉड्यूल है जिसमें कड़ाई से परिभाषित जिम्मेदारियाँ हैं। VIPER मोबाइल डेवलपमेंट में एकल जिम्मेदारी सिद्धांत (Single Responsibility Principle) का सबसे सख्त कार्यान्वयन है: कोई भी घटक वह नहीं करता जो दूसरा कर सकता है।

View एक निष्क्रिय घटक है जो केवल Presenter द्वारा भेजे गए डेटा को प्रदर्शित करने के लिए जिम्मेदार है। View में कोई व्यावसायिक तर्क नहीं है, नेविगेशन नहीं संभालता, नेटवर्क अनुरोध नहीं करता। iOS में — UIViewController एक ViewProtocol के साथ। Interactor व्यावसायिक तर्क परत है जो Entity और सेवाओं (नेटवर्क, DB, GPS) के साथ काम करती है। Interactor UIKit को इम्पोर्ट नहीं करता। Presenter View और Interactor के बीच मध्यस्थ है: Interactor से डेटा प्राप्त करता है, प्रदर्शन के लिए फ़ॉर्मेट करता है, View को भेजता है। Presenter भी UIKit को इम्पोर्ट नहीं करता। Entity — डेटा मॉडल (struct, class)। Router — नेविगेशन प्रबंधित करता है: मॉड्यूल बनाता है, स्क्रीन खोलता है, मॉड्यूल के बीच डेटा भेजता है।

घटकजिम्मेदारीनिर्भरताएँ
Viewप्रदर्शन, एनिमेशन, जेस्चरUIKit (केवल View)
Interactorव्यावसायिक तर्क, नेटवर्क, DBEntity, सेवाएँ
Presenterडेटा फ़ॉर्मेटिंग, View कमांडViewProtocol, Interactor
Entityडेटा मॉडलकोई नहीं
Routerनेविगेशन, मॉड्यूल निर्माणUIViewController (संक्रमण के लिए)

घटकों के बीच संबंध प्रोटोकॉल द्वारा वर्णित हैं। ViewProtocol प्रदर्शन विधियों को परिभाषित करता है, InteractorProtocol व्यावसायिक तर्क विधियों को, PresenterProtocol घटना प्रबंधन विधियों को, RouterProtocol नेविगेशन विधियों को परिभाषित करता है। प्रत्येक घटक केवल प्रोटोकॉल के माध्यम से दूसरे से संचार करता है, जो कार्यान्वयन को आसानी से बदलने और पृथक परीक्षण की अनुमति देता है। औसतन, एक स्क्रीन के लिए VIPER मॉड्यूल में 5 प्रोटोकॉल + 5 क्लास + 1 Builder/Assembler = 11 फ़ाइलें प्रति स्क्रीन होती हैं।

Swift में VIPER: मॉड्यूल, Router और Presenter

VIPER मॉड्यूल का निर्माण Builder (या Assembler) में किया जाता है, जो सभी पाँच घटकों को बनाता है और उन्हें प्रोटोकॉल के माध्यम से जोड़ता है। Builder एकमात्र स्थान है जहाँ घटक एक-दूसरे के ठोस प्रकारों को जानते हैं। असेंबली के बाद, View प्रदर्शन के लिए बाहर लौटाया जाता है, शेष श्रृंखला साफ है और पृथक रूप से परीक्षण योग्य है।

swift
// प्रोटोकॉल — View
protocol UserViewProtocol: AnyObject {
    func display(name: String)
    func display(email: String)
    func showLoading()
    func hideLoading()
}

// प्रोटोकॉल — Interactor
protocol UserInteractorProtocol {
    func fetchUser(id: Int, completion: @escaping (Result<User, Error>) -> Void)
}

// प्रोटोकॉल — Router
protocol UserRouterProtocol {
    func navigateToProfile(userId: Int)
}

// Interactor — व्यावसायिक तर्क
final class UserInteractor: UserInteractorProtocol {
    private let service: UserService

    init(service: UserService) { self.service = service }

    func fetchUser(id: Int, completion: @escaping (Result<User, Error>) -> Void) {
        service.fetchUser(id: id, completion: completion)
    }
}

// Presenter — डेटा तैयारी
final class UserPresenter {
    private weak var view: UserViewProtocol?
    private let interactor: UserInteractorProtocol
    private let router: UserRouterProtocol

    init(interactor: UserInteractorProtocol, router: UserRouterProtocol) {
        self.interactor = interactor
        self.router = router
    }

    func setView(_ view: UserViewProtocol) {
        self.view = view
    }

    func viewDidLoad() {
        view?.showLoading()
        interactor.fetchUser(id: 42) { [weak self] result in
            guard let self else { return }
            self.view?.hideLoading()
            switch result {
            case .success(let user):
                self.view?.display(name: user.name)
                self.view?.display(email: user.email)
            case .failure(let error):
                // त्रुटि प्रबंधन
            }
        }
    }
}

// Router — नेविगेशन
final class UserRouter: UserRouterProtocol {
    private weak var viewController: UIViewController?

    func setViewController(_ vc: UIViewController) {
        viewController = vc
    }

    func navigateToProfile(userId: Int) {
        let profileModule = ProfileModuleBuilder.build(userId: userId)
        viewController?.navigationController?.pushViewController(profileModule, animated: true)
    }
}

// Builder — मॉड्यूल असेंबली
enum UserModuleBuilder {
    static func build(userId: Int) -> UIViewController {
        let service = UserService()
        let interactor = UserInteractor(service: service)
        let router = UserRouter()
        let presenter = UserPresenter(interactor: interactor, router: router)
        let viewController = UserViewController(presenter: presenter)
        presenter.setView(viewController)
        router.setViewController(viewController)
        return viewController
    }
}

Builder/Assembler VIPER का एक प्रमुख तत्व है, जो मैन्युअल रूप से डिपेंडेंसी इंजेक्शन लागू करता है। कंस्ट्रक्टर के माध्यम से डिपेंडेंसी इंजेक्शन (constructor injection) गारंटी देता है कि कोई घटक अपनी निर्भरताओं के बिना नहीं बनाया जा सकता। आधुनिक VIPER में, Builder Swinject (DI कंटेनर) का उपयोग कर सकता है, लेकिन मैन्युअल असेंबली परीक्षण के लिए अधिक पारदर्शी रहती है। IT Sectr में, हम जटिल तर्क वाले मॉड्यूल के लिए मैन्युअल असेंबली के साथ VIPER लागू करते हैं — यह नए डेवलपर्स के लिए कोड पढ़ना सरल बनाता है।

Mapper (Formatter) VIPER का एक वैकल्पिक छठा घटक है। Mapper Entity (DB/सर्वर मॉडल) को ViewModel (प्रदर्शन मॉडल) में बदलता है। Entity में फ़ील्ड id, first_name, last_name, email के साथ UserDTO होता है। ViewModel — name (first_name + last_name) और email के साथ UserDisplayItem। Mapper Presenter में निष्पादित होता है। यदि डेटा मैपिंग जटिल है (एकाधिक Entity → एक ViewModel), तो Mapper को परीक्षण के लिए एक अलग क्लास में निकाला जाता है।

VIPER मॉड्यूल के बीच संचार

VIPER मॉड्यूल पृथक हैं और एक-दूसरे के बारे में नहीं जानते। मॉड्यूल के बीच संचार Router के माध्यम से होता है। जब उपयोगकर्ता उपयोगकर्ता स्क्रीन पर "प्रोफ़ाइल" बटन पर क्लिक करता है, Presenter router.navigateToProfile(userId: 42) को कॉल करता है। Router ProfileModuleBuilder.build(userId: 42) के माध्यम से एक नया मॉड्यूल बनाता है और इसे navigationController.push के माध्यम से खोलता है। डेटा प्रवाह: मॉड्यूल A → Router A → मॉड्यूल B Builder → मॉड्यूल B बनाया और खोला जाता है।

डेटा वापस भेजना (उदाहरण के लिए, चयन स्क्रीन पर शहर चुनना → प्रोफ़ाइल संपादन स्क्रीन पर वापस लौटना) VIPER में डेलिगेट या क्लोज़र के माध्यम से कार्यान्वित किया जाता है। मॉड्यूल B didSelectCity(_ city: City) विधि के साथ ModuleBDelegate प्रोटोकॉल को परिभाषित करता है। मॉड्यूल A इस प्रोटोकॉल को लागू करता है। Router A डेलिगेट को मॉड्यूल B Builder को भेजता है। जब कोई शहर चुना जाता है, मॉड्यूल B delegate?.didSelectCity(city) को कॉल करता है। यह मानक iOS अभ्यास है, जो किसी भी UIKit डेवलपर से परिचित है।

परिदृश्यतंत्रउदाहरण
आगे नेविगेशनRouter → BuildernavigateToProfile(userId:)
डेटा वापस भेजनाDelegatedidSelectCity(_:)
सिस्टम सूचनाNotificationCenterUserDidLogout
Interactor से घटनाPresenter → ViewWebSocket संदेश

NotificationCenter का उपयोग सिस्टम ईवेंट (लॉगआउट, प्लान बदलना, पुश सूचनाएँ) के लिए किया जाता है जो एक साथ कई मॉड्यूल को प्रभावित करते हैं। Router या AppDelegate Notification की सदस्यता लेता है, आवश्यक मॉड्यूल बनाता है या स्थिति अपडेट करता है। VIPER NotificationCenter को प्रतिबंधित नहीं करता — महत्वपूर्ण यह है कि इसका उपयोग केवल 1-to-many ईवेंट के लिए किया जाए, जबकि 1-to-1 संचार के लिए डेलिगेट या क्लोज़र का उपयोग किया जाए।

VIPER की MVVM और Clean Architecture से तुलना

VIPER बनाम MVVM — VIPER को प्रति स्क्रीन 2–3 गुना अधिक कोड की आवश्यकता होती है लेकिन पूर्ण घटक पृथक्करण प्रदान करता है। MVVM ViewModel + SwiftUI के साथ सरल और तेज़ है लेकिन 5+ डेवलपर्स की टीमों के लिए कम स्केलेबल है। VIPER सख्ती से परिभाषित करता है कि कौन किसके लिए जिम्मेदार है: Interactor — केवल व्यावसायिक तर्क, Presenter — फ़ॉर्मेटिंग, Router — नेविगेशन। MVVM में, ViewModel अक्सर बढ़ता है, नेविगेशन और व्यावसायिक तर्क को अपने हाथ में ले लेता है।

VIPER बनाम Clean Architecture — VIPER iOS UIKit के लिए अनुकूलित Clean Architecture का एक विशिष्ट मामला है। Interactor = Use Case, Entity = Domain Model, Presenter = Presentation, Router = Controller रॉबर्ट मार्टिन के शब्दों में। Clean Architecture Interactor और डेटा के बीच एक Gateway/Repository परत जोड़ता है, जो आमतौर पर VIPER में अलग नहीं की जाती। आधुनिक SwiftUI प्रोजेक्ट्स के लिए, अधिकांश टीमें Clean Architecture (The Composable Architecture) या MVVM चुनती हैं, VIPER को UIKit लिगेसी के लिए छोड़ देती हैं।

VIPER कब चुनें — 5+ डेवलपर्स की टीमें, 50+ स्क्रीन वाले UIKit प्रोजेक्ट्स, 80% से ऊपर परीक्षण आवश्यकताएँ, केवल iOS (VIPER बिना पुनर्लेखन के Android पर पोर्टेबल नहीं है)। VIPER एक पूर्वानुमानित संरचना प्रदान करता है: एक नया डेवलपर 15 मिनट में एक मॉड्यूल समझ लेता है। हालांकि, अधिक फ़ाइलों के कारण विकास की गति MVVM की तुलना में 20–30% कम है। IT Sectr में, हम 3+ लोगों की टीमों के साथ एंटरप्राइज़ UIKit प्रोजेक्ट्स के लिए VIPER का उपयोग करते हैं और नए SwiftUI प्रोजेक्ट्स के लिए Clean Architecture पसंद करते हैं।

VIPER मॉड्यूल का परीक्षण

VIPER परीक्षण के लिए डिज़ाइन किया गया है — प्रत्येक घटक प्रोटोकॉल के माध्यम से पृथक रूप से परीक्षण किया जाता है। Interactor का परीक्षण मॉक सेवाओं के साथ किया जाता है: यह जाँच की जाती है कि fetchUser सही ID के साथ कॉल किया गया और परिणाम Presenter को भेजा गया। Presenter का परीक्षण मॉक View और Interactor ऑब्जेक्ट के साथ किया जाता है। Router का परीक्षण मॉक नेविगेशन के साथ किया जाता है: यह जाँच की जाती है कि navigateToProfile सही userId के साथ कॉल किया गया और सही मॉड्यूल बनाया गया। View का परीक्षण UI टेस्ट (XCUITest) से किया जाता है।

swift
import XCTest

final class UserPresenterTests: XCTestCase {
    func testViewDidLoad_callsFetchUserAndUpdatesView() {
        // Given
        let view = MockUserView()
        let interactor = MockUserInteractor()
        let router = MockUserRouter()
        let presenter = UserPresenter(interactor: interactor, router: router)
        presenter.setView(view)
        let expectedUser = User(id: 42, name: "John", email: "john@test.com")
        interactor.result = .success(expectedUser)

        // When
        presenter.viewDidLoad()

        // Then
        XCTAssertEqual(interactor.capturedUserId, 42)
        XCTAssertEqual(view.displayedName, "John")
        XCTAssertTrue(view.didShowLoading)
    }
}

मॉक ऑब्जेक्ट VIPER के लिए मैन्युअल रूप से बनाए जाते हैं (संग्रहीत कैप्चर गुणों वाली क्लास) या Cuckoo / Mockingbird जैसी लाइब्रेरी के माध्यम से। मैन्युअल मॉक क्लास सरल और स्पष्ट होते हैं, विशेष रूप से नए डेवलपर्स को प्रशिक्षित करने के लिए। प्रत्येक मॉक कैप्चर किए गए मान (capturedUserId, displayedName) और कॉल फ़्लैग (didShowLoading) संग्रहीत करता है। परीक्षण के अंत में, न केवल यह जाँच की जाती है कि विधि को कॉल किया गया था, बल्कि यह भी कि किन पैरामीटर के साथ — यह डेटा प्रवाह की शुद्धता में विश्वास दिलाता है।

कोड कवरेज IT Sectr VIPER प्रोजेक्ट्स में Interactor के लिए 85–95%, Presenter के लिए 90–95%, Router के लिए 70–80%, View के लिए 30–50% (UI टेस्ट के माध्यम से) तक पहुँचता है। View का परीक्षण स्नैपशॉट टेस्ट (SnapshotTesting, 1.5K स्टार) से किया जाता है — यह XCUITest से तेज़ है और अधिक मामलों को कवर करता है। VIPER प्रोजेक्ट का कुल कवरेज आमतौर पर 70–80% होता है, जो MVVM प्रोजेक्ट (50–65%) से अधिक है, लेकिन टेस्ट लिखने में अधिक समय लगता है (विकास समय का 30–40% बनाम MVVM में 20–25%)।

अक्सर पूछे जाने वाले प्रश्न

एक VIPER मॉड्यूल में कितनी फ़ाइलें होती हैं?

न्यूनतम 11 फ़ाइलें: 5 प्रोटोकॉल (ViewProtocol, InteractorProtocol, PresenterProtocol, RouterProtocol, Entity), 5 कार्यान्वयन (ViewController, Interactor, Presenter, Router, Entity) और Builder/Assembler। Mapper (Formatter) के साथ — 12–13। 50 स्क्रीन वाले प्रोजेक्ट के लिए, केवल VIPER मॉड्यूल की 550–650 फ़ाइलें होती हैं। MVVM को प्रति स्क्रीन 3 फ़ाइलों की आवश्यकता होती है (ViewModel, View, Model) — 50 स्क्रीन के लिए 150 फ़ाइलें।

क्या VIPER Android पर उपयोग किया जा सकता है?

हाँ, सैद्धांतिक रूप से VIPER Android पर पोर्टेबल है, लेकिन व्यवहार में इसका उपयोग नहीं किया जाता — Google Jetpack के साथ MVVM की सिफारिश करता है। VIPER iOS UIKit के लिए बनाया गया था, जहाँ ViewController अपने जीवनचक्र के कारण परीक्षण करना कठिन है। Android पर, Jetpack ViewModel VIPER पृथक्करण के बिना परीक्षण समस्या को हल करता है। Android पर VIPER का समकक्ष मॉड्यूल/फ़ीचर विभाजन के साथ Clean Architecture है।

VIPER और Clean Architecture में क्या अंतर है?

VIPER Clean Architecture का iOS-विशिष्ट कार्यान्वयन है। Interactor Use Case से मेल खाता है, Entity — Domain Model, Presenter — Presentation परत। Clean Architecture Interactor और डेटा के बीच Repository/Gateway जोड़ता है, जो VIPER में आमतौर पर Interactor के अंदर कार्यान्वित किए जाते हैं। Clean Architecture Router को निर्धारित नहीं करता — नेविगेशन कार्यान्वयन पर छोड़ दिया जाता है।

क्या SwiftUI प्रोजेक्ट्स के लिए VIPER आवश्यक है?

नहीं — SwiftUI MVVM + Combine के लिए डिज़ाइन किया गया है। SwiftUI में VIPER अनावश्यक है: घोषणात्मक UI के साथ प्रति स्क्रीन पाँच घटक लाभ के बिना ओवरहेड है। SwiftUI के लिए, MVVM या TCA (The Composable Architecture) चुनें। VIPER UIKit लिगेसी और उन प्रोजेक्ट्स के लिए प्रासंगिक बना हुआ है जहाँ iOS 12 और उससे नीचे न्यूनतम संस्करण है।

VIPER मॉड्यूल के बीच डेटा कैसे भेजें?

Router के माध्यम से। मॉड्यूल A router.navigateToProfile(userId: id) कॉल करता है। Router A Builder के माध्यम से मॉड्यूल B बनाता है, userId भेजता है। वापसी संचार — डेलिगेट के माध्यम से: मॉड्यूल B ModuleBDelegate प्रोटोकॉल को परिभाषित करता है, मॉड्यूल A इसे लागू करता है और Router के माध्यम से भेजता है। सिस्टम ईवेंट (लॉगआउट) — NotificationCenter के माध्यम से।

सारांश

  • VIPER — सख्त पृथक्करण के साथ पाँच घटक: View, Interactor, Presenter, Entity, Router
  • मॉड्यूलरिटी — प्रत्येक स्क्रीन पृथक है, Builder कंस्ट्रक्टर इंजेक्शन के माध्यम से निर्भरताएँ जोड़ता है
  • Router — नेविगेशन को Presenter से बाहर ले जाता है, iOS पर नेविगेशन समस्या का समाधान
  • Interactor — UIKit के बिना साफ व्यावसायिक तर्क, यूनिट टेस्ट से परीक्षण योग्य
  • कोड की मात्रा — प्रति स्क्रीन 11+ फ़ाइलें, विकास MVVM से 20–30% धीमा
  • परीक्षण — 70–80% कवरेज, Interactor और Presenter मॉक ऑब्जेक्ट के माध्यम से परीक्षण योग्य
  • SwiftUI बनाम UIKit — UIKit (लिगेसी) के लिए VIPER, SwiftUI के लिए MVVM/TCA

हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे

IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।

परियोजना पर चर्चा करें

यह भी पढ़ें