见兔而顾犬,未为晚也;亡羊而补牢,未为迟也。------《战国策·楚策》
最近一直在面试,可以说是一天一个心情,面试的过程中也发现了自己的诸多不足以及自以为是的技术错误,今天就好好写下文章总结下,为自己敲响警钟,也希望能帮到读者。
APP的主要涉及模式框架虽说就以下三种,但是我们未必真正意义上的理解这些框架的精髓,自己在和面试官交流的过程中发现自己确实是理解有偏差的,从而导致面试时有些许尴尬。哎,谁叫自己学艺不精,现在亡羊补牢吧。
一、MVC
MVC(model-view-controller),用户操作> View (负责接受用户的输入操作)>Controller(业务逻辑处理)>Model(数据持久化)>View(将结果通过View反馈给用户)。
M - Model :数据保存
V - View : 用户界面
C - Controller : 业务逻辑
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的展示。
//客户类
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是将“数据模型数据双向绑定”的思想作为核心,因此在View和Model之间没有联系,通过ViewModel进行交互,而且Model和ViewModel之间的交互是双向的。因此视图的数据的变化会同时修改数据源,而数据源数据的变化也会立即反应到View上。
- MVVM的优点
低耦合。视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的"View"上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
可重用性。你可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑。
独立开发。开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计。
可测试。界面素来是比较难于测试的,而现在测试可以针对ViewModel来写。
-
MVVM的缺点
1、类会增多
每个VC都附带一个viewModel,类的数量*22、viewModel会越来越庞大
我们把逻辑给了viewModel,那势必Model也会变得很复杂,里面的属性和方法越来越多。可能重写的方法比较多,因为涉及到一些数据的转换以及和controller之间的通信。3、调用复杂度增加
由于数据都是从viewModel来,想想突然来了一个新人,一看代码,不知道真实的模型是谁。比如常用tableview的数据源,一般都是一个数组,如果不断的通过viewModel去取,沟通上没有那么直接。况且每封一层,意味着要写很多代码去融合他们的转换。
不废话了,直接上代码,方便大家理解,我们用代码项目为例来进行分析:
//新建一个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
三、MVP
MVP是把MVC中的Controller换成了Presenter(呈现),目的就是为了完全切断View跟Model之间的联系,由Presenter充当桥梁,做到View-Model之间通信的完全隔离。这个目前买没有项目以及实例,所以就不贴代码了,我们提供示意图作为参考。
参考资料1
参考资料2