设计模式:设计模式可以通俗的理解为实现/解决某些问题,而形成的解决方案规范。增加代码的可重用性,让代码能更容易理解和可靠。我们通常说所的代理模式、迭代器模式、策略模式就属于这一类。对各种设计模式的了解可以帮助我们更快的解决编程过程中遇到的问题。
架构模式:架构模式的出现时为了管理复杂的应用程序,这样可以在一个时间内专门关注一个方面。例如,您可以在不依赖业务逻辑的情况下专注于视图设计。同时也让应用程序的测试更加容易。同时也简化了分组开发。不同的开发人员可同时开发视图、控制器逻辑和业务逻辑。我们经常说的MVC架构、MVVM架构属于此类。
框架:这个最好理解了,通常是代码重用。框架与设计模式的概念容易弄混,两者有相似之处,但却有着根本的不同。设计模式是对在某种环境中反复出现的问题以及解决该问题的方案的描述规范,它比框架更抽象;框架为已经解决问题的具体实现方法,能直接执行或复用;设计模式是比框架更小的元素,一个框架中往往含有一种或多种设计模式。Xcode自带的Foundation、UIKit,以及我们经常使用的AFNetworking,MJExtension,SVProgressHUD就属于这一类。
设计模式:设计模式主要分三个类型:创建型、结构型和行为型。
创建型:
一、Abstract Factory,抽象工厂:提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们的具体类。也就是通常说的类方法
二、Builder,建造模式:将一个复杂对象的构建与他的表示相分离,使得同样的构建过程可以创建不同的表示。
三、Factory Method,工厂方法:定义一个用于创建对象的接口,让子类决定实例化哪一个类,Factory为一个产品族提供了统一的创建接口。
四、Prototype,原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型来创建新的对象。
五、Singleton,单例模式:保证一个类只有一个实例,并提供一个访问它的全局访问点。
结构型:
一、Adapter,适配器模式:将一类的接口转换成客户希望的另外一个接口,Adapter模式使得原本由于接口不兼容而不能一起工作那些类可以一起工作。
二、Bridge,桥模式:将抽象部分与它的实现部分相分离,使他们可以独立的变化。
三、Composite,组合模式:将对象组合成树形结构以表示部分整体的关系,Composite使得用户对单个对象和组合对象的使用具有一致性。
四、Decrator,装饰模式:动态地给一个对象增加一些额外的职责,就增加的功能来说,Decorator模式相比生成子类更加灵活。
五、Facade,外观模式:为子系统中的一组接口提供一致的界面,Facade提供了一高层接口,这个接口使得子系统更容易使用。
六、Proxy,代理模式:为其他对象提供一种代理以控制对这个对象的访问。
七、Flyweight,享元模式: 通过共享以便有效的支持大量小颗粒对象。
行为型:
一、Chain of Responsibility,职责链模式:为解除请求的发送者和接收者之间耦合,而使多个对象都有机会处理这个请求。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它。
二、Command,命令模式:将一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化,对请求排队和记录请求日志,以及支持可撤销的操作。
三、Interpreter,解释器模式:给定一个语言,定义他的文法的一个表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
四、Iterator,迭代器模式:提供一个方法顺序访问一个聚合对象的各个元素,而又不需要暴露该对象的内部表示。
五、Mediator,中介者模式:用一个中介对象封装一些列的对象交互。
六、Memento,备忘录模式:在不破坏对象的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
七、Observer,观察者模式:定义对象间一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知自动更新。
八、State,状态模式:允许对象在其内部状态改变时改变他的行为。对象看起来似乎改变了他的类。
九、Strategy,策略模式:定义一系列的算法,把他们一个个封装起来,并使他们可以互相替换,本模式使得算法可以独立于使用它们的客户。
十、Template Method,模板方法:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中,TemplateMethod使得子类可以不改变一个算法的结构即可以重定义该算法得某些特定步骤。
十一、Visitor,访问者模式:表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素类的前提下定义作用于这个元素的新操作。
MVC:
MVC 即 Modal View Controller(模型 视图 控制器)
苹果推荐的 MVC:

View和Model之间没有任何直接的联系,Controller是一个介于View 和 Model之间的协调器,Controller里面写逻辑复杂度较高的代码;Model变化会通知Controller,然后Controller操作View更新;或者View上的数据发生改变,比如用户输入了用户名、或者修改了密码,View就会通知Controller更新Model;理论上来讲,这种模式看起来非常直观,但是这样的模式会让代码变得格外的臃肿。所有有很多开发者将MVC的缩写展开成(Massive View Controller)。所以,为View controller减负也成为iOS开发者面临的一个重要话题。
MVC 的事实:

Cocoa的MVC模式驱使人们写出臃肿的视图控制器,因为它们经常被混杂到View的生命周期中,因此很难说View和ViewController是分离的。尽管仍可以将业务逻辑和数据转换到Model,但是大多数情况下当需要为View减负的时候我们却无能为力了,View的最大的任务就是向Controller传递用户动作事件。ViewController最终会承担一切代理和数据源的职责,还负责一些分发和取消网络请求以及一些其他的任务,所以会让代码变得格外臃肿;而有时候我们的View还持有Model造成了Model和View的耦合。
综上所述:Cocoa MVC 看起来是一个相当差的架构方案。但是如果你不想在架构选择上投入更多精力,那么Cocoa MVC无疑是最好的方案,而且你会发现一些其他维护成本较高的模式对于你所开发的小的应用是一个致命的打击。但是就开发速度而言,Cocoa MVC 是组好的架构选择方案。
MVC的优缺点:任务均摊–View和Model确实是分开的,但是View和Controller却是紧密耦合的;Controller格外的臃肿;可测试性–由于糟糕的分散性,只能对Model进行测试;易用性–与其他几种模式相比最小的代码量。熟悉的人很多,因而即使对于经验不那么丰富的开发者来讲维护起来也较为容易。
MVP:
MVP 全称:Model-View-Presenter ;MVP 是从经典的模式MVC演变而来
Controller/Presenter负责逻辑的处理,Model提供数据,View负责显示。
MVP与MVC有着一个重大的区别:在MVP中View并不直接使用Model,它们之间的通信是通过Presenter (MVC中的Controller)来进行的,所有的交互都发生在Presenter内部,而在MVC中View会直接从Model中读取数据而不是通过 Controller。

MVC 和 MVP 的关系
MVP:是MVC模式的变种。
项目开发中,UI是容易变化的,且是多样的,一样的数据会有N种显示方式;业务逻辑也是比较容易变化的。为了使得应用具有较大的弹性,我们期望将UI、逻辑(UI的逻辑和业务逻辑)和数据隔离开来,而MVP是一个很好的选择。
Presenter代(协调器)替了Controller,它比Controller担当更多的任务,也更加复杂。Presenter处理事件,执行相应的逻辑,这些逻辑映射到Model操作Model。那些处理UI如何工作的代码基本上都位于Presenter。
MVC中的Model和View使用Observer模式进行沟通;MPV中的Presenter和View则使用Mediator模式进行通信;Presenter操作Model则使用Command模式来进行。基本设计和MVC相同:Model存储数据,View对Model的表现,Presenter协调两者之间的通信。在 MVP 中 View 接收到事件,然后会将它们传递到 Presenter, 如何具体处理这些事件,将由Presenter来完成。
如果要实现的UI比较复杂,而且相关的显示逻辑还跟Model有关系,就可以在View和 Presenter之间放置一个Adapter。由这个 Adapter来访问Model和View,避免两者之间的关联。而同时,因为Adapter实现了View的接口,从而可以保证与Presenter之 间接口的不变。这样就可以保证View和Presenter之间接口的简洁,又不失去UI的灵活性。
优缺点:
- 任务均摊–我们将最主要的任务划分到Presenter和Model,而View的功能较少(虽然上述例子中Model的任务也并不多)。
可测试性–非常好,由于一个功能简单的View层,所以测试大多数业务逻辑也变得简单
易用性–在我们上边不切实际的简单的例子中,代码量是MVC模式的2倍,但同时MVP的概念却非常清晰
MVVM:
MVVM是Model-View-ViewModel的简写,它的由来便是MVP(Model-View-Presenter)模式与WPF结合的应用方式时发展演变过来的一种新型架构框架。它立足于原有MVP框架并且把WPF的新特性糅合进去,以应对客户日益复杂的需求变化。
在mvp模式中presenter负责model与view的通信,而mvvm中view和viewmodel以及model进行了双向绑定,但这个绑定不是在View和Model之间而是在View和ViewModel之间,m,v实现双向绑定;m的值改变,view界面自动更新;从而view和model能专心于逻辑,如下图:

MVVM 的三个特性评估
- 任务均摊 – 在例子中并不是很清晰,但是事实上,MVVM的View要比MVP中的View承担的责任多。因为前者通过ViewModel的设置绑定来更新状态,而后者只监听Presenter的事件但并不会对自己有什么更新。
可测试性 – ViewModel不知道关于View的任何事情,这允许我们可以轻易的测试ViewModel。同时View也可以被测试,但是由于属于UIKit的范畴,对他们的测试通常会被忽略。
易用性 – 在我们例子中的代码量和MVP的差不多,但是在实际开发中,我们必须把View中的事件指向Presenter并且手动的来更新View,如果使用绑定的话,MVVM代码量将会小的多。
MVVM优点
低耦合。View可以独立于Model变化和修改,一个ViewModel可以绑定到不同的”View”上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
可重用性。你可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑。
独立开发。开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计,生成xml代码。
可测试。界面素来是比较难于测试的,而现在测试可以针对ViewModel来写。
“MVVM很诱人,因为它集合了上述方法的优点,并且由于在View层的绑定,它并不需要其他附加的代码来更新View,尽管这样,可测试性依然很强。”
MVC,MVP,MVVM三者演化:

Viper:
VIPER有以下几部分组成
- 视图(View):根据展示器的要求显示界面,并将用户输入反馈给展示器。
- 交互器(Interactor):包含由用例指定的业务逻辑。
- 展示器(Presenter):包含为显示(从交互器接受的内容)做的准备工作的相关视图逻辑,并对用户输入进行反馈(从交互器获取新数据)
- 实体(Entity):包含交互器要使用的基本模型对象。
- 路由(Routing):包含用来描述屏幕显示和显示顺序的导航逻辑。
VIPER 和 MV(X)的区别:
VIPER把MVC中的Controller进一步拆分成了Presenter、Router和Interactor。和MVP中负责业务逻辑的Presenter不同,VIPER的Presenter的主要工作是在View和Interactor之间传递事件,并管理一些View的展示逻辑,主要的业务逻辑实现代码都放在了Interactor里。Interactor的设计里提出了”用例”的概念,也就是把每一个会出现的业务流程封装好,这样可测试性会大大提高。而Router则进一步解决了不同模块之间的耦合。
优点
VIPER的特色就是职责明确,粒度细,隔离关系明确,这样能带来很多优点:
可测试性好。UI测试和业务逻辑测试可以各自单独进行。
易于迭代。各部分遵循单一职责,可以很明确地知道新的代码应该放在哪里。
隔离程度高,耦合程度低。一个模块的代码不容易影响到另一个模块。
易于团队合作。各部分分工明确,团队合作时易于统一代码风格,可以快速接手别人的代码。
缺点
一个模块内的类数量增大,代码量增大,在层与层之间需要花更多时间设计接口。
模块的初始化较为复杂,打开一个新的界面需要生成View、Presenter、Interactor,并且设置互相之间的依赖关系。而iOS中缺少这种设置复杂初始化的原生方式。