iOS的设计模式分析

2018-06-27  本文已影响33人  woniu
见兔而顾犬,未为晚也;亡羊而补牢,未为迟也。------《战国策·楚策》

最近一直在面试,可以说是一天一个心情,面试的过程中也发现了自己的诸多不足以及自以为是的技术错误,今天就好好写下文章总结下,为自己敲响警钟,也希望能帮到读者。

APP的主要涉及模式框架虽说就以下三种,但是我们未必真正意义上的理解这些框架的精髓,自己在和面试官交流的过程中发现自己确实是理解有偏差的,从而导致面试时有些许尴尬。哎,谁叫自己学艺不精,现在亡羊补牢吧。

一、MVC

MVC(model-view-controller),用户操作> View (负责接受用户的输入操作)>Controller(业务逻辑处理)>Model(数据持久化)>View(将结果通过View反馈给用户)。
M - Model :数据保存
V - View : 用户界面
C - Controller : 业务逻辑

MVC逻辑图
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上。

  1. 低耦合。视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的"View"上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。

  2. 可重用性。你可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑。

  3. 独立开发。开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计。

  4. 可测试。界面素来是比较难于测试的,而现在测试可以针对ViewModel来写。

不废话了,直接上代码,方便大家理解,我们用代码项目为例来进行分析:


MVVM逻辑示意图
//新建一个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之间通信的完全隔离。这个目前买没有项目以及实例,所以就不贴代码了,我们提供示意图作为参考。

MVP逻辑图
参考资料1
参考资料2
上一篇下一篇

猜你喜欢

热点阅读