MST

星途 面试题库

面试题:Objective-C中VIPER模式的基础组件理解

请简述在Objective-C的VIPER模式中,View、Interactor、Presenter、Entity和Router分别承担什么职责,并举例说明它们之间是如何协作的。
13.3万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试

1. 各组件职责

  • View
    • 职责:负责展示用户界面,处理用户交互事件,并将这些事件传递给Presenter。它只关注界面的呈现,不涉及业务逻辑。例如,在一个登录界面中,View负责显示用户名和密码输入框、登录按钮等UI元素,并将用户点击登录按钮的事件传递给Presenter。
    • 代码示例:在Objective - C中,可能是一个继承自UIViewController的类,如LoginViewController,其中IBAction方法处理按钮点击事件并调用Presenter的方法。
@interface LoginViewController : UIViewController
@property (weak, nonatomic) IBOutlet UITextField *usernameTextField;
@property (weak, nonatomic) IBOutlet UITextField *passwordTextField;
- (IBAction)loginButtonTapped:(id)sender;
@end

@implementation LoginViewController
- (IBAction)loginButtonTapped:(id)sender {
    NSString *username = self.usernameTextField.text;
    NSString *password = self.passwordTextField.text;
    [self.presenter attemptLoginWithUsername:username password:password];
}
@end
  • Interactor
    • 职责:负责处理具体的业务逻辑,它从Presenter接收请求,与数据层(如数据库、网络服务)交互获取或修改数据,并将结果返回给Presenter。例如,在登录功能中,Interactor负责与服务器进行网络通信,验证用户名和密码。
    • 代码示例:可以是一个独立的类,如LoginInteractor
@interface LoginInteractor : NSObject
@property (nonatomic, weak) id<LoginInteractorOutput> output;
- (void)attemptLoginWithUsername:(NSString *)username password:(NSString *)password;
@end

@implementation LoginInteractor
- (void)attemptLoginWithUsername:(NSString *)username password:(NSString *)password {
    // 模拟网络请求验证
    BOOL success = [self validateCredentialsWithUsername:username password:password];
    if (success) {
        [self.output loginSucceeded];
    } else {
        [self.output loginFailed];
    }
}
- (BOOL)validateCredentialsWithUsername:(NSString *)username password:(NSString *)password {
    // 实际逻辑连接服务器验证,这里简单模拟
    return [username isEqualToString:@"test"] && [password isEqualToString:@"test"];
}
@end
  • Presenter
    • 职责:作为View和Interactor之间的桥梁,它接收View传递的用户事件,调用Interactor的方法来处理业务逻辑,然后根据Interactor返回的结果更新View。例如,在登录场景中,Presenter接收View传递的登录请求,调用Interactor的登录方法,根据登录结果通知View显示相应的提示信息。
    • 代码示例:如LoginPresenter类。
@interface LoginPresenter : NSObject <LoginInteractorOutput>
@property (nonatomic, weak) id<LoginViewInterface> view;
@property (nonatomic, strong) LoginInteractor *interactor;
- (void)attemptLoginWithUsername:(NSString *)username password:(NSString *)password;
@end

@implementation LoginPresenter
- (void)attemptLoginWithUsername:(NSString *)username password:(NSString *)password {
    [self.interactor attemptLoginWithUsername:username password:password];
}
- (void)loginSucceeded {
    [self.view showLoginSuccessMessage];
}
- (void)loginFailed {
    [self.view showLoginErrorMessage];
}
@end
  • Entity
    • 职责:代表应用程序中的数据模型,用于存储和传输数据。例如,在用户登录场景中,可能有一个User实体类,用于存储用户的相关信息,如用户名、密码、用户ID等。
    • 代码示例
@interface User : NSObject
@property (nonatomic, strong) NSString *username;
@property (nonatomic, strong) NSString *password;
@property (nonatomic, assign) NSInteger userId;
@end

@implementation User
@end
  • Router
    • 职责:负责处理视图之间的导航和路由逻辑,它知道如何创建和切换不同的视图控制器。例如,在登录成功后,Router负责将用户导航到主应用界面。
    • 代码示例:如LoginRouter类。
@interface LoginRouter : NSObject
+ (instancetype)routerWithViewController:(UIViewController *)viewController;
- (void)navigateToMainScreen;
@end

@implementation LoginRouter
+ (instancetype)routerWithViewController:(UIViewController *)viewController {
    LoginRouter *router = [[LoginRouter alloc] init];
    router.viewController = viewController;
    return router;
}
- (void)navigateToMainScreen {
    MainViewController *mainVC = [[MainViewController alloc] init];
    [self.viewController.navigationController pushViewController:mainVC animated:YES];
}
@end

2. 协作流程举例

  1. 用户交互:用户在登录界面(View)点击登录按钮,View将用户名和密码信息传递给Presenter的attemptLoginWithUsername:password:方法。
  2. Presenter调用Interactor:Presenter接收到请求后,调用Interactor的attemptLoginWithUsername:password:方法,将用户名和密码传递给Interactor进行业务逻辑处理。
  3. Interactor处理业务逻辑:Interactor与数据层交互(这里简单模拟验证),验证用户名和密码是否正确。如果验证成功,调用Presenter实现的loginSucceeded方法;如果失败,调用loginFailed方法。
  4. Presenter更新View:Presenter根据Interactor的返回结果,调用View的相应方法,如showLoginSuccessMessageshowLoginErrorMessage,更新界面显示。
  5. Router进行导航:如果登录成功,Presenter可以通知Router,Router执行navigateToMainScreen方法,将用户导航到主应用界面。