iOS底层-架构设计

MVC/MVP/MVVM

MVC

MVC - Apple版

图4

  1. 优点:View、Model可以重复利用,可以独立使用
  2. 缺点:Controller的代码过于臃肿
  3. View特点:View需要将自己的属性暴露出来
  4. 举例:

     #import "ZHNewsViewController.h"
     #import "ZHShop.h"
        
     @interface ZHNewsViewController ()
     @property (strong, nonatomic) NSMutableArray *shopData;
     @end
        
     @implementation ZHNewsViewController
        
     - (void)viewDidLoad {
         [super viewDidLoad];
         [self loadShopData];
     }
        
     - (void)loadShopData
     {
         self.shopData = [NSMutableArray array];
            
         for (int i = 0; i < 20; i++) {
             ZHShop *shop = [[ZHShop alloc] init];
             shop.name = [NSString stringWithFormat:@"商品-%d", i];
             shop.price = [NSString stringWithFormat:@"¥19.%d", i];
             [self.shopData addObject:shop];
         }
     }
        
        
     #pragma mark - Table view data source
     - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
         return self.shopData.count;
     }
        
     /**MVC - Apple版
      控制器取出模型,来赋值给View的属性
      优点:View、Model可以重复利用,可以独立使用
      缺点:Controller的代码过于臃肿
      View特点:View需要将自己的属性暴露出来
      */
     - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
         UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"NewsCell" forIndexPath:indexPath];
            
         ZHShop *shop = self.shopData[indexPath.row];
            
         cell.detailTextLabel.text = shop.price;
         cell.textLabel.text = shop.name;
            
         return cell;
     }
     @end
    

MVC – 变种

图4

  1. 优点:对Controller进行瘦身,将View内部的细节封装起来了,外界不知道View内部的具体实现
  2. 缺点:View依赖于Model
  3. View拥有Model
  4. 举例略(常用的)

MVP

图4

  1. 代码示例

     #import <UIKit/UIKit.h>
    
     @interface ZHAppPresenter : NSObject
     - (instancetype)initWithController:(UIViewController *)controller;
     @end
        
     #import "ZHAppPresenter.h"
     #import "ZHApp.h"
     #import "ZHAppView.h"
        
     @interface ZHAppPresenter() <ZHAppViewDelegate>
     @property (weak, nonatomic) UIViewController *controller;
     @end
        
     @implementation ZHAppPresenter
        
     - (instancetype)initWithController:(UIViewController *)controller
     {
         if (self = [super init]) {
             self.controller = controller;
                
             // 创建View
             ZHAppView *appView = [[ZHAppView alloc] init];
             appView.frame = CGRectMake(100, 100, 100, 150);
             appView.delegate = self;
             [controller.view addSubview:appView];
                
             // 加载模型数据
             ZHApp *app = [[ZHApp alloc] init];
             app.name = @"QQ";
             app.image = @"QQ";
                
             // 赋值数据
             [appView setName:app.name andImage:app.image];
         }
         return self;
     }
        
     #pragma mark - ZHAppViewDelegate
     - (void)appViewDidClick:(ZHAppView *)appView
     {
         NSLog(@"presenter 监听了 appView 的点击");
     }
        
     @end
        
    
     #import <UIKit/UIKit.h>
        
     @class ZHAppView;
        
     @protocol ZHAppViewDelegate <NSObject>
     @optional
     - (void)appViewDidClick:(ZHAppView *)appView;
     @end
        
     @interface ZHAppView : UIView
     - (void)setName:(NSString *)name andImage:(NSString *)image;
     @property (weak, nonatomic) id<ZHAppViewDelegate> delegate;
     @end
     #import "ZHAppView.h"
    
     @interface ZHAppView()
     @property (weak, nonatomic) UIImageView *iconView;
     @property (weak, nonatomic) UILabel *nameLabel;
     @end
        
     @implementation ZHAppView
        
     - (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)setName:(NSString *)name andImage:(NSString *)image
     {
         _iconView.image = [UIImage imageNamed:image];
         _nameLabel.text = name;
     }
        
     - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
     {
         if ([self.delegate respondsToSelector:@selector(appViewDidClick:)]) {
             [self.delegate appViewDidClick:self];
         }
     }
        
     @end
        
        
     //使用
     #import "ViewController.h"
     #import "ZHAppPresenter.h"
     @interface ViewController ()
     @property (strong, nonatomic) ZHAppPresenter *presenter;
     //@property (strong, nonatomic) ZHOtherPresenter *presenter1;
     //@property (strong, nonatomic) ZHNewsPresenter *presenter2;
     @end
        
     @implementation ViewController
        
     - (void)viewDidLoad {
         [super viewDidLoad];
            
         self.presenter = [[ZHAppPresenter alloc] initWithController:self];
     }
     @end
    

MVVM

分层架构

  1. 界面层
    1. 调用业务层拿到数据来展示
  2. 业务层(service)
    1. 封装用于获取数据的工具,对外提供一个API供界面层使用
    2. 内部调用数据层获取工具
  3. 数据层
    1. 网络请求的工具—用网络请求获取数据
    2. 获取本地数据工具—获取本地缓存数据

设计模式

  1. 设计模式(Design Pattern)
    1. 是一套被反复使用、代码设计经验的总结
    2. 使用设计模式的好处是:可重用代码、让代码更容易被他人理解、保证代码可靠性
    3. 一般与编程语言无关,是一套比较成熟的编程思想
  2. 设计模式可以分为三大类
    1. 创建型模式:对象实例化的模式,用于解耦对象的实例化过程
      1. 单例模式、工厂方法模式,等等
    2. 结构型模式:把类或对象结合在一起形成一个更大的结构
      1. 代理模式、适配器模式、组合模式、装饰模式,等等
    3. 行为型模式:类或对象之间如何交互,及划分责任和算法
      1. 观察者模式、命令模式、责任链模式,等等

资料推荐

  1. 数据结构与算法
    1. 严蔚敏,《数据结构》
    2. 《大话数据结构与算法》
  2. 网络
    1. 《HTTP权威指南》
    2. 《TCP/IP详解卷1:协议》
  3. 架构与设计模式
    1. https://github.com/skyming/Trip-to-iOS-Design-Patterns
    2. https://design-patterns.readthedocs.io/zh_CN/latest/
Table of Contents