美文网首页
设计模式和架构

设计模式和架构

作者: dandelionYD | 来源:发表于2019-04-12 11:21 被阅读0次

    面试题

    1.讲讲MVC、MVVM、MVP,以及你在项目中是如何使用的?
    2.你自己用过哪些设计模式?
    3.一般开始一个项目,你的架构是如何思考的?
    

    演示代码 DesignPatternsArchitectures

    架构

    DesignPatterns_Architectures_1.png

    MVC - Apple版

    DesignPatterns_Architectures_2.png

    【mvc相信大家都用过,这里就不举例了】


    MVC – 变种

    DesignPatterns_Architectures_3.png
    ViewController.m
    
    #import "ViewController.h"
    #import "MyApp.h"
    #import "MyAppView.h"
    
    @interface ViewController () <MyAppViewDelegate>
    @end
    
    @implementation ViewController
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        // 创建view
        MyAppView *appView = [[MyAppView alloc] init];
        appView.frame = CGRectMake(100, 100, 100, 150);
        appView.delegate = self;
        [self.view addSubview:appView];
        
        // 加载模型数据
        MyApp *app = [[MyApp alloc] init];
        app.name = @"QQ";
        app.image = @"QQ";
        
        // 设置数据到view上
        appView.app = app;
    }
    
    #pragma mark - MyAppViewDelegate
    - (void)appViewDidClick:(MyAppView *)appView{
        NSLog(@"控制器监听到了appView的点击");
    }
    @end
    
    
    MyApp.h
    #import <Foundation/Foundation.h>
    @interface MyApp : NSObject
    @property (copy, nonatomic) NSString *name;
    @property (copy, nonatomic) NSString *image;
    @end
    
    MyApp.m
    #import "MyApp.h"
    @implementation MyApp
    @end
    
    
    MyAppView.h
    #import <UIKit/UIKit.h>
    @class MyApp, MyAppView;
    @protocol MyAppViewDelegate <NSObject>
    @optional
    - (void)appViewDidClick:(MyAppView *)appView;
    @end
    
    @interface MyAppView : UIView
    @property (strong, nonatomic) MyApp *app;
    @property (weak, nonatomic) id<MyAppViewDelegate> delegate;
    @end
    
    MyAppView.m
    #import "MyAppView.h"
    #import "MyApp.h"
    @interface MyAppView()
    @property (weak, nonatomic) UIImageView *iconView;
    @property (weak, nonatomic) UILabel *nameLabel;
    @end
    
    @implementation MyAppView
    - (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)setApp:(MyApp *)app{
        _app = app;
        self.iconView.image = [UIImage imageNamed:app.image];
        self.nameLabel.text = app.name;
    }
    
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
        if ([self.delegate respondsToSelector:@selector(appViewDidClick:)]) {
            [self.delegate appViewDidClick:self];
        }
    }
    @end
    

    MVP

    DesignPatterns_Architectures_4.png
    MyApp.h
    #import <Foundation/Foundation.h>
    @interface MyApp : NSObject
    @property (copy, nonatomic) NSString *name;
    @property (copy, nonatomic) NSString *image;
    @end
    
    MyApp.m
    #import "MyApp.h"
    @implementation MyApp
    @end
    
    MyAppView.h
    #import <UIKit/UIKit.h>
    @class MyAppView;
    @protocol MyAppViewDelegate <NSObject>
    @optional
    - (void)appViewDidClick:(MyAppView *)appView;
    @end
    
    @interface MyAppView : UIView
    - (void)setName:(NSString *)name andImage:(NSString *)image;
    @property (weak, nonatomic) id<MyAppViewDelegate> delegate;
    @end
    
    MyAppView.m
    #import "MyAppView.h"
    @interface MyAppView()
    @property (weak, nonatomic) UIImageView *iconView;
    @property (weak, nonatomic) UILabel *nameLabel;
    @end
    
    @implementation MyAppView
    
    - (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
    
    MyAppPresenter.h
    #import <UIKit/UIKit.h>
    
    @class MyApp, MyAppView;
    @interface MyAppPresenter : UIView
    @property (strong, nonatomic) MyApp *app;
    - (instancetype)initWithController:(UIViewController *)controller;
    @end
    
    MyAppPresenter.m
    #import "MyAppPresenter.h"
    #import "MyApp.h"
    #import "MyAppView.h"
    
    @interface MyAppPresenter() <MyAppViewDelegate>
    @property (weak, nonatomic) UIViewController *controller;
    @end
    
    @implementation MyAppPresenter
    - (instancetype)initWithController:(UIViewController *)controller
    {
        if (self = [super init]) {
            self.controller = controller;
            
            // 创建View
            MyAppView *appView = [[MyAppView alloc] init];
            appView.frame = CGRectMake(100, 100, 100, 150);
            appView.delegate = self;
            [controller.view addSubview:appView];
            
            // 加载模型数据
            MyApp *app = [[MyApp alloc] init];
            app.name = @"QQ";
            app.image = @"QQ";
            
            // 赋值数据
            [appView setName:app.name andImage:app.image];
        }
        return self;
    }
    
    #pragma mark - MyAppViewDelegate
    - (void)appViewDidClick:(MyAppView *)appView{
        NSLog(@"presenter 监听了 appView 的点击");
    }
    @end
    
    ViewController.m
    #import "ViewController.h"
    #import "MyAppPresenter.h"
    
    @interface ViewController ()
    @property (strong, nonatomic) MyAppPresenter *presenter;
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        self.presenter = [[MyAppPresenter alloc] initWithController:self];
    }
    @end
    

    MVVM

    DesignPatterns_Architectures_5.png

    和MVP的区别:可以监听属性的改变做出相应的操作

    【KVOController】
    facebook推出的属性监听(github)
    也可使用RAC
    
    MyApp_3.h
    #import <Foundation/Foundation.h>
    @interface MyApp_3 : NSObject
    @property (copy, nonatomic) NSString *name;
    @property (copy, nonatomic) NSString *image;
    @end
    
    MyApp_3.m
    #import "MyApp_3.h"
    @implementation MyApp_3
    @end
    
    MyAppView_3.h
    #import <UIKit/UIKit.h>
    @class MyAppView_3, MyAppViewModel;
    @protocol MyAppViewDelegate <NSObject>
    @optional
    - (void)appViewDidClick:(MyAppView_3 *)appView;
    @end
    
    @interface MyAppView_3 : UIView
    @property (weak, nonatomic) MyAppViewModel *viewModel;
    @property (weak, nonatomic) id<MyAppViewDelegate> delegate;
    @end
    
    MyAppView_3.m
    #import "MyAppView_3.h"
    #import <NSObject+FBKVOController.h>
    
    @interface MyAppView_3()
    @property (weak, nonatomic) UIImageView *iconView;
    @property (weak, nonatomic) UILabel *nameLabel;
    @end
    
    @implementation MyAppView_3
    - (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)setViewModel:(MyAppViewModel *)viewModel{
        _viewModel = viewModel;
        __weak typeof(self) waekSelf = self;
        [self.KVOController observe:viewModel keyPath:@"name" options:NSKeyValueObservingOptionNew block:^(id _Nullable observer, id _Nonnull object, NSDictionary<NSKeyValueChangeKey,id> * _Nonnull change) {
            waekSelf.nameLabel.text = change[NSKeyValueChangeNewKey];
        }];
        
        [self.KVOController observe:viewModel keyPath:@"image" options:NSKeyValueObservingOptionNew block:^(id _Nullable observer, id _Nonnull object, NSDictionary<NSKeyValueChangeKey,id> * _Nonnull change) {
            waekSelf.iconView.image = [UIImage imageNamed:change[NSKeyValueChangeNewKey]];
       }];
    }
    
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
        if ([self.delegate respondsToSelector:@selector(appViewDidClick:)]) {
            [self.delegate appViewDidClick:self];
        }
    }
    @end
    
    MyAppViewModel.h
    #import <Foundation/Foundation.h>
    #import <UIKit/UIKit.h>
    @interface MyAppViewModel : NSObject
    - (instancetype)initWithController:(UIViewController *)controller;
    @end
    
    MyAppViewModel.m
    #import "MyAppViewModel.h"
    #import "MyApp_3.h"
    #import "MyAppView_3.h"
    
    @interface MyAppViewModel() <MyAppViewDelegate>
    @property (weak, nonatomic) UIViewController *controller;
    @property (copy, nonatomic) NSString *name;
    @property (copy, nonatomic) NSString *image;
    @end
    
    @implementation MyAppViewModel
    - (instancetype)initWithController:(UIViewController *)controller{
        if (self = [super init]) {
            self.controller = controller;
            
            // 创建View
            MyAppView_3 *appView = [[MyAppView_3 alloc] init];
            appView.frame = CGRectMake(100, 100, 100, 150);
            appView.delegate = self;
            appView.viewModel = self;
            [controller.view addSubview:appView];
            
            // 加载模型数据
            MyApp_3 *app = [[MyApp_3 alloc] init];
            app.name = @"QQ";
            app.image = @"QQ.jpg";
            
            // 设置数据
            self.name = app.name;
            self.image = app.image;
        }
        return self;
    }
    
    #pragma mark - MyAppViewDelegate
    - (void)appViewDidClick:(MyAppView_3 *)appView{
        NSLog(@"viewModel 监听了 appView 的点击");
        self.name = [NSString stringWithFormat:@"数字:%ld",random()%100];
    }
    @end
    
    ///使用
    #import "ViewController_3.h"
    #import "MyAppViewModel.h"
    
    @interface ViewController_3 ()
    @property (strong, nonatomic) MyAppViewModel *viewModel;
    @end
    
    @implementation ViewController_3
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.viewModel = [[MyAppViewModel alloc] initWithController:self];
    }
    @end
    
    
    //======================使用RAC来监听=====================
    - (void)setViewModel:(MyAppViewModel *)viewModel{
        _viewModel = viewModel;
        __weak typeof(self) waekSelf = self;
           
        //RAC
        [[self.viewModel rac_valuesForKeyPath:@"name" observer:self] subscribeNext:^(id x) {
            waekSelf.nameLabel.text = x;
        }];
        
        [[self.viewModel rac_valuesForKeyPath:@"image"observer:self] subscribeNext:^(id x) {
             waekSelf.iconView.image = [UIImage imageNamed:x];
        }];
    }
    

    三层架构

    DesignPatterns_Architectures_6.png

    设计模式

    DesignPatterns_Architectures_7.png

    相关文章

      网友评论

          本文标题:设计模式和架构

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