常见设计模式(一)

常见设计模式(一)

前言

什么是设计模式,设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。是软件开发人员在软件开发过程中面临的一般问题的解决方案。 本文主要讲解责任链桥接适配器单例命令模式这几种常见的设计模式。

  • 简单了解一下设计模式的分类,总体来说设计模式分为三大类:
    • 创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
    • 结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
    • 行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

遵从六大设计原则

  • 单一职责原则:
    • 一个类只负责一件事
    • (如UiVIew和CALayer)
  • 开闭原则:
    • 对修改关闭、对扩展开放
    • (如对一个类的定义,尽量考虑后期扩展性)
  • 接口隔离原则:
    • 使用多个专门的协议,而不是一个庞大臃肿的协议
    • 协议中的方法应当尽量少
    • (如UITableView,系统提供了UITableViewDataSource,UITableViewDelegate多个协议)
  • 依赖倒置原则:
    • 抽象不应该依赖于具体实现,具体实现可以依赖于抽象
    • (比如我们在定义数据访问的一些接口方法时候,所有上层业务的调用都应有依赖于我们这些抽象的接口,具体的存储方案,上层业务是感觉不到的)
  • 里氏替换原则:
    • 父类可以被子类无缝替换,且原有功能不受任何影响
    • (实际我们KVO机制,就运用了里氏替换原则)
  • 迪米特法则:
    • 一个对象应当对其他对象有尽可能少的了解
    • 高内聚、低耦合

责任链模式(Responder)

  • 含义:避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。职责链模式是一种对象行为型模式。
    • 用通俗的话就是推卸责任某件事,我们去解决,找到A,结果A踢皮球,说这不关我的事,去找B解决,然后我们就去找B,结果B也说,这跟我没关系,快去找C,就这样,我们就被踢来踢去,这就是责任链模式的思想。
  • 类构成:一个类有一个成员变量,成员变量的类型和原有的类是一样的;

  • 使用场景:一个关于需求变更的问题,比如业务之间的调用顺序的变换。
    • 使用责任链模式
    • Buiness C–>Buiness B–>Buiness A–>nil;动态更改下个执行业务

桥接模式(Bridge)

  • 含义:将抽象部分与它的实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interface)模式。

  • 类构成:一个抽象类A中有一个抽象类B的成员变量;具体子类继承自抽象类;

  • 使用场景:一个关于业务解耦的问题
    • 一个页面数据列表,随着业务的迭代,数据类型从网络数据B1—>网络数据B2—>网络数据B3。意思是列表数据发生了3次变化;但是这3种数据类型是需要并存的。

适配器(Adapter)

  • 含义:将一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。

  • 分为两种:

    • 对象适配器
    • 类适配器

我们讲解下对象适配器的实现

  • 类构成:一个适配对象存在一个成员变量是原有的类;

  • 比如说:
- (void)request 
{
	// 适配逻辑
	[被适配对象 某方法];
	// 适配逻辑
}
  • 使用场景:一个现有类需要适应变化的问题
    • 如某个业务文件在很久之前就产生了,经过需求的快速或者长期迭代,这个文件并未修改过,相对成熟稳定,如果我们对文件做成员变量或方法的修改,这样会加大出错的风险。

单例模式(Singleton)

  • 含义:

  • 具体实现如下:注意重写实例生成方法

@implementation Mook

+ (id)sharedInstance
{
    // 静态局部变量
    static Mook *instance = nil;
    
    // 通过dispatch_once方式,确保instance在多线程环境下只被创建一次
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        // 创造实例;因为重写了allocWithZone方法,若使用self调用,则第一次创建对象时,会造成死循环
        instance = [[super allocWithZone:NULL] init];
    });
    return instance;
}


// 重写方法【必不可少】
+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
    return [self sharedInstance];
}

// 重写方法【必不可少】
- (id)copyWithZone:(NSZone *)zone
{
    return self;
}

@end

命令模式(Command)

  • 含义:将一个请求封装为一个对象,从而使我们可以使用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。

  • 作用:
    • 降低代码重合度
  • 类构成:存在命令管理者命令抽象类;命令抽象类存在执行、取消,完成,完成回调等

  • 使用场景:行为参数化;
    • 如新浪微博,在很多页面,都存在点赞、评论、转发功能;如果不是呀命令设计模式的话,那么在不同的页面就需要单独实现这些逻辑。

设计模式总结

  • 请手写单例实现。(注意使用super创建对象)

  • 你都知道哪些设计原则,请谈谈你的理解。(六大设计原则)

  • 能否用一幅图简单的表示桥接模式的主体结构。(两个抽象类)

  • UI事件传递机制是怎样实现的?你对其中运用到的设计模式是怎样理解的?(责任链模式)

    • (事件的传递和响应的区别: 事件的传递是从父控件到子控件的, 事件的响应是顺着响应者链向上传递,从子控件到父控件)

参考文章

最后

如果对大家有帮助,请github上follow和star,本文发布在戴超的技术博客,转载请注明出处

Loading Disqus comments...
Table of Contents