架構(gòu)模式MVC,MVP, MVVM

MVC

MVC架構(gòu)模式: Model-View-Controller是一個(gè)用來(lái)組織代碼的權(quán)威范式。Apple甚至是這么說(shuō)的。在MVC下,所有的對(duì)象被歸類為一個(gè)model,一個(gè)view,或一個(gè)controller。Model持有數(shù)據(jù),View顯示與用戶交互的界面,而View Controller調(diào)解Model和View之間的交互。

用戶操作View, 在Controller層完成業(yè)務(wù)邏輯處理, 更新Model層, 將數(shù)據(jù)顯示在View層.

  • Model層
@interface Person : NSObject
@property (nonatomic, readonly) NSString *firstName;
@property (nonatomic, readonly) NSString *lastName;

- (instancetype)initWithFirstName:(NSString *)firstName lastName:(NSString *)lastName;

@end

@implementation Person

- (instancetype)initWithFirstName:(NSString *)firstName lastName:(NSString *)lastName {
    if ([super init]) {
        _firstName = firstName;
        _lastName = lastName;
    }
    return self;
}
@end
  • View層
@interface TestView : UIView

@property (nonatomic, strong) UILabel *nameLabel;

@end

@implementation TestView

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        _nameLabel = [[UILabel alloc] initWithFrame:self.bounds];
        _nameLabel.textAlignment = NSTextAlignmentCenter;
        [self addSubview:_nameLabel];
    }
    return self;
}
@end
  • Controller層
@interface ViewController ()

@property (nonatomic, strong) Person *personModel;
@property (nonatomic, strong) TestView *testView;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    [self setupViews];

    if (self.personModel.firstName.length > 0) {
        self.testView.nameLabel.text = self.personModel.firstName;
    } else {
        self.testView.nameLabel.text = self.personModel.lastName;
    }
}

- (void)setupViews {
    self.personModel = [[Person alloc] initWithFirstName:@"" lastName:@"XXX"];
    self.testView = [[TestView alloc] initWithFrame:CGRectMake(100, 100, CGRectGetWidth(self.view.bounds)-200, 50)];
    [self.view addSubview:self.testView];
}

@end

MVP

MVP架構(gòu)模式: Model-View-Presenter是MVC的改良模式,由IBM的子公司Taligent提出。和MVC的相同之處在于:Controller/Presenter負(fù)責(zé)業(yè)務(wù)邏輯,Model管理數(shù)據(jù),View負(fù)責(zé)顯示只不過(guò)是將 Controller 改名為 Presenter,同時(shí)改變了通信方向。
View 與 Model 不通信,都通過(guò) Presenter 傳遞。Presenter完全把Model和View進(jìn)行了分離,主要的程序邏輯在Presenter里實(shí)現(xiàn)。

  • Model層
@interface Person : NSObject

@property (nonatomic, readonly) NSString *firstName;
@property (nonatomic, readonly) NSString *lastName;

- (instancetype)initWithFirstName:(NSString *)firstName lastName:(NSString *)lastName;

@end

@implementation Person

- (instancetype)initWithFirstName:(NSString *)firstName lastName:(NSString *)lastName {
    if (self = [super init]) {
        _firstName = firstName;
        _lastName = lastName;
    }
    return self;
}

@end
  • View層
@interface TestView : UIView

@property (nonatomic, strong) UILabel *nameLabel;

@end

@implementation TestView

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        _nameLabel = [[UILabel alloc] initWithFrame:self.bounds];
        _nameLabel.textAlignment = NSTextAlignmentCenter;
        [self addSubview:_nameLabel];
    }
    return self;
}
@end
  • Presenter層
@protocol PersonViewProtocol

- (void)setNameText:(NSString *)nameText;

@end

@interface Presenter : NSObject

- (void)attachView:(id )view;

- (void)fetchData;

@end


@interface Presenter()

@property (nonatomic, strong) Person *person;
@property (nonatomic, weak) id attachView;

@end

@implementation Presenter

- (void)attachView:(id)view {
    self.attachView = view;
}

- (void)fetchData {
    self.person = [[Person alloc] initWithFirstName:@"AAA" lastName:@"BB"];
    if (self.person.firstName.length > 0) {
        [self.attachView setNameText:self.person.firstName];
    } else {
        [self.attachView setNameText:self.person.lastName];
    }
}

@end
  • Controller
@interface ViewController ()

@property (nonatomic, strong) TestView *testView;
@property (nonatomic, strong) Presenter *presenter;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    [self setupViews];

    self.presenter = [Presenter new];
    [self.presenter attachView:self];
    [self.presenter fetchData];
}

- (void)setupViews {
    self.testView = [[TestView alloc] initWithFrame:CGRectMake(100, 100, CGRectGetWidth(self.view.bounds)-200, 50)];
    [self.view addSubview:self.testView];
}

#pragma PersonViewProtocol
- (void)setNameText:(NSString *)nameText {
    self.testView.nameLabel.text = nameText;
}

@end

MVVM

MVVM架構(gòu)模式: Model-View-ViewModel是 M-V-VM 三部分組成,它本質(zhì)上就是 MVC 的改進(jìn)版. 在 MVC 下,所有的對(duì)象被歸類為一個(gè) model,一個(gè) view,或一個(gè) controller。Model 持有數(shù)據(jù),View 顯示與用戶交互的界面,而 View Controller 調(diào)解 Model 和 View 之間的交互。然而,隨著模塊的迭代我們?cè)絹?lái)越發(fā)現(xiàn) MVC 自身存在著很多不足。因此,MVVM 從其他應(yīng)用而出,在 iOS 中從此我們完全將業(yè)務(wù)邏輯加以區(qū)分并使用這套思想。在 MVVM 中他的設(shè)計(jì)思路和 MVC 很像。它正式規(guī)范了視圖和控制器緊耦合的性質(zhì),并引入新的組件 ViewModel。此外,它還有像監(jiān)管版本的 MVP 那樣的綁定功能,但這個(gè)綁定不是在 View 和 Model 之間而是在 View 和 ViewModel 之間。

  • Model層
@interface Person : NSObject

@property (nonatomic, readonly) NSString *firstName;
@property (nonatomic, readonly) NSString *lastName;

- (instancetype)initWithFirstName:(NSString *)firstName lastName:(NSString *)lastName;

@end

@implementation Person

- (instancetype)initWithFirstName:(NSString *)firstName lastName:(NSString *)lastName {
    if (self = [super init]) {
        _firstName = firstName;
        _lastName = lastName;
    }
    return self;
}

@end
  • View層
@interface TestView : UIView

@property (nonatomic, strong) UILabel *nameLabel;

@end

@implementation TestView

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        _nameLabel = [[UILabel alloc] initWithFrame:self.bounds];
        _nameLabel.textAlignment = NSTextAlignmentCenter;
        [self addSubview:_nameLabel];
    }
    return self;
}

@end
  • ViewModel層
@interface PersonViewModel : NSObject

@property (nonatomic, readonly) Person *person;
@property (nonatomic, readonly) NSString *nameText;

- (instancetype)initWithPerson:(Person *)person;

@end


@implementation PersonViewModel

- (instancetype)initWithPerson:(Person *)person {

    if (self = [super init]) {
        _person = person;
        if (_person.firstName.length > 0) {
            _nameText = _person.firstName;
        } else {
            _nameText = _person.lastName;
        }
    }
    return self;
}

@end
  • Controller
@interface ViewController ()

@property (nonatomic, strong) TestView *testView;
@property (nonatomic, strong) PersonViewModel *viewModel;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    [self setupViews];

    self.testView.nameLabel.text = self.viewModel.nameText;
}

- (void)setupViews {
    Person *person = [[Person alloc] initWithFirstName:@"AAA" lastName:@"BB"];
    self.viewModel = [[PersonViewModel alloc] initWithPerson:person];
    self.testView = [[TestView alloc] initWithFrame:CGRectMake(100, 100, CGRectGetWidth(self.view.bounds)-200, 50)];
    [self.view addSubview:self.testView];
}

@end
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容