ios:设计模式

========================================
MVVM (mode viewMode view mode)
========================================
MVC (C 管家)
////////////////////////C层
#import "LoginController.h"
#import "LoginContainerView.h"
#import "LoginModel.h"
#import "UIAlertView+show.h"
@interface LoginController ()

@end

@implementation LoginController
- (void)viewDidLoad {
    [super viewDidLoad];
    [self initView];
}

#pragma mark InitView
- (void)initView
{
    LoginContainerView *container = [[LoginContainerView alloc]initWithFrame:self.view.bounds];
    [self.view addSubview:container];
    __weak typeof(self) ws = self;
    container.loginHandler = ^(NSString *account,NSString *pwd){
        [ws loginWithAccount:account pwd:pwd];
    };
}

#pragma mark Event Handle
- (void)loginWithAccount:(NSString *)account pwd:(NSString *)pwd
{
    [[LoginModel shareInstance] loginWithAccount:account password:pwd success:^{
        [UIAlertView showAlertWithTitle:@"登录成功"];
    } failure:^{
        [UIAlertView showAlertWithTitle:@"登录失败"];
    }];
}

@end

///////////////////////////////V层
#import "LoginContainerView.h"
@interface LoginContainerView()
@property (nonatomic,strong) UITextField *accountTextField;
@property (nonatomic,strong) UITextField *pwdTextField;
@property (nonatomic,weak) id delegate;

@end
@implementation LoginContainerView
#pragma mark LifeCycle
- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self initUI];
    }
    return self;
}
#pragma mark InitUI
- (void)initUI
{
    self.backgroundColor = [UIColor whiteColor];
    self.accountTextField = [[UITextField alloc]initWithFrame:CGRectMake(0, 0, 200, 44)];
    self.accountTextField.center = CGPointMake(self.center.x, 100);
    self.accountTextField.borderStyle = UITextBorderStyleRoundedRect;
    self.accountTextField.placeholder = @"请输入用户名";
   
    self.pwdTextField = [[UITextField alloc]initWithFrame:CGRectMake(0, 0, 200, 44)];
    self.pwdTextField.center = CGPointMake(self.center.x, 160);
    self.pwdTextField.secureTextEntry = YES;
    self.pwdTextField.borderStyle = UITextBorderStyleRoundedRect;
    self.pwdTextField.placeholder = @"请输入密码";
   
    [self addSubview:self.accountTextField];
    [self addSubview:self.pwdTextField];
   
    UIButton *loginBtn = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 100, 60)];
    loginBtn.center = CGPointMake(self.center.x, 220);
    [loginBtn setTitle:@"登录" forState:UIControlStateNormal];
    [loginBtn setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
    [loginBtn addTarget:self action:@selector(login) forControlEvents:UIControlEventTouchUpInside];
    [self addSubview:loginBtn];
}

#pragma mark Event Handle
- (void)login
{
    [self endEditing:YES];
    if (!self.accountTextField.hasText || !self.pwdTextField.hasText) {
        UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"账号或密码不能为空" message:nil delegate:nil cancelButtonTitle:@"确定" otherButtonTitles: nil];
        [alert show];
        return;
    }
    if (self.loginHandler) {
        self.loginHandler(self.accountTextField.text,self.pwdTextField.text);
    }
}
@end

//////////////////////////M层
#import "LoginModel.h"
@interface LoginModel()

@end
@implementation LoginModel
+ (instancetype)shareInstance
{
    static LoginModel *_instance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [[self alloc]init];
    });
    return _instance;
}

- (void)loginWithAccount:(NSString *)account password:(NSString *)pwd success:(void (^)())loginSuccess failure:(void (^)())loginFailed;
{
    if ([account isEqualToString:@"test"]&&[pwd isEqualToString:@"123456"]) {
        loginSuccess();
    }else{
        loginFailed();
    }
}

@end

========================================
MVP (P 秘书)
1、View 层比较简单明,就是 View 的一些封装、重用。在一款精心设计过的 App 里面,应该有很多 View 是可以封装重用的。比如一些自己的 TableViewCell,自己设计的 Button,一些 View(包含一些子 View,UI 精心设计过,在项目里多处出现的)等等。

2、Model 层应该不仅仅是创建一个数据对象,还应该包含网络请求,以及数据 SQLite 的 CRUD 操作(比如 iOS 平台,一般以 FMDB 框架直接操作 sql,或者用 CoreData) 。一般可以将数据对象是否需要缓存设计成一个字段 isCache,或者针对整个项目设计一个开存储关,决定整个项目是否需要数据缓存。我们常见的新闻类 App,在离线的时候看到的数据,都是做了缓存处理的。比如一些金融类的 App,实时性比较高,是不做缓存的。

3、Presenter 层并不涉及数据对象的网络请求和 SQLite 操作,只是 Model 层和 View 层的一个桥梁。Presenter 层就不至于太臃肿,容易看懂。
/////////Controller
#import "LoginViewController.h"
#import "UIAlertView+show.h"
#import "LoginPresenter.h"
@interface LoginViewController ()
@property (nonatomic,strong) UITextField *accountTextField;
@property (nonatomic,strong) UITextField *pwdTextField;
@property (nonatomic,strong) LoginPresenter *presenter;

@end

@implementation LoginViewController
- (instancetype)initWithPresenter:(LoginPresenter *)presenter
{
    if (self = [super init]) {
        self.presenter = presenter;
    }
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    [self initUI];
}

#pragma mark InitUI
- (void)initUI
{
    self.view.backgroundColor = [UIColor whiteColor];
    self.accountTextField = [[UITextField alloc]initWithFrame:CGRectMake(0, 0, 200, 44)];
    self.accountTextField.center = CGPointMake(self.view.center.x, 100);
    self.accountTextField.borderStyle = UITextBorderStyleRoundedRect;
    self.accountTextField.placeholder = @"请输入用户名";
   
    self.pwdTextField = [[UITextField alloc]initWithFrame:CGRectMake(0, 0, 200, 44)];
    self.pwdTextField.center = CGPointMake(self.view.center.x, 160);
    self.pwdTextField.secureTextEntry = YES;
    self.pwdTextField.borderStyle = UITextBorderStyleRoundedRect;
    self.pwdTextField.placeholder = @"请输入密码";
   
    [self.view addSubview:self.accountTextField];
    [self.view addSubview:self.pwdTextField];
   
    UIButton *loginBtn = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 100, 60)];
    loginBtn.center = CGPointMake(self.view.center.x, 220);
    [loginBtn setTitle:@"登录" forState:UIControlStateNormal];
    [loginBtn setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
    [loginBtn addTarget:self action:@selector(login) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:loginBtn];
}

#pragma mark Event Handle
- (void)login
{
    [self.view endEditing:YES];
    if (!self.accountTextField.hasText || !self.pwdTextField.hasText) {
        [UIAlertView showAlertWithTitle:@"账号或密码不能为空"];
        return;
    }
    [self.presenter loginWithAccount:self.accountTextField.text password:self.pwdTextField.text success:^{
        [UIAlertView showAlertWithTitle:@"登录成功"];
    } failure:^{
        [UIAlertView showAlertWithTitle:@"登录失败"];

    }];
}


@end

////////P层
#import "LoginPresenter.h"
#import "LoginModel.h"
@implementation LoginPresenter
- (void)loginWithAccount:(NSString *)account password:(NSString *)pwd success:(void (^)())loginSuccess failure:(void (^)())loginFailed
{
    [[LoginModel shareInstance] loginWithAccount:account password:pwd success:^{
        loginSuccess();
    } failure:^{
        loginFailed();
    }];
}
@end

/////////M层
#import "LoginModel.h"
@interface LoginModel()

@end
@implementation LoginModel
+ (instancetype)shareInstance
{
    static LoginModel *_instance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [[self alloc]init];
    });
    return _instance;
}

- (void)loginWithAccount:(NSString *)account password:(NSString *)pwd success:(void (^)())loginSuccess failure:(void (^)())loginFailed;
{
    if ([account isEqualToString:@"test"]&&[pwd isEqualToString:@"123456"]) {
        loginSuccess();
    }else{
        loginFailed();
    }
}


@end

猜你喜欢

转载自samson870830.iteye.com/blog/2352269