# 设计模式
代理模式、观察者模式、MVC模式、单例模式、策略模式、工厂模式、MVVM
##代理
场景:当一个类的某些功能需要由别的类来实现,但是又不确定具体会是哪个类实现。
优势:解耦合
敏捷原则:开放-封闭原则
实例:tableview的 数据源delegate,通过和protocol的配合,完成委托诉求。
列表row个数delegate
自定义的delegate
一句话总结:传入对象实现对象的功能
## 观察者
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己。 简而言之,就是A和B,A对B的变化感兴趣,就注册A为观察者,当B发生变化时通知A,告知B发生了变化。这个也叫做经典观察者模式。
场景:一般为model层对,controller和view进行的通知方式,不关心谁去接收,只负责发布信息。
实例:Notification通知中心,注册通知中心,任何位置可以发送消息,注册观察者的对象可以接收。
kvo,键值对改变通知的观察者。
对象的属性变化时,通知会直接发送到观察者对象.
可以用来实现 ,比如, UITableView滑动时导航自动变换颜色,或者,一个计算房贷的软件,当首付金额改变时,每月还款数目等数据相应自动改变等.
这里来观察UITableView一个实例的contentOffset属性.
##MVC
场景:是一中非常古老的设计模式,通过数据模型,控制器逻辑,视图展示将应用程序进行逻辑划分。
优势:使系统,层次清晰,职责分明,易于维护
敏捷原则:对扩展开放-对修改封闭
实例:model-即数据模型,view-视图展示,controller进行UI展现和数据交互的逻辑控制。
##单例
一个单例类,保证一个类仅有一个实例,在整个程序中只有一个实例,并且提供一个类方法供全局调用,在编译时初始化这个类,然后一直保存在内存中,到程序(APP)退出时由系统自动释放这部分内存。
在整个应用程序中,共享一份资源(这份资源只需要创建初始化1次),一般用于工具类。例如:登陆控制器,网络数据请求,音乐播放器等一个工程需要使用多次的控制器或方法。
如工具类、公共跳转类等经常调用的类,都会采用单例模式。
static LoginViewController * _instance = nil;
+(instancetype)sharedLoginHandle{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// loginVC = [[LoginViewController alloc] init];
_instance= [[self alloc] init];
});
return _instance;
}
## 适配器
适配器模式:将一个类的接口转换成客户端希望的另一个接口。适配器模式使得原来由于接口不兼容而不能一起工作的那些类可以一起工作。
基本上有两种实现适配器的方式。
第一种是通过集成来适配两个接口,这称为类适配器。类适配器是通过多重集成来实现的。
第二种是对象适配器,与类适配器不同,对象适配器不继承被适配者,而是组合了一个对它的引用。
简单讲适配器模式的作用就是在封装控件,接收数据的时候,数据通过中间的适配器处理后再传给控件,主要是在自定义控件时使用。
##策略
策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。
简而言之就是把控制其中的一大串 if...else... 或者 switch()单独抽出来写成一些列的算法文件, 减轻了ViewController的负担同时也简化操作,提高代码维护性。算法可以自由切换,避免使用多重条件判断,扩展性良好。
**注意事项: #e91e63 如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题。
#import "EmailValidator.h"
@implementation EmailValidator
-(BOOL)validateInput:(UITextField *)input {
if (input.text.length <= 0) {
self.errorMessage = @"邮箱没有输入";
}
else{
self.errorMessage = nil;
}
return self.errorMessage == nil ? YES : NO;
}
@end
## 装饰器(Decorator)
装饰器模式在不修改原来代码的情况下动态的给对象增加新的行为和职责,它通过一个对象包装被装饰对象的方法来修改类的行为,这种方法可以做为子类化的一种替代方法。
这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。
在Objective-C中,存在两种非常常见的实现:Category(类别)和Delegation(委托)。
## 原型(Prototype)
使用原型实例指定创建对象的种类,并通过复制这个原型创建新的对象。
NSArray *array = [[NSArray alloc] initWithObjects:@1, nil];
NSArray *array2 = array.copy;
array 就是原型了,array2 以 array 为原型,通过 copy 操作创建了 array2。
当创建的实例非常复杂且耗时,或者新实例和已存在的实例值相同,使用原型模式去复制已经存在的实例效率更高。
## MVVM
在 iOS 应用中日益增长的重量级视图控制器的问题。在典型的 MVC 应用里, 许多 逻辑被放在 View Controller 里。
它们中的一些确实属于 View Controller,但更多的是所谓的“表示逻辑(presentation logic);
为了不让控制器日益增大,便于测试管理,便出现了MVVM.
MVVM:它其实是一个 MVC 的增强版,并将表示逻辑从 Controller 移出放到一个新的对象里,即 View Model
在 iOS 上使用 MVVM 的动机,就是让它能减少 View Controller 的复杂性并使得表示逻辑更易于测试
## MVP
1,controller,view是属于MVP中的V,model即为上图中的M,关键的Presenter,是对V,M的组织;
2,在数据模型M中发起请求,在Presenter组织好数据,通过协议,哪个view遵守了Presenter的协议,数据返回给指定的view;
3,V与M是完全解耦的,在controller界面进来,引入Presenter,通过协议,从而形成了请求数据--展示到指定的view上。其实是把逻辑处理放到了Presenter这里。