美文网首页
iOS的设计模式分析

iOS的设计模式分析

作者: woniu | 来源:发表于2018-06-27 17:56 被阅读33次
    见兔而顾犬,未为晚也;亡羊而补牢,未为迟也。------《战国策·楚策》

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

    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上。

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

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

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

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

    • MVVM的缺点
      1、类会增多
      每个VC都附带一个viewModel,类的数量*2

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

      3、调用复杂度增加
      由于数据都是从viewModel来,想想突然来了一个新人,一看代码,不知道真实的模型是谁。比如常用tableview的数据源,一般都是一个数组,如果不断的通过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

    相关文章

      网友评论

          本文标题:iOS的设计模式分析

          本文链接:https://www.haomeiwen.com/subject/asvbyftx.html