iOS设计模式之装饰者模式
一,什么是装饰模式
- 模式定义
装饰者包含被装饰者的所有接口和引用,方法实现完全是引用调用自己的方法,在装饰者子类添加新功能。
注释:
Category不要重写被装饰对象的方法,否则改变了被装饰对象的行为,不符合装饰者模式,只可适用特殊场景。分类主要用于对被装饰者类的方法和属性拓展
- 需求场景
静态库扩展功能。不改变(原始类)、不继承、动态扩展功能。
- 不知道原始类实现细节,只提供接口,动态扩展功能。
- 不想有更多子类,不想通过继承的方式添加功能。
- 动态扩展对象的功能。
- 必须持有对象的引用,包含实例化的被装饰类。
二,装饰模式结构图
实现方式:
- 定义装饰者类,并在.h定义被装饰者类中的所有暴漏到.h的方法(也可以添加自定义的操作方法)和对被装饰者类的引用。
- 在装饰者类用用被装饰者对象对其方法调用,已输出我们想要的结果。
- 如果想拓展被装饰者类,可通过分类的方法,这样可以不破坏被装饰者类原生逻辑。

三,代码示例
- Target(被装饰者类)
- Target.h
@interface Target : NSObject
/**
* 游戏币的数量
*/
@property(nonatomic,assign) NSInteger coin; /**
* 上下左右的操作
*/
- (void)up; - (void)down; - (void)left; - (void)right;
/**
* 选择与开始的操作
*/
- (void)select;
- (void)start;
/**
* 按钮 A + B 的操作
*/
- (void)commandA;
- (void)commandB;
@end - Target.m
@implementation Target - (void)up{
NSLog(@"up");
} - (void)down{
NSLog(@"down");
} - (void)left{
NSLog(@"left");
} - (void)right{
NSLog(@"right");
} - (void)select { NSLog(@"select");
} - (void)start { NSLog(@"start");
} - (void)commandA { NSLog(@"commandA");
} - (void)commandB { NSLog(@"commandB");
} @end
- Target.h
- Decorator(装饰者类)
- Decorator.h
#import <Foundation/Foundation.h> NS_ASSUME_NONNULL_BEGIN @interface Decorator : NSObject #pragma mark --被装饰者类方法 @property (nonatomic) NSInteger coin; - (void)up;
- (void)down;
- (void)left;
- (void)right;
- (void)select;
- (void)start;
- (void)commandA;
- (void)commandB; #pragma mark - 以下为装饰对象新添加的功能 /**
* 剩余几条命
*/
@property (nonatomic, readonly) NSInteger lives; /**
* 作弊 (上下上下左右左右ABAB)
*/
- (void)cheat; @end - Decorator.m
#import "Decorator.h"
#import "Target.h"
@interface Decorator() @property (nonatomic,strong) Target target; //持有被装饰者类对象 @end @implementation Decorator #pragma mark - 初始化 - (instancetype)init { if (self = [super init]) { // 装饰对象包含一个真实对象的引用
self.target = [Target new];
} return self;
} #pragma mark - 让真实对象的引用执行对应的方法 - (void)up { [_target up];
} - (void)down { [_target down];
} - (void)left { [_target left];
} - (void)right {
[_target right];
} - (void)select {
[_target select];
} - (void)start { [_target start];
} - (void)commandA { [_target commandA];
} - (void)commandB { [_target commandB];
} #pragma mark - 装饰器新添加的方法
- (void)cheat {
[_target up];
[_target down];
[_target up];
[_target down];
[_target left];
[_target right];
[_target left];
[_target right];
[_target commandA];
[_target commandB];
[_target commandA];
[_target commandB];
} @synthesize lives = _lives;
- (NSInteger)lives {
// 相关处理逻辑
return ;
} @end
- Decorator.h
四,装饰模式优缺点
- 优点
在不改变目标类业务逻辑的情况下,拓展原有的方法和功能
五,demo
装饰者模式
iOS设计模式之装饰者模式的更多相关文章
- Java 设计模式泛谈&装饰者模式和单例模式
设计模式(Design Pattern) 1.是一套被反复使用.多人知晓的,经过分类编目 的 代码设计经验总结.使用设计模式是为了可重用代码,让代码更容易维护以及扩展. 2.简单的讲:所谓模式就是得到 ...
- C#设计模式(9)——装饰者模式(Decorator Pattern)
一.引言 在软件开发中,我们经常想要对一类对象添加不同的功能,例如要给手机添加贴膜,手机挂件,手机外壳等,如果此时利用继承来实现的话,就需要定义无数的类,如StickerPhone(贴膜是手机类).A ...
- IOS设计模式之三:MVC模式
IOS设计模式之三:MVC模式 模型-视图-控制器 这个模式其实应该叫做MCV,用控制器把model与view隔开才对,也就是model与view互相不知道对方的存在,没有任何瓜葛,他们就像一个团 ...
- 设计模式之装饰者模式-java实例
设计模式之装饰者模式 需求场景 我们有了别人提供的产品,但是别人提供的产品对我们来说还不够完善,我们需要对这个产品的功能进行补强,此时可以考虑使用装饰者模式. 我们已经有了产品,而且这个产品的功能非常 ...
- iOS设计模式 - (3)简单工厂模式
iOS设计模式 - (3)简单工厂模式 by Colin丶 转载请注明出处: http://blog.csdn.net/hitwhylz/article/ ...
- Java设计模式 - - 单例模式 装饰者模式
Java设计模式 单例模式 装饰者模式 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 静态代理模式:https://www.cnblogs.com/StanleyBlogs/p/1 ...
- python 设计模式之装饰器模式 Decorator Pattern
#写在前面 已经有一个礼拜多没写博客了,因为沉醉在了<妙味>这部小说里,里面讲的是一个厨师苏秒的故事.现实中大部分人不会有她的天分.我喜欢她的性格:总是想着去解决问题,好像从来没有怨天尤人 ...
- PHP设计模式之装饰器模式(Decorator)
PHP设计模式之装饰器模式(Decorator) 装饰器模式 装饰器模式允许我们给一个类添加新的功能,而不改变其原有的结构.这种类型的类属于结构类,它是作为现有的类的一个包装 装饰器模式的应用场景 当 ...
- 实践GoF的23种设计模式:装饰者模式
摘要:装饰者模式通过组合的方式,提供了能够动态地给对象/模块扩展新功能的能力.理论上,只要没有限制,它可以一直把功能叠加下去,具有很高的灵活性. 本文分享自华为云社区<[Go实现]实践GoF的2 ...
随机推荐
- Linux_Bash常用脚本
目录 目录 从用户列表中过滤用户名并创建用户 awktrcut 指令的文本处理 tr指令 cut指令 awk指令 备份文件 测试LFTPServer权限设定 开启Httpd 安装Httpd 批量创建用 ...
- Shell中uname命令查看系统内核、版本
uname命令 描述 用于打印内核名称和版本.主机名等系统信息. 用法 uname [OPTION]... 参数 用法 -a print all information -s print th ...
- 使用定时器settimeout、setInterval执行能传递参数的函数
无论是window.setTimeout还是window.setInterval,在使用函数名作为调用句柄时都不能带参数,而在许多场合必须要带参数,这就需要想方法解决.经网上查询后整理如下: 例如对于 ...
- Jenkins持续集成_02_添加python项目&设置定时任务
前言 自动化测试脚本编写后,最终目的都是持续集.持续集成可以实现一天多次部署运行自动化脚本,对功能进行不断监控测试.由于小编使用python编写的自动化脚本,这里仅讲解下如何在Jenkins中添加py ...
- git团队协作代码提交步骤
我们公司由五个人同时开发一个项目,大佬建好仓库后叫我们统一提交到dev这个分支,我的分支是hardy,你们只要将这两个值改成你们团队协作中使用的分支即可.代码如下: git add . git com ...
- java.lang.NumberFormatException: For input string: "title"异常
java.lang.NumberFormatException: For input string: "title" at java.lang.NumberFormatExcept ...
- word中迅速将表格一分为二 拆分表格快捷键ctrl+shift+enter 重复上一个命令快捷键f4
这里说的是将一个表格拆分为两个表格 选择要拆分的行,快捷键ctrl+shift+enter,就拆分为两个表格了,是不是很快! 在多个表格需要拆分的时候,做一次这样的操作,然后不停的移动.F4,就可以了 ...
- 《剑指offer》面试题4 替换空格 Java版
(给一个足够长的字符数组,其中有一段字符,将' '(空格)替换成'%' '2' '0'三个字符,原字符段由'\0'结尾) 书中方法:这道题如果从头到尾扫描数组并替换,会涉及到数组的移动.如果不移动元素 ...
- java_第一年_JavaWeb(3)
ServletConfig对象 可以通过web.xml文件中的<init-param>标签来初始化参数,这些参数会在创建servlet实例时将其封装到ServletConfig对象中,并在 ...
- 观list.clear()方法 有感
一 . list.clear()底层源码实现 在使用list 结合的时候习惯了 list=null :在创建这样的方式,但是发现使用list的clear 方法很不错,尤其是有大量循环的时候 1.lis ...