设计模式记录(oc编程之道笔记)

对象创建

原型模式

【原型模式】使用原型实例指定创建对象的种类,并通过复制这个原型创建新的对象。

基本思想如同使用印章在纸上印出许多相同的内容,印章相当于原型,用同一模具生产一系列的产品就是复制过程

类图
在这里插入图片描述
何时使用
在这里插入图片描述
NSObject的派生类可以通过NSCopying协议及其(id)copyWithZone:(NSZone *)zone实现对象的深复制,NSObject提供的copy方法默认调用[self copyWithZone:nil]

工厂方法模式

【工厂方法模式】定义创建对象的接口,让子类决定实例化哪一个类。工厂方法使得一个类的实例化延迟到其子类

基本思想就如同真实的工厂一样当我们让工厂生产什么产品只需下达一个生产某产品的消息,工厂就会生产对应的产品
工厂方法也被称为虚构造器,它适用于当一个类无法预期需要生成哪个类的对象,想让其子类来指定所生成的对象

类图
在这里插入图片描述

何时使用
在这里插入图片描述

抽象工厂模式

【抽象工厂模式】提供一个创建一系列相关或相互依赖对象的接口,而无需制定它们的具体类

工厂模式和抽象工厂模式的区别
在这里插入图片描述

类图
在这里插入图片描述

抽象方法常见于cocoa touch框架,其NSNumber创建实例完全符合抽象工厂模式,例如[NSNumber numberWithBool: YES] 返回的实例是NSCFBoolean的实例,其中NSCFBoolean就是具体工厂,而NSNumber是抽象工厂

生成器模式

【生成器模式】将一个复杂对象的构建与它的表现分离,使得同样的构造过程可以创建不同的表现

基本思想当进行复杂对象构建时,比如造房子,客户告诉承包商房子的需求,然后承包商再调度各方的建筑商进行搭建,整个构建过程就形成客户(client)-指导者(director)-生成器(builder),使得过程建筑更容易管理和复用
工厂方法也被称为虚构造器,它适用于当一个类无法预期需要生成哪个类的对象,想让其子类来指定所生成的对象

类图时序图

在这里插入图片描述

何时使用
在这里插入图片描述

在这里插入图片描述

生成器模式主要是拆分了what和how,指导者可以将同一个what应用到不同的builder中完成how对处理, 例如当director要处理很多中情况时,若没有builder而是直接将逻辑写在director中将会造成一个庞大的‘神’类并带有无数与某种情况相关的内嵌算法

单例模式

【单例模式】保证类仅有一个实例,并提供一个访问它的全局访问点

类图
在这里插入图片描述

单例模式看起来很容易,实际上理解和使用起来确实很容易,应用频率上也比较高,但在oc中使用单例需要考虑几个细节点,同是要注意线程安全问题

@implementation Singleton
static Singleton *sharedInstance = nil;
+ (Singleton *)sharedInstance 
{
	if (sharedInstance == nil) {
		sharedInstance = [NSAllocateObject([self class], 0, NULL) init];
		// sharedInstance = [[super allocWithZone: NULL] init];
		// 采用第一中方式而不是第二种方式可以避免在子类话单例时创建出Singleton点对象
	}
}

+(id) allocWithZone:(NSZone *)zone { // 避免创建新对象分配新空间
	return [[self sharedInstance] retain];
}

-(id) copyWithZone:(NSZone *)zone { // 避免被copy出一个新对象
	return self;
}

-(id)retain {
	return self;
}

-(NSUInteger) retainCount {
	return NSUIntegerMax; // 表示不能释放对象
}
-(void) release {//什么也不做}
-(void) autorelease {return self;}

在上面的代码中可以看到创建单例对象用的是super而不是self,这是因为self中已经重载了allocWithZone,所以需要借用父类的方法进行底层的空间分配任务。

copy方法默认调用[copyWithZone:NULL]而创建对象时的alloc默认调用[allocWithZone: NULL]

当单例模式由多个线程访问时,需要关注现场安全问题,需要在sharedInstance静态实例的nil检查周围加入@synchronized()或NSLock实例,也可将其声明为atomic

接口适配

适配或结合带有不同接口的对象

适配器模式

【适配器模式】将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由子接口不兼容而不能一起观察的那些类可以一起工作

基本思想适配器模式又称包装器模式,类似电源插座,通过转换器将三角插座转为二角插座,而转换器就相当于适配器

类图
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

何时使用
在这里插入图片描述

oc中的delegate就是一种适配器模式,相关理解杂记

桥接模式

【桥接模式】将抽象部分与它的实现部分分离,使它们都可以相对独立的变化

基本思想将抽象层次结构从其实现中分离出来,抽象层定义了供客户端使用的上层的抽象接口,实现层次结构定义类供抽象层次使用的底层接口,实现类的引用被封装于抽象层的实例中,形成了桥接

类图
在这里插入图片描述

何时使用
在这里插入图片描述

外观模式

【外观模式】为系统中的一组接口提供一个统一的接口,外观定义一个高度接口,让子系统更容易使用

结构图
在这里插入图片描述

何时使用
在这里插入图片描述

例子
乘客乘坐出租车出行,其中涉及出租车打开关闭里程器,起步打方向盘等各种操作,利用外观模式可以将这些都封到一个壳子中,类似给一个汽车套上一个车壳,那么外部的使用者将不用在意其内部有多少复杂的操作
在这里插入图片描述

有些设计模式看起来很相似,特别是比如给客户端统一接口,内部再进行变更什么的,虽然实现上类似不过这种属于从技术编码角度来看,但本质上他们的区别应该在于其使用背景和目的吧,像桥接模式统一抽象上层,自由组装具体下层本质上是为了一对一多,万能遥控器那种;外观看起来也是留了个通用的接口给客户端但其本质在于一个复杂系统功能组合后进行套壳子留下一个统一接口便于使用,两个的使用对象和目的不同,不过手段上其实也类似,这两还好,不过后面的中介者模式就更就和某些模型越来越像了,估计主要还是使用对象和场景实现目标的不同【个人理解】

对象去耦

中介者模式

【中介者模式】用一个对象来封装一系列对象的交互方式。中介者使个对象不需要显示的相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互

类图
在这里插入图片描述

中介者模式避免了对象间复杂的引用关系,使其之间的耦合关系松散
在这里插入图片描述

何时使用
在这里插入图片描述

虽然通过中介者模式可以减少不同对象间的依存关系,当也应当避免让中介者类过于类过于庞大而难以维护,当中介者类过于庞大时应当考虑另一种设计模式将它分解,每个设计模式就像一个乐高积木,整个应用的设计搭建可能要使用不同的积木块进行构造

观察者模式

观察者模式也称"发布-订阅模式",发布者通过通知器注册特定的通知,当有通知时,观察者只能从通知器中得到订阅模型

【观察者模式】:定义对象间的一种一对多依赖关系,当一个对象的状态发生改变时,所以依赖于它的对象都得到通知并被自动更新

oc中的广播机制就属于观察者模式

/// 发送方
//  通知对象
NSNotification *notification = [NSNotification notificationWithName:@"notifiyName" object: nil];
// 通知中心
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
//发送通知
[notificationCenter postNotification: notification];

/// 接收方
// 订阅通知
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter addObserver:self selector:@selector(myfunc:) name:@"notifiyName" object: nil];

/// 其中发生方定义的NSNotification对象时若制定了object对象,则接收方注册时的object对象若不是和发送方发生的通知有相同的object则不会收到该通知,若制定object为nil则对发送方而言该通知发给所以对象,对接收方而言将会接受所有没有指定对象的通知

另外oc也提供了键-值观察基于NSKeyValueObserving协议

何时使用
在这里插入图片描述

抽象集合

组合模式

【组合模式】:将对象组合成成树形结构以表示"部分-整体"的层次结构。组合使得用户对单个对象和组合对象的使用具有一致性

基本思想组合模式让我们可以把相同基类型的对象组合到树状结构中,其中的父节点包含同类型的子节点,组合模式主要时强调部分-整体的递归关系中,因为处理的是部分-总体关系,则对象抽象出一个共同的基类使得客户端在进行操作是可以忽略它们的区别,其主要意图是让树形结构中的每个节点具有相同的抽象接口。这样整个结构课作为一个统一的抽象结构使用,而不暴露器内部的表示

类图
在这里插入图片描述

何时使用
在这里插入图片描述

迭代器

【迭代器模式】:提供一种方法顺序访问一个聚合对象中的各个元素,而又不需暴露该对象的内部表示

在面向对象软件中,针对抽象集合迭代行为的设计模式叫做迭代器,迭代器提供了一种顺序访问聚合对象中元素的方法,而无需暴露结构的底层表示和细节,遍历结婚中元素的职能从集合本身转移到迭代器对象

类图
在这里插入图片描述

迭代器又分外部迭代器和内部迭代器两种
在这里插入图片描述

何时使用
在这里插入图片描述

cocoa框架中的枚举器/枚举就是类似于迭代器模式,NSEnumerator

行为扩展

访问者模式

【访问者模式】:表示一个作用于某对象结构中的各元素的操作。它让我们可以在不改变各元素的类的前提下定义作用于这些元素的新操作

例子🌰:
当你家水管坏了,你无需去学习修水管的技术(向类中添加新方法),只需叫来管道修理工(访问者),他来了后你放他进来修水管(接受),然后他就会进来修水管(访问水管对象),在这整个过程中都没有对现有的你或是水管这两类进行修改,而是通过一个访问者来定义作用于这些元素的新操作

  • [访问者模式和装饰者模式有什么区别?]

访问者模式中主要涉及两个关键角色:访问者和他访问的元素
类图
在这里插入图片描述

何时使用在这里插入图片描述

访问者模式有个需要注意的缺点,那就是访问者和目标类耦合在一起。因此,如果访问者需要支持新的类,访问者的父类和子类都需要修改,才能反映新的功能

装饰模式

【装饰模式】:动态的给一个对象添加一些额外的职责。就扩展功能来说,装饰模式比生成子类更加灵活

类图
在这里插入图片描述

何时使用
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

oc中的范畴(catalog) 在意图上实现了装饰模式,但这不是一种严格的实现,算是一种变体。有装饰器范畴添加的行为是编译器绑定的,虽然oc一般支持动态绑定。而且装饰器范畴实际上没有封装被扩展的类的实例,但使用范畴更加轻量

责任链模式

【责任链模式】:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间发生耦合。此模式将一些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止

主要思想对象引用了同一类型的另一个对象,形成一条链。链中的每个对象实现了同样的方法,处理对链中的第一个对象发起的同一个请求,如果那个对象不知道如何处理请求就把请求传递给下一个响应者

类图
在这里插入图片描述

何时使用
在这里插入图片描述

在这里插入图片描述

算法封装

模版方法

【模版方法模式】定义一个操作中算法的骨架,而将一些步骤延迟到子类中。模版方法使子类可以重定义算法的某些特定步骤而不改变该算法的结构。

基本思想在抽象类的一个方法中定义“标准”算法,在这个方法中调用的基本操作应由子类重载予以实现

类图
在这里插入图片描述

何时使用模版方法
在这里插入图片描述

例:
做一个三明治需要的步骤

  1. 准备面包
  2. 把面包放盘子上
  3. 往面包加肉
  4. 加调味料
  5. 上餐
    在这里插入图片描述

子类可以继承并重定义准备面包,放肉等操作,最后调用[super make]制作三明治,其中make方法就是模版方法


模版方法和委托(适配器模式)的区别
在这里插入图片描述

oc中没有属性可以要求子类必须重载,在但模版方法中有些必要部分是需要子类实现对应的方法,如三明治例子中的prebread这些方法,解决这个问题可以在父类的默认实现中抛出nsexception
非必要部分属于子类可拓展父类的钩子方法可以不实现

策略

【策略模式】定义一系列算法,把它们一个个封装起来,并且使它们可相互替换。本模式是的算法可独立于使用它的客户而变化

基本思想当有大量的if-else或switch结构时可以将相关算法分离为不同的类,成为策略

类图
在这里插入图片描述

在这里插入图片描述

何时使用策略模式
在这里插入图片描述

举个🌰
用UITextField针对不同输入类型进行检查时,用if-else时
在这里插入图片描述

ifelse可能会延伸很长
用策略模式方案
在这里插入图片描述

装饰器模式从外部扩展对象的行为,而各种策略则被封装在对象内容内部

命令模式

【命令模式】将请求封装为一个对象,从而可用不同的请求对客户端进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作

基本思想命令对象封装了如何对目标执行指令的信息,因此客户端或调用者不必了解目标的任何细节,却仍可以对它执行任何已有的操作

类图
在这里插入图片描述

何时使用
在这里插入图片描述

cocoa框架中现有的命令模式,NSInvocationNSUndoManager

性能与对象访问

享元模式

【享元模式】运用共享技术有效地支持大量细粒度的对象

基本思想将被大量创建重用的对象福利处公共部分形成一个共享实例,而将某些对象的独特状态拿到外部在别处管理,其中共享实例就是享元

类图
在这里插入图片描述

在这里插入图片描述

实现享元模式的两个关键组件通常是可共享的享元对象和保护他们的池。某种中央对象维护这个池,并从它返回适当的实例(工厂就很理想)

使用享元最重要的原因在于通过共享能节省处内存空间,在某些需要持有大数量级的应用中可以使用其提升整体性能

何时使用
在这里插入图片描述

代理模式

【代理模式】为其他对象提供一种代理以控制对这个对象的访问

代理种类:

  • 远程代理:为位于不同地址空间或网络上的对象提供本地代表
  • 虚拟代理:根据需要创建重型对象
  • 保护代理:根据各种访问权限控制对原对象的访问
  • 智能引用代理:通过对真正对象的引用进行计数来管理内存。也用于锁定真正对象,让其他对象不能对其进行修改

基本思想使用一个基本上和实体对象行为相同的代理,客户端可以透明的使用代理,即不必知悉所面对的只是一个代理而不是实体对象

类图
在这里插入图片描述

何时使用
在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值