设计模式

iOS:常见架构

2020-08-14  本文已影响0人  春暖花已开

常见的架构有 MVCMVPMVVM。下面分别用代码做下演示。

MVC
#import "ViewController.h"

#pragma mark - Model
@interface MZPerson : NSObject

@property (copy, nonatomic) NSString *name;
@property (copy, nonatomic) NSString *image;

@end

@implementation MZPerson
@end


#pragma mark - View

@class MZView;
@protocol MZClickDelegate <NSObject>
@optional
- (void)viewDidClicked:(MZView *)view;

@end

@interface MZView : UIView

@property (nonatomic, strong) MZPerson *model;
@property (nonatomic, weak) id<MZClickDelegate> delegate;

@end

@interface MZView ()

//特点: 将View内部的细节封装起来了,外界不知道View内部的具体实现
@property (nonatomic, strong) UIImageView *iconView;
@property (nonatomic, strong) UILabel *nameLabel;

@end

@implementation MZView

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        UIImageView *iconView = [[UIImageView alloc] init];
        iconView.frame = CGRectMake(0, 0, 100, 100);
        [self addSubview:iconView];
        _iconView = iconView;
        
        UILabel *nameLabel = [[UILabel alloc] init];
        nameLabel.frame = CGRectMake(0, 100, 100, 30);
        nameLabel.textAlignment = NSTextAlignmentCenter;
        [self addSubview:nameLabel];
        _nameLabel = nameLabel;
    }
    return self;
}

- (void)setModel:(MZPerson *)model {
    _model = model;
    
    self.iconView.image = [UIImage imageNamed:model.image];
    self.nameLabel.text = model.name;
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    if ([self.delegate respondsToSelector:@selector(viewDidClicked:)]) {
        [self.delegate viewDidClicked:self];
    }
}

@end

#pragma mark - Controller

@interface ViewController ()<MZClickDelegate>
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //view
    MZView *view = [[MZView alloc] initWithFrame:CGRectMake(100, 100, 100, 150)];
    view.delegate = self;
    [self.view addSubview:view];
    
    //model
    MZPerson *model = [[MZPerson alloc] init];
    model.name = @"路飞";
    model.image = @"lufei";
    
    //设置数据到view上
    view.model = model;
}

//代理方法
- (void)viewDidClicked:(MZView *)view {
    NSLog(@"控制器接收到view的点击");
}

@end

MVP

MVP与MVC的区别在于:MVP将MVC中控制器的逻辑抽离出来放到presenter里(每一个大的逻辑都可以抽成一个presenter)。

#import "ViewController.h"

#pragma mark - Model
@interface MZPerson : NSObject

@property (copy, nonatomic) NSString *name;
@property (copy, nonatomic) NSString *image;

@end

@implementation MZPerson
@end


#pragma mark - View

@class MZView;
@protocol MZClickDelegate <NSObject>
@optional
- (void)viewDidClicked:(MZView *)view;

@end

@interface MZView : UIView

@property (nonatomic, strong) MZPerson *model;
@property (nonatomic, weak) id<MZClickDelegate> delegate;

@end

@interface MZView ()

//特点: 将View内部的细节封装起来了,外界不知道View内部的具体实现
@property (nonatomic, strong) UIImageView *iconView;
@property (nonatomic, strong) UILabel *nameLabel;

@end

@implementation MZView

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        UIImageView *iconView = [[UIImageView alloc] init];
        iconView.frame = CGRectMake(0, 0, 100, 100);
        [self addSubview:iconView];
        _iconView = iconView;
        
        UILabel *nameLabel = [[UILabel alloc] init];
        nameLabel.frame = CGRectMake(0, 100, 100, 30);
        nameLabel.textAlignment = NSTextAlignmentCenter;
        [self addSubview:nameLabel];
        _nameLabel = nameLabel;
    }
    return self;
}

- (void)setModel:(MZPerson *)model {
    _model = model;
    
    self.iconView.image = [UIImage imageNamed:model.image];
    self.nameLabel.text = model.name;
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    if ([self.delegate respondsToSelector:@selector(viewDidClicked:)]) {
        [self.delegate viewDidClicked:self];
    }
}

@end


#pragma mark - Presenter

@interface MZPresenter : NSObject<MZClickDelegate>

- (instancetype)initWithController:(UIViewController *)viewController;

@end

@implementation MZPresenter

- (instancetype)initWithController:(UIViewController *)viewController {
    if (self = [super init]) {
        
        //view
        MZView *view = [[MZView alloc] initWithFrame:CGRectMake(100, 100, 100, 150)];
        view.delegate = self;
        [viewController.view addSubview:view];
        
        //model
        MZPerson *model = [[MZPerson alloc] init];
        model.name = @"路飞";
        model.image = @"lufei";
        
        //设置数据到view上
        view.model = model;
    }
    return self;
}

//代理方法
- (void)viewDidClicked:(MZView *)view {
    NSLog(@"控制器接收到view的点击");
}

@end


#pragma mark - Controller

@interface ViewController ()

@property (strong, nonatomic) MZPresenter *presenter;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.presenter = [[MZPresenter alloc] initWithController:self];
}

@end

MVVM
#import "ViewController.h"
#import "NSObject+FBKVOController.h"

#pragma mark - Model
@interface MZPerson : NSObject

@property (copy, nonatomic) NSString *name;
@property (copy, nonatomic) NSString *image;

@end

@implementation MZPerson
@end


#pragma mark - View

@class MZView, MZViewModel;
@protocol MZClickDelegate <NSObject>
@optional
- (void)viewDidClicked:(MZView *)view;

@end

@interface MZView : UIView

@property (nonatomic, strong) MZViewModel *viewModel;
@property (nonatomic, weak) id<MZClickDelegate> delegate;

@end

@interface MZView ()

//特点: 将View内部的细节封装起来了,外界不知道View内部的具体实现
@property (nonatomic, strong) UIImageView *iconView;
@property (nonatomic, strong) UILabel *nameLabel;

@end

@implementation MZView

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        UIImageView *iconView = [[UIImageView alloc] init];
        iconView.frame = CGRectMake(0, 0, 100, 100);
        [self addSubview:iconView];
        _iconView = iconView;
        
        UILabel *nameLabel = [[UILabel alloc] init];
        nameLabel.frame = CGRectMake(0, 100, 100, 30);
        nameLabel.textAlignment = NSTextAlignmentCenter;
        [self addSubview:nameLabel];
        _nameLabel = nameLabel;
    }
    return self;
}

- (void)setViewModel:(MZViewModel *)viewModel {
    _viewModel = viewModel;
    
    __weak typeof(self) waekSelf = self;
    [self.KVOController observe:viewModel keyPath:@"name" options:NSKeyValueObservingOptionNew block:^(id  _Nullable observer, id  _Nonnull object, NSDictionary<NSKeyValueChangeKey,id> * _Nonnull change) {
        waekSelf.nameLabel.text = change[NSKeyValueChangeNewKey];
    }];
    
    [self.KVOController observe:viewModel keyPath:@"image" options:NSKeyValueObservingOptionNew block:^(id  _Nullable observer, id  _Nonnull object, NSDictionary<NSKeyValueChangeKey,id> * _Nonnull change) {
        waekSelf.iconView.image = [UIImage imageNamed:change[NSKeyValueChangeNewKey]];
    }];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    if ([self.delegate respondsToSelector:@selector(viewDidClicked:)]) {
        [self.delegate viewDidClicked:self];
    }
}

@end


#pragma mark - Presenter

@interface MZViewModel : NSObject

- (instancetype)initWithController:(UIViewController *)viewController;

@end

@interface MZViewModel ()<MZClickDelegate>

@property (weak, nonatomic) UIViewController *controller;
@property (copy, nonatomic) NSString *name;
@property (copy, nonatomic) NSString *image;

@end

@implementation MZViewModel

- (instancetype)initWithController:(UIViewController *)viewController {
    if (self = [super init]) {
        
        self.controller = viewController;
        
        //view
        MZView *view = [[MZView alloc] initWithFrame:CGRectMake(100, 100, 100, 150)];
        view.delegate = self;
        view.viewModel = self;
        [viewController.view addSubview:view];
        
        //model
        MZPerson *model = [[MZPerson alloc] init];
        model.name = @"路飞";
        model.image = @"lufei";
        
        // 设置数据
        self.name = model.name;
        self.image = model.image;
    }
    return self;
}

//代理方法
- (void)viewDidClicked:(MZView *)view {
    NSLog(@"控制器接收到view的点击");
}

@end


#pragma mark - Controller

@interface ViewController ()

@property (strong, nonatomic) MZViewModel *viewModel;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.viewModel = [[MZViewModel alloc] initWithController:self];
}

@end
上一篇 下一篇

猜你喜欢

热点阅读