iOS设计模式解析--开篇(一)

本文深入浅出地介绍了设计模式的概念及其在iOS开发中的应用。设计模式作为软件工程的基础,能够帮助开发者解决常见问题,提高代码质量。文章详细划分了设计模式的类型,并结合面向对象设计原则,探讨了如何在实践中灵活运用。

设计模式(Design Pattern)是一套代码设计思想的经验总结,它为各类常见场景下的问题提供了解决方案,它代表了软件设计的最佳实践。它最早是在GoF合著的《设计模式》一书中被提出的。书中阐述了23种经典的设计模式被视为现代软件工程的基石。

对于每一位开发人员来说,设计模式都是他们进阶路上必可少的修炼。在项目中合理地运用设计模式可以完美地解决很多问题,提高代码的复用性,扩展性,可维护性。尤其是当你在设计大型的程序,模块或框架,或者重构代码的时候,设计模式一定会对你有所帮助。

个人觉得,学习设计模式的核心在于理解每种模式适用的场景解决的问题。本文会以Cocoa(Touch)框架和经典开源库为例,围绕这两个核心来逐一讲解iOS中的设计模式。

设计模式的分类

  • 创建型模式(Creational)

    关注对象的创建。

    • 工厂方法模式(Factory Method Pattern)
    • 抽象工厂模式(Abstract Factory Pattern)
    • 单例模式(Singleton Pattern)
    • 建造者模式(Builder Pattern)
    • 原型模式(Prototype Pattern)
  • 结构型模式(Structural)

    通过对象的组合获得新的功能。

    • 适配器模式(Adapter Pattern)
    • 桥接模式(Bridge Pattern)
    • 组合模式(Composite Pattern)
    • 装饰器模式(Decorator Pattern)
    • 外观模式(Facade Pattern)
    • 享元模式(Flyweight Pattern)
    • 代理模式(Proxy Pattern)
  • 行为型模式(Behavioral)

    关注对象之间的通信。

    • 责任链模式(Chain of Responsibility Pattern)
    • 命令模式(Command Pattern)
    • 解释器模式(Interpreter Pattern)
    • 迭代器模式(Iterator Pattern)
    • 中介者模式(Mediator Pattern)
    • 备忘录模式(Memento Pattern)
    • 观察者模式(Observer Pattern)
    • 状态模式(State Pattern)
    • 策略模式(Strategy Pattern)
    • 模板模式(Template Pattern)
    • 访问者模式(Visitor Pattern)

面向对象设计原则

学习设计模式的各种设计方法之前我们首先需要了解面向对象程序设计的一些基本原则。设计模式的提出正是基于了这些原则,它为我们实现代码的高内聚和低耦合,为我们提高程序的扩展性和可维护性提供了基础。

  • 针对接口(协议)编程而不是针对实现编程

接口是抽象的,简洁的,相对稳定的;而实现是具体的,复杂的,相对多变的。更多的依赖不易变的接口,而不是易变的具体类,有助于提高代码的灵活性,同时减少代码的耦合。 接口常被用在以下情况:

  1. iOS开发中的各种delegate。
  2. 一组类实现各不相同,但是对外提供一样的方法。
  3. 模块或组件对外暴露方法。
  4. 设计模式中也有多种模式是面向接口的。

Swift的标准库完全是基于面向接口编程的思想而设计的,而且,Swift的protocol可以在条件扩展里给出方法的具体实现。

  • 优先使用对象组合而不是继承

继承虽然实现了代码的复用,但这种复用被称白箱复用(white-box reuse)。父类的内部实现暴露于子类,父类的改动会传导给子类,它们之间是强耦合的关系。

而对象组合可以只通过接口来访问对象,该对象的内部实现对包含它的对象是不可见的,这种复用被称为黑箱复用(black-box reuse)。对象通过简单的接口访问另一个对象,它们之间的依赖大大降低了,因为接口常常是不易改变的,而且实现接口的具体类还可以在运行时动态的替换,灵活性大大的提高了。

组合优先并不等于不用继承,而要根据具体的情况加以判断。事实上,设计合理的系统,组合和继承常常是相互配合出现的。

iOS中除了组合,有些情况下还可以用下列两种方式替代继承:

  1. 类别
  2. AOP面向切面编程(或Method Swizzling)

我们在设计代码的时候可以想一想,原本要写到基类里,通过继承复用的代码是否可以加到类别里或是通过AOP来做。如统计埋点通常可以用AOP来做。

六大设计原则

  • 开闭原则(Open Close Principle)

    指一个软件实体(类、模块或函数)应当对扩展开放,对修改关闭。也就是说软件实体应尽量在不修改原有代码的情况下进行扩展。要做到这点抽象是关键。依赖于接口或抽象基类的类通常是稳定的,较少修改的。扩展的部分交给具体的子类去实现。

  • 单一职责原则(Single Responsebility Principle)

    指一个类的职责应该是单一的。比如一个下载文件的类,通过URL生成MD5文件名的方法就不应该放在它里面。

  • 里氏替换原则(Liskov Substitution Principle)

    指任何基类可以出现的地方,子类一定可以出现。比如原来方法里传入的是NSArray,那么传入NSMutableArray,代码行为功能不会出现问题。这个原则要求我们子类不要破坏父类的逻辑,子类应该只用来增加新的逻辑。

  • 依赖倒置原则(Dependence Inversion Principle)

    指高层次的模块不应依赖于低层次的模块。具体来说就是针对接口编程,依赖于抽象而不依赖于具体。

  • 接口隔离原则(Interface Segregation Principle)

    指我们应该使用多个隔离的接口,来隐藏不需要的方法。比如iOS中ViewController常常实现多个类的代理,对这些类而言,它们不需要知道整个ViewController的方法,它们只需要知道各自代理的方法即可。

  • 最少知道原则(Demeter Principle)

    指一个实体应当尽量少地暴露信息给其他实体,减少耦合。把无需公开的属性和成员变量放在.m文件里,保持.h文件的整洁和最简就是一种好习惯。

UML中的类图

统一建模语言中的类图是描述设计模式的最佳方法。UML类图中定义了六种关系:

依赖

依赖关系可以理解为一个类使用了另一个类。比如参数,返回值或者方法中调用。

继承

继承关系是面向对象设计中最常见的关系。注意,类和类之间,接口和接口之间都可以继承。它是一种强耦合的关系。

实现

一个类可以实现多个接口。

关联

关联关系是一种强依赖关系,它不像依赖关系那样,两个类之间的联系是偶然的,临时的;关联关系的两个类之间一般是长期性的。比如上图中的老师和学生。代码上,关联关系通常表现为一个类是另一个类的属性或成员变量。

聚合

聚合关系是一种特殊的关联关系。它们之间的区别是关联关系的两个类通常是平等的;而聚合关系的两个类是整体和部分之间的拥有关系(has-a)。比如班级和学生。

组合

组合关系是一种比聚合关系更强的关系,它也成为强聚合。它体现的是一种包含关系(contains-a),整体和部分是密不可分的。它和聚合关系的区别是:聚合关系中的两个类有各自的生命周期,而组合关系中整体的生命周期结束,部分的生命周期也会结束。

继承和实现是两种纵向关系;其余的四种则是横向关系,它们之间关系的强弱依次为:组合>聚合>关联>依赖。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值