MVC与MVVM设计模式理解

MVC与MVVM设计模式理解

MVC设计模式

MVC是一种架构模式,M表示Model,V表示视图View,C表示控制器Controller:

  • Model负责存储、定义、操作数据;
  • View用来展示给用户,并且和用户进行交互;
  • Controller是Model和View的协调者,Controller把Model中的数据拿过来给View使用。Controller可以直接与Model和View进行通信,而View不能与Controller直接通信。,当有数据更新时,Model也要与Controller进行通信,这个时候就要用Notification和KVO,这个方式就像发广播一样,Model发信号,Controller设置接收监听信号,当有数据更新是就发信号给Controller,Model和View不能直接通信,这样违背MVC设计原则。View与Controller通信需要利用代理协议的方式,Controller可以直接根据Model决定View的展示。View如果接受响应事件则通过delegate,target-action,block等方式告诉Controller的状态变化。Controller进行业务的处理,然后再控制View的展示。

那这样Model和View就是相互独立的。View只负责页面的展示,Model只是数据的存储,那么也就达到了解耦和重用的目的。
实例:假设苹果根据买iPhone的人给予不同的优惠,学生优惠20%,it民工优惠50%,其他不优惠。

//客户类

typedef NS_ENUM(NSInteger, CustomerType) {
    CustomerTypeStudent,
    CustomerTypeiT,
    CustomerTypeOther,
};

@interface Customer : NSObject

@property (nonatomic, assign) CustomerType customerType;

@end

//iPhone类

@interface iPhone : NSObject

@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *price;

@end

//VC类

@interface ViewController ()

@property (nonatomic, strong) iPhone *iphone;
@property (nonatomic, strong) Customer *customer;

@property (weak, nonatomic) IBOutlet UILabel *lblName;
@property (weak, nonatomic) IBOutlet UILabel *lblPrice;
@property (weak, nonatomic) IBOutlet UILabel *lblDiscount;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.title = @"手机优惠";

    self.lblName.text = self.iphone.name;
    self.lblPrice.text = self.iphone.price;

    if (self.customer.customerType == CustomerTypeStudent) {
        self.lblDiscount.text = @"优惠20%";
    }
    else if (self.customer.customerType == CustomerTypeiT) {
        self.lblDiscount.text = @"优惠50%";
    }
    else {
        self.lblDiscount.text = @"没有优惠";
    }
}

@end

MVVM设计模式

MVVM就是帮忙分担一下controller里面的部分业务逻辑。
这里写图片描述
这个时候,controller将不再直接和真实的model进行绑定了,而通过ViewModel,viewModel进而持有真实的Model。
实例:

//新建一个viewModel
//.h文件

@interface viewModel : NSObject

@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *price;
@property (nonatomic, strong) NSString *discount;

- (id)initWithCustomer:(Customer *)customer iphone:(iPhone *)iphone;

@end

//.m文件

@interface viewModel ()

@property (nonatomic, strong) iPhone *iphone;
@property (nonatomic, strong) Customer *customer;

@end

@implementation viewModel

- (id)initWithCustomer:(Customer *)customer iphone:(iPhone *)iphone
{
    if (self = [super init]) {
        _customer = customer;
        _iphone = iphone;
        [self bindData];
    }
    return self;
}

- (void)bindData
{
    self.name = _iphone.name;
    self.price = _iphone.price;

    if (self.customer.customerType == CustomerTypeStudent) {
        self.discount = @"优惠20%";
    }
    else if (self.customer.customerType == CustomerTypeiT) {
        self.discount = @"优惠50%";
    }
    else {
        self.discount = @"没有优惠";
    }
}

@end

//VC

@interface ViewController ()

@property (nonatomic, strong) viewModel *viewModel;

@property (weak, nonatomic) IBOutlet UILabel *lblName;
@property (weak, nonatomic) IBOutlet UILabel *lblPrice;
@property (weak, nonatomic) IBOutlet UILabel *lblDiscount;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    self.title = @"手机优惠";

    self.lblName.text = self.viewModel.name;
    self.lblPrice.text = self.viewModel.price;
    self.lblDiscount.text = self.viewModel.discount;

}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

看到修改完的代码,你会发现VC里面已经省去了不少的代码。一切都和viewModel进行交流。这里我只是展示一个最简单的数据展示,如果有其他响应事件,是需要viewModel开放方法来进行处理的,并要通知VC处理结果的。

关于MVVM的优点:

  • 方便测试

在MVC下,Controller基本是无法测试的,里面混杂了个各种逻辑,而且分散在不同的地方。有了MVVM我们就可以测试里面的viewModel,来验证我们的处理结果对不对(Xcode7的测试已经越来越完善了)。

  • 便于代码的移植

比如iOS里面有iPhone版本和iPad版本,除了交互展示不一样外,业务逻辑的model是一致的。这样,我们就可以以很小的代价去开发另一个app。

  • 兼容MVC

MVVM是MVC的一个升级版,目前的MVC也可以很快的转换到MVVM这个模式。VC可以省去一大部分展示逻辑。

缺点:

  • 类会增多

每个VC都附带一个viewModel,类的数量*2

  • viewModel会越来越庞大

我们把逻辑给了viewModel,那势必Model也会变得很复杂,里面的属性和方法越来越多。可能重写的方法比较多,因为涉及到一些数据的转换以及和controller之间的通信。

  • 调用复杂度增加

由于数据都是从viewModel来,想想突然来了一个新人,一看代码,不知道真实的模型是谁。比如常用tableview的数据源,一般都是一个数组,如果不断的通过viewModel去取,沟通上没有那么直接。况且每封一层,意味着要写很多代码去融合他们的转换。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值