iOS设计模式

近期可自由安排的时间比較多, iOS应用方面, 没什么好点子, 就先放下, 不写了。花点时间学学设计模式。

之后将会写一系列博文, 记录设计模式学习过程。

当然, 由于我自己是搞iOS的, 所以之后设计代码部分, 将尽量与objective-c相结合。


iOS设计模式 - 概述           by Colin丶

转载请注明出处:              http://blog.csdn.net/hitwhylz/article/details/40372113


一。定义

设计模式(Design pattern)是一套被重复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。

使用设计模式是为了可重用代码、让代码更easy被他人理解、保证代码可靠性。 

毫无疑问,

  • 设计模式于己于他人于系统都是多赢的。
  • 模式使代码编制真正project化;
  • 设计模式是软件project的基石脉络。如同大厦的结构一样。


二。

目的

其目的就是一方面教你怎样利用真实可靠的设计来组织代码的模板。 简单地说,就是从前辈们在程序设计过程中总结、抽象出来的通用优秀经验。

主要目的一方面是为了添加程序的灵活性、可重用性。 

 还有一方面也有助于程序设计的标准化和提高系统开发进度



也有人忠告:不要过于注重程序的“设计模式”。

有时候,写一个简单的算法,要比引入某种模式更easy。在多数情况下,程序代码应是简单易懂。甚至清洁工也能看懂。只是呢, 在大项目或者框架中。没有设计模式来组织代码,别人是不易理解的。



一个软件设计模型也仅仅仅仅是一个引导。它必须依据程序设计语言和你的应用程序的特点和要求而特别的设计。


三。

原则

面向对象有几个原则:

  • 开闭原则(Open Closed Principle。OCP)
  • 里氏代换原则(Liskov Substitution Principle,LSP)
  • 依赖倒转原则(Dependency Inversion Principle,DIP)
  • 接口隔离原则(Interface Segregation Principle,ISP)
  • 合成/聚合复用原则(Composite/Aggregate Reuse Principle。CARP)
  • 最小知识原则(Principle of Least Knowledge,PLK,也叫迪米特法则)

开闭原则具有理想主义的色彩。它是面向对象设计的终极目标。

其它几条,则能够看做是开闭原则的实现方法。
设计模式就是实现了这些原则,从而达到了代码复用、添加可维护性的目的。


1)"开-闭"原则( Open - ClosedPrinciple 缩写:OCP ):对扩展开放,对改动关闭


意思是,在一个系统中,对于扩展是开放的,对于改动是关闭的,一个好的系统是在不改动源码的情况下,能够扩展你的功能..而实现开闭原则的关键就是抽象化.

通过扩展已有软件系统,能够提供新的行为。以满足对软件的新的需求,使变化中的软件有一定的适应性和灵活性。已有软件模块。特别是最重要的抽象层模块不能再改动,这使变化中的软件系统有一定的稳定性和延续性。
在"开-闭"原则中,不同意改动的是抽象的类或者接口,同意扩展的是详细的实现类,抽象类和接口在"开-闭"原则中扮演着极其重要的角色..即要预知可能变化的需求.又预见全部可能已知的扩展..所以在这里"抽象化"是关键!!!

可变性的封闭原则:找到系统的可变因素,将它封装起来..这是对"开-闭"原则最好的实现..不要把你的可变因素放在多个类中,或者散落在程序的各个角落..你应该将可变的因素,封套起来..而且切忌不要把所用的可变因素封套在一起..最好的解决的方法是,分块封套你的可变因素!!避免超大类,超长类,超长方法的出现!!给你的程序添加艺术气息,将程序艺术化是我们的目标!!

2) 里氏代换原则:不论什么基类能够出现的地方,子类也能够出现


Liskov Substitution Principle(里氏代换原则):子类能够必须能够替换基类能够从出现的地方。子类也能在基类 的基础上新增行为。

这yi讲的是基类和子类的关系,仅仅有这种关系存在时,里氏代换原则才存在。正方形是长方形是理解里氏代换原则的经典样例。



3) 依赖倒转原则::要依赖抽象,而不要依赖详细的实现.


依赖倒置(Dependence Inversion Principle)原则讲的是:要依赖于抽象,不要依赖于详细。简单的说。依赖倒置原则要求client依赖于抽象耦合。原则表述:
(1)抽象不应当依赖于细节。细节应当依赖于抽象。
(2)要针对接口编程,不针对实现编程。


假设说开闭原则是目标,依赖倒转原则是到达"开闭"原则的手段..假设要达到最好的"开闭"原则,就要尽量的遵守依赖倒转原则..能够说依赖倒转原则是对"抽象化"的最好规范!!我个人感觉,依赖倒转原则也是里氏代换原则的补充..你理解了里氏代换原则,再来理解依赖倒转原则应该是非常easy的..


4)合成/聚合复用原则(CARP):要尽量使用合成/聚合原则,而不是继承关系达到软件复用的目的


合成/聚合复用原则(Composite/Aggregate ReusePrinciple或CARP)常常又叫做合成复用原则(Composite ReusePrinciple或CRP),就是在一个新的对象里面使用一些已有的对象。使之成为新对象的一部分;新对象通过向这些对象的委派达到复用已有功能的目的。

简而言之,要尽量使用合成/聚合。尽量不要使用继承。
要尽量使用合成/聚合原则,而不是继承关系达到软件复用的目的。此原则和里氏代换原则氏相辅相成的,两者都是详细实现"开-闭"原则的规范..违反这一原则:就无法实现"开-闭"原则..先来看看什么是合成,什么是聚合.


什么是合成?
合成:是指一个总体对依托他而存在的关系,比如:一个人对他的房子和家具,当中他的房子和家具是不能被共享的,由于那些东西都是他自己的..而且人没了,这个也关系就没了..这个样例就好像,乌鸡百凤丸这个产品,它是有乌鸡和上等药材合成而来的一样..也比方网络游戏中的武器装备合成一样,多种东西合并为一种超强的东西一样..

什么是聚合?

聚合:聚合是比合成关系的一种更强的依赖关系,聚合是一个总体对个体的部分,比如,一个奔驰S360汽车,对奔驰S360引擎,奔驰S360轮胎的关系..这些关系就是带有聚合性质的..由于奔驰S360引擎和奔驰S360轮胎他们仅仅能被奔驰S360汽车所用,离开了奔驰S360汽车,它们就失去了存在的意义..在我们的设计中,这种关系不应该频繁出现..这样会增大设计的耦合度..


明确了合成和聚合关系,再来理解合成/聚合原则应该就清楚了..要避免在系统设计中出现,一个类的继承层次超过3次..假设这种话,能够考虑重构你的代码,或者又一次设计结构..当然最好的办法就是考虑使用合成/聚合原则...

5)迪米特法则:系统中的类,尽量不要与其它类互相作用,降低类之间的耦合度


迪米特法则(Law of Demeter或简写LoD)又叫最少知识原则(Least Knowledge Principle或简写为LKP),也就是说。一个对象应当对其它对象有尽可能少的了解。
其它表述:仅仅与你直接的朋友们通信。不要跟"陌生人"说话。

一个类应该对自己须要耦合或调用的类知道得最少,你(被耦合或调用的类)的内部是怎样复杂都和我没关系,那是你的事情,我就知道你提供的public方法,我就调用这么多,其它的一概不关心。


迪米特法则与设计模式Facade模式、Mediator模式使民无知
系统中的类,尽量不要与其它类互相作用,降低类之间的耦合度,由于在你的系统中,扩展的时候,你可能须要改动这些类,而类与类之间的关系,决定了改动的复杂度,相互作用越多,则改动难度就越大,反之,假设相互作用的越小,则改动起来的难度就越小..比如A类依赖B类,则B类依赖C类,当你在改动A类的时候,你要考虑B类是否会受到影响,而B类的影响是否又会影响到C类..假设此时C类再依赖D类的话,呵呵,我想这种改动有的受了..

6)接口隔离法则:这个法则与迪米特法则是相通的


接口隔离原则(Interface Segregation Principle)讲的是:使用多个专门的接口比使用单一的总接口总要好。

换而言之,从一个客户类的角度来讲:一个类对另外一个类的依赖性应当是建立在最小接口上的。
过于臃肿的接口是对接口的污染。不应该强迫客户依赖于它们不用的方法。
迪米特法则是目的,而接口隔离法则是对迪米特法则的规范..为了做到尽可能小的耦合性,我们须要使用接口来规范类,用接口来约束类.要达到迪米特法则的要求,最好就是实现接口隔离法则,实现接口隔离法则,你也就满足了迪米特法则...



四。分类

设计模式分为三种类型,共23种。

  • 创建型模式:单例模式、抽象工厂模式、建造者模式、工厂模式、原型模式。
  • 结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。

  • 行为型模式:模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、职责链模式、訪问者模式。
按字典序排列简单介绍例如以下。


  • Abstract Factory(抽象工厂模式):提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们详细的类。
  • Adapter(适配器模式):将一个类的接口转换成客户希望的另外一个接口。

    Adapter模式使得原本由于接口不兼容而不能一起工作的那些类能够一起工作。

  • Bridge(桥接模式):将抽象部分与它的实现部分分离,使它们都能够独立地变化。
  • Builder(建造者模式):将一个复杂对象的构建与它的表示分离,使得相同的构建过程能够创建不同的表示。
  • Chain of Responsibility(职责链模式):为解除请求的发送者和接收者之间耦合,而使多个对象都有机会处理这个请求。

    将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它。

  • Command(命令模式):将一个请求封装为一个对象,从而使你可用不同的请求对客户进行參数化;对请求排队或记录请求日志。以及支持可取消的操作。

  • Composite(组合模式):将对象组合成树形结构以表示“部分-总体”的层次结构。它使得客户对单个对象和复合对象的使用具有一致性。
  • Decorator(装饰模式):动态地给一个对象加入一些额外的职责。

    就扩展功能而言。 它比生成子类方式更为灵活。

  • Facade(外观模式):为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加easy使用。
  • Factory Method(工厂模式):定义一个用于创建对象的接口。让子类决定将哪一个类实例化。

    Factory Method使一个类的实例化延迟到其子类。

  • Flyweight(享元模式):运用共享技术有效地支持大量细粒度的对象。

  • Interpreter(解析器模式):给定一个语言, 定义它的文法的一种表示,并定义一个解释器, 该解释器使用该表示来解释语言中的句子。
  • Iterator(迭代器模式):提供一种方法顺序訪问一个聚合对象中各个元素,而又不需暴露该对象的内部表示。
  • Mediator(中介模式):用一个中介对象来封装一系列的对象交互。

    中介者使各对象不须要显式地相互引用,从而使其耦合松散。而且能够独立地改变它们之间的交互。

  • Memento(备忘录模式):在不破坏封装性的前提下。捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到保存的状态。

  • Observer(观察者模式):定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,全部依赖于它的对象都得到通知并自己主动刷新。
  • Prototype(原型模式):用原型实例指定创建对象的种类。而且通过拷贝这个原型来创建新的对象。
  • Proxy(代理模式):为其它对象提供一个代理以控制对这个对象的訪问。

  • Singleton(单例模式):保证一个类仅有一个实例,并提供一个訪问它的全局訪问点。 单例模式是最简单的设计模式之中的一个。可是对于Java的开发人员来说,它却有非常多缺陷。在九月的专栏中,David Geary探讨了单例模式以及在面对多线程(multi-threading)、类装载器(class loaders)和序列化(serialization)时怎样处理这些缺陷。
  • State(状态模式):同意一个对象在其内部状态改变时改变它的行为。

    对象看起来似乎改动了它所属的类。

  • Strategy(策略模式):定义一系列的算法,把它们一个个封装起来, 而且使它们可相互替换。本模式使得算法的变化可独立于使用它的客户。
  • Template Method(模板方法模式):定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。

    Template Method使得子类能够不改变一个算法的结构就可以重定义该算法的某些特定步骤。

  • Visitor(訪问者模式):表示一个作用于某对象结构中的各元素的操作。它使你能够在不改变各元素的类的前提下定义作用于这些元素的新操作。



尽管这篇文章看起来比較头大, 都是文字。

但它确实是学习设计模式须要了解的一些的。

当然, 我这里的资料也是从网上copy来的。 摘录了一些我认为有必要了解的。

对于这些知识, 看着理解就好了。


学习的路上, 与君共勉

原文地址:https://www.cnblogs.com/mfmdaoyou/p/7210350.html