【iOS】关于设计模式的小小总结
在软件开发中,无论是什么开发语言总会伴随着一下常见的设计模式,如MVC模式、代理模式、单例模式等等。下面就对开发中常用的一下模式进行归纳整理。
首先先说一下什么是设计模式?
设计模式是一种编程经验,就是用比较成熟的逻辑来处理某一类型的事情。有了它我们就可以比较清晰明了的来处理开发中遇到的问题。
在iOS中常用的设计模式有哪些?
在开发中常用的设计模式包含单例模式、观察者模式、代理模式、工厂模式、策略模式、MVC模式以及MVC的变种MVVM模式。
以上就是常用的设计模式,当然还有一些不常用的模式,如中介者模式、组合模式等
下面我就一一解释常用的设计模式
一、单例模式
单例模式可以保证APP在程序运行中,一个类有且只有唯一一个实例(即无论请求创建多少次,始终返回同一个实例),并且在整个APP程序中,这一份资源是共享的。它通常采用懒加载的方式在第一次用到实例的时候再去创建。
优点:使用简单,延时求值,易于跨模块
敏捷原则:单一职责原则
示例:苹果大量使用了此模式。例如:[NSUserDefaults standardUserDefaults], [UIApplication sharedApplication], [UIScreen mainScreen], [NSFileManager defaultManager],所有的这些方法都返回一个单例对象。
个人理解:
很多情况下我们并不会关心一个类是否有多个实例,占多少内存的问题。可是在一些情况下,只有一个实例显得非常合理。举例来说,我们有一个配置文件,但是有好多歌类同时修改这个文件,我们创建一个单例就显得很合理了。
二、观察者模式
观察者模式本质上是一种发布-订阅模型,泳衣消除具有不同行为的对象之间的耦合。通过这一模式,不同对象之间可以协同工作,同时他们也可以被复用于其他地方Observer从Subject订阅通知,ConncrecteObserver实现重现Observer并将其重载其update方法。
一旦Subject的实例需要通知Observer任何新的变更,Subject就会发送update消息来通知存储在其内部类中所注册的Observer,在ConcreteObserver的update方法中,Subject的内部状态可被获取并进行后续处理。
优点:解耦合
敏捷原则:接口隔离原则,开放-封闭原则
示例:Notification通知中心,注册通知中心,任何位置都可以发送消息,注册观察者的对象都可以接收消息;KVO键值对改变通知的观察者等
个人理解:
一般为model层,对从controller和view进行的通知方式,不关心谁去接受,只负责发布消息。
三、代理模式
代理模式是一种消息传递方式,一个完整的代理模式包括:委托对象,代理对象和协议。
协议“用来指定代理双方可以做什么,必须做什么。
委托对象:根据协议指定代理对象需要完成的事,即调用协议中的方法。
代理对象:根据协议实现委托方需要完成的事,即实现协议中的方法。
代理模式完成委托方交给的任务,委托方有一些任务自己不想完成,但是还需要实现,择将该任务存放在协议中,由代理完成。但是代理并不会主动的执行任务,需要委托方通知代理。
优点:解耦合
敏捷原则:开放-封闭原则
示例:tableview的 数据源delegate;列表row个数delegate;自定义的delegate等
个人理解:
当一个类的某些功能需要由别的类来实现,但是又不确定具体会是哪个类实现。可以使用代理。举个例子,我在公司敲代码,突然想吃水果,这是我就拿起手机去每日生鲜订一份水果,然后每日生鲜会下单给店铺并让店铺给我送过来。这个过程中,我是委托方,APP是我的代理,我买了一份水果并付给APP钱,这就是购买协议。我只需要从APP上都卖,其余操作都是APP去处理。我付的钱就是参数,送过来的水果就是处理结果。再买水果的同事我还可以定外卖,这时需要用到饿了么APP。饿了么当我的代理。这就是多个代理对象。实现一对多。
四、工厂模式
专门定义一个类来负责创建其他类的实例,被创建的实例痛楚具有共同的父类。简单来说就是定义一个抽象类,抽象类中生命公共的特征及属性,抽象子类继承抽象类,趋势线具体的操作。工厂类根据外界需求,在工厂类中创建对应的抽象子类实例并传给外界,而对象的创建室友外界决定的,外界只需要知道抽象子类对应参数即可,并不需要抽象子类的创建过程,在外界使用甚至不用引入抽象子类。
优点:易于替换,面向对象编程,application只与抽象工厂和易变类的共性抽象类发生调用关系。
通过简单工厂模式的重构,我们就实现了低耦合度的代码结构,做到了对外扩展开放,对修改关闭。如果再增加任何的操作方法,只需要继承操作方法父类,新建一个操作子类,并且在简单工厂类里面多添加一个else if的判断即可。
缺点:工厂类集中了所有产品的创建逻辑,一旦不能正常工作,整个系统都会受到影响,而且当产品类多、结构复杂时,把所有的创建工作放在一个工厂中,后期扩展维护比较困难。
敏捷原则:DIP一来倒置原则
示例:工厂方式创建类的实例,多与proxy模式配合,创建可替换代理类。如项目部署环境中依赖多个不同类型的数据库时,需要使用工厂配合proxy完成易用性替换
个人理解:
我认为工厂模式就是为了创建对象的。一般来说我们创建对象都是alloc一个,如果需要创建100个,在for循环中还好。可是实际中往往不是如此。我们可能会在不同的地方去创建,难道我们要写100次?并且如果我们在创建时给属性添加值,那就更复杂了。那么我们如果写一个父类并在里面写一个createObj的方法,把创建和赋值写在方法里,然后都继承这个父类这不就简单很多了。这就是简单工程方法。这也说明了工厂类的限制,就是创建的类必须有同一个父类,而且创建的类在不同地方调用的方法一致。
在项目初期,软件结构和需求都没有稳定下来时,不建议使用此模式。
五、策略模式
策略模式定义了一系列的算法,并将每一个算法封装起来,而且使他们还可以互相替换。使算法本身和使用算法的用户分割开来,互相独立
优点:使算法的变化独立于使用算法的用户
敏捷原则:接口隔离原则,多用组合,少用继承,针对接口编程而非实现。
个人理解:
举一个简单的例子,就像地图APP中,确定起始点和目的地后我们可以选择不同的出行方式(步行、公交、私家车等)。
六、MVC模式
MVC模式是一种古老的软件设计典范。通过数据模型,控制器逻辑,视图展示将应用程序进行逻辑划分。将控制器逻辑聚集在一个部件中,在改进页面和交互是不需要重新编写业务逻辑。
MVC涉及的三个角色:
Model:模型对象用来封装应用程序的数据,并定义操作和处理该数据的逻辑和运算。
View:试图对象是用户在应用程序中可以看到的对象。它知道如何将自己展示绘制出来,并对用户的操作做出反应。
Controller:控制器是一个协调所有工作的中介者。它访问模型中的数据并在视图中展示它们,同时它们还监听事件和操作数据。通过它,视图可以了解模型的更改,反之亦然。控制器对象还可以为应用程序执行设置和协调人物,并管理其他对象的生命周期。
优点:是系统层次清晰,职责分明,易于维护。
敏捷原则:对扩展开发-对修改封闭
个人理解:
一个MVC模式的好的实现也就意味着每一个对象都会被划分到上面的三种角色中。可以用下图来协助理解。
模型会把数据的变更通知控制器,然后控制器更新视图数据。
试图对象通知控制器用户的操作,控制器要么根据需求来更新模型,要么检索任何被请求的数据。
七、MVVM模式
在iOS应用日益增长的重量级控制器的情形下,典型的MVC模式中,许多逻辑被安放在ViewController中。他们中的一些确实属于viewController,但更多的是所谓的表示逻辑。为了不让控制器日益增大,便于管理便出现了MVVM。
MVVM是MVC的增强版,并将表示逻辑从Controller中移出放在一个新的对象里面,即ViewModel。在iOS中使用MVVM的动机就是为了减少ViewController的复杂性并使得表示逻辑更易于测试。
ViewModel:位于ViewController和Model之间,是两者的沟通桥梁,是一些逻辑的处理。
这就是我对于常见设计模式的一些整理归纳,才疏学浅,如有问题,敬请指教。