装饰模式是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。

比如游戏机有一个GamePad类, 现在要增加一个作弊功能(例如100条命), 如果直接在GamePad类中去添加可能会影响其他子类的使用

我们考虑装饰模式思维, 先建立一个装饰器实现GamePad的所有功能, 然后在装饰器类的子类中去添加作弊放方法

上代码

比如GamePad类是这样

 #import <Foundation/Foundation.h>

 @interface GamePad : NSObject

 - (void)up;
- (void)down;
- (void)left;
- (void)right;
- (void)buttonA;
- (void)buttonB; @end

我们创建一个装饰器类, 让它持有一个GamePad实例并实现相同的方法接口

GamePadDecorator.h

 #import <Foundation/Foundation.h>
#import "GamePad.h" @interface GamePadDecorator : NSObject - (void)up;
- (void)down;
- (void)left;
- (void)right;
- (void)buttonA;
- (void)buttonB; @end

GamePadDecorator.m

 #import "GamePadDecorator.h"

 @interface GamePadDecorator ()

 @property (nonatomic, strong) GamePad *gamePad;

 @end

 @implementation GamePadDecorator

 - (instancetype)init {
self = [super init];
if (self) {
self.gamePad = [[GamePad alloc] init];
}
return self;
} - (void)up {
[self.gamePad up];
} - (void)down {
[self.gamePad down];
} - (void)left {
[self.gamePad left];
} - (void)right {
[self.gamePad right];
} - (void)buttonA {
[self.gamePad buttonA];
} - (void)buttonB {
[self.gamePad buttonB];
} @end

现在我们新增一个子类来实现作弊方法

CheatGamePadDecorator.h

 #import "GamePadDecorator.h"

 @interface CheatGamePadDecorator : GamePadDecorator

 - (void)cheat;

 @end

CheatGamePadDecorator.m

 #import "CheatGamePadDecorator.h"

 @implementation CheatGamePadDecorator

 - (void)cheat {
NSLog(@"cheat");
} @end

这样我们就可以直接在Controller中直接用CheatGamePadDecorator类去实现GamePad的所有功能还能额外实现作弊方法

 #import "ViewController.h"
#import "CheatGamePadDecorator.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad]; //创建CheatGamePadDecorator实例
CheatGamePadDecorator *cheaterGamePad = [[CheatGamePadDecorator alloc] init]; //实现GamePad的功能
[cheaterGamePad up];
[cheaterGamePad down]; //实现作弊方法
[cheaterGamePad cheat];
} @end

这样就完成了一个装饰模式思路的代码构建

下面说说cocoa touch中自带的Category, 它也是对装饰模式的一个实现

我们用Category来实现上面GamePad添加作弊功能

我们创建一个Cheat Category

GamePad+Cheat.h

 #import "GamePad.h"

 @interface GamePad (Cheat)

 - (void)cheat;

 @end

GamePad+Cheat.m

 #import "GamePad+Cheat.h"

 @implementation GamePad (Cheat)

 - (void)cheat {
NSLog(@"cheat");
} @end

这样我们就可以直接在Controller中通过Category来实现上面功能

 #import "ViewController.h"
#import "GamePad+Cheat.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad]; //创建GamePad实例
GamePad *gamePad = [[GamePad alloc] init]; //实现GamePad原有方法
[gamePad up];
[gamePad down]; //实现作弊方法
[gamePad cheat]; }

使用Category更为简单

但是在使用Category时有个细节一定要注意, 尽量不要在Category类中去重写基类方法

假如我们在GamePad+Cheat.h中重写了- (void)up方法, 则整个工程中的up方法都被重载了

即使我们不在任何地方引用GamePad+Cheat.h, 只要这个文件在工程里面就会让GamePad方法被重载

Objective-C 装饰模式--简单介绍和使用的更多相关文章

  1. Java EE设计模式(主要简单介绍工厂模式,适配器模式和模板方法模式)

    Java EE设计模式分为三种类型,共23种: 创建型模式:单例模式.抽象工厂模式.建造者模式.工厂模式.原型模式. 结构型模式:适配器模式.桥接模式.装饰模式.组合模式.外观模式.享元模式.代理模式 ...

  2. 嵌入式Linux下MP4视频录制库MP4V2移植和简单介绍

    **************************************************************************************************** ...

  3. dubbo学习过程、使用经验分享及实现原理简单介绍

    一.前言 部门去年年中开始各种改造,第一步是模块服务化,这边初选dubbo试用在一些非重要模块上,慢慢引入到一些稍微重要的功能上,半年时间,学习过程及线上使用遇到的些问题在此总结下. 整理这篇文章差不 ...

  4. 【Dubbo基础】dubbo学习过程、使用经验分享及实现原理简单介绍

    一.前言 部门去年年中开始各种改造,第一步是模块服务化,这边初选dubbo试用在一些非重要模块上,慢慢引入到一些稍微重要的功能上,半年时间,学习过程及线上使用遇到的些问题在此总结下. 整理这篇文章差不 ...

  5. [原创]关于mybatis中一级缓存和二级缓存的简单介绍

    关于mybatis中一级缓存和二级缓存的简单介绍 mybatis的一级缓存: MyBatis会在表示会话的SqlSession对象中建立一个简单的缓存,将每次查询到的结果结果缓存起来,当下次查询的时候 ...

  6. 利用Python进行数据分析(7) pandas基础: Series和DataFrame的简单介绍

    一.pandas 是什么 pandas 是基于 NumPy 的一个 Python 数据分析包,主要目的是为了数据分析.它提供了大量高级的数据结构和对数据处理的方法. pandas 有两个主要的数据结构 ...

  7. 利用Python进行数据分析(4) NumPy基础: ndarray简单介绍

    一.NumPy 是什么 NumPy 是 Python 科学计算的基础包,它专为进行严格的数字处理而产生.在之前的随笔里已有更加详细的介绍,这里不再赘述. 利用 Python 进行数据分析(一)简单介绍 ...

  8. yii2的权限管理系统RBAC简单介绍

    这里有几个概念 权限: 指用户是否可以执行哪些操作,如:编辑.发布.查看回帖 角色 比如:VIP用户组, 高级会员组,中级会员组,初级会员组 VIP用户组:发帖.回帖.删帖.浏览权限 高级会员组:发帖 ...

  9. angular1.x的简单介绍(二)

    首先还是要强调一下DI,DI(Denpendency Injection)伸手获得,主要解决模块间的耦合关系.那么模块是又什么组成的呢?在我看来,模块的最小单位是类,多个类的组合就是模块.关于在根模块 ...

随机推荐

  1. Android 权限列表

    访问登记属性 android.permission.ACCESS_CHECKIN_PROPERTIES ,允许读写check-in数据库属性表的权限 ( Allows read/write acces ...

  2. CC countari & 分块+FFT

    题意: 求一个序列中顺序的长度为3的等差数列. SOL: 对于这种计数问题都是用个数的卷积来进行统计.然而对于这个题有顺序的限制,不好直接统计,于是竟然可以分块?惊为天人... 考虑分块以后的序列: ...

  3. grep 信息提取

    1.提取svn版本库的版本号 svn info |grep -Po '(?<=Revision: )[0-9]*'

  4. 对Hibernate的理解

    ---恢复内容开始--- 一.面向对象设计的软件内部运行过程可以理解成就是不断创建各种新对象,建立对象之间的关系,调用对象的方法来改变各个对象的状态和对象消亡的过程.不管程序运行的过程和操作怎么样,本 ...

  5. php清理当前目录下的指定文件和空目录(源码),建议服务器端执行

    <?php /** * @desc 解析当前目录并递归删除目录下的指定文件 * @author mengdj<mengdj@outlook.com> 2014.10.02 1530 ...

  6. (转)Vsdocman7.2 注册版

    Vsdocman是一个优秀的.NET源代码注释编写工具,方便的以GUI的方式设计.NET源代码的注释.我们只是大自然的搬运工:http://download.csdn.net/detail/iamyg ...

  7. Xamarin的不归路-生成安卓错误3

    错误提示: 解决方案:升级jdk到8即可. 2016年9月1日14:50

  8. backbone新手填坑教程资源

    backbone 入门第二版 http://www.kancloud.cn/kancloud/backbonejs-learning-note/49379 backbone 入门讲解 http://w ...

  9. Java 8 forEach简单例子

    1. forEach and Map 1.1 通常这样遍历一个Map Map<String, Integer> items = new HashMap<>(); items.p ...

  10. H5+Mui文件配置 vue-resource基本使用方法

    使用HBuilder空项目搭建h5原生开发框架需要的文件配置: *css:mui.min.css *fonts:mui.ttf mui-icon-extra.ttf *js:mui.js mui.mi ...