Objective-C 装饰模式--简单介绍和使用

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

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

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

上代码

比如GamePad类是这样

 1 #import <Foundation/Foundation.h>
 2
 3 @interface GamePad : NSObject
 4
 5 - (void)up;
 6 - (void)down;
 7 - (void)left;
 8 - (void)right;
 9 - (void)buttonA;
10 - (void)buttonB;
11
12 @end

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

GamePadDecorator.h

 1 #import <Foundation/Foundation.h>
 2 #import "GamePad.h"
 3
 4 @interface GamePadDecorator : NSObject
 5
 6 - (void)up;
 7 - (void)down;
 8 - (void)left;
 9 - (void)right;
10 - (void)buttonA;
11 - (void)buttonB;
12
13 @end

GamePadDecorator.m

 1 #import "GamePadDecorator.h"
 2
 3 @interface GamePadDecorator ()
 4
 5 @property (nonatomic, strong) GamePad *gamePad;
 6
 7 @end
 8
 9 @implementation GamePadDecorator
10
11 - (instancetype)init {
12     self = [super init];
13     if (self) {
14         self.gamePad = [[GamePad alloc] init];
15     }
16     return self;
17 }
18
19 - (void)up {
20     [self.gamePad up];
21 }
22
23 - (void)down {
24     [self.gamePad down];
25 }
26
27 - (void)left {
28     [self.gamePad left];
29 }
30
31 - (void)right {
32     [self.gamePad right];
33 }
34
35 - (void)buttonA {
36     [self.gamePad buttonA];
37 }
38
39 - (void)buttonB {
40     [self.gamePad buttonB];
41 }
42
43 @end

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

CheatGamePadDecorator.h

1 #import "GamePadDecorator.h"
2
3 @interface CheatGamePadDecorator : GamePadDecorator
4
5 - (void)cheat;
6
7 @end

CheatGamePadDecorator.m

1 #import "CheatGamePadDecorator.h"
2
3 @implementation CheatGamePadDecorator
4
5 - (void)cheat {
6     NSLog(@"cheat");
7 }
8
9 @end

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

 1 #import "ViewController.h"
 2 #import "CheatGamePadDecorator.h"
 3
 4 @interface ViewController ()
 5
 6 @end
 7
 8 @implementation ViewController
 9
10 - (void)viewDidLoad {
11     [super viewDidLoad];
12
13     //创建CheatGamePadDecorator实例
14     CheatGamePadDecorator *cheaterGamePad = [[CheatGamePadDecorator alloc] init];
15
16     //实现GamePad的功能
17     [cheaterGamePad up];
18     [cheaterGamePad down];
19
20     //实现作弊方法
21     [cheaterGamePad cheat];
22 }
23
24
25
26 @end

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

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

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

我们创建一个Cheat Category

GamePad+Cheat.h

1 #import "GamePad.h"
2
3 @interface GamePad (Cheat)
4
5 - (void)cheat;
6
7 @end

GamePad+Cheat.m

1 #import "GamePad+Cheat.h"
2
3 @implementation GamePad (Cheat)
4
5 - (void)cheat {
6     NSLog(@"cheat");
7 }
8
9 @end

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

 1 #import "ViewController.h"
 2 #import "GamePad+Cheat.h"
 3
 4 @interface ViewController ()
 5
 6 @end
 7
 8 @implementation ViewController
 9
10 - (void)viewDidLoad {
11     [super viewDidLoad];
12
13     //创建GamePad实例
14     GamePad *gamePad = [[GamePad alloc] init];
15
16     //实现GamePad原有方法
17     [gamePad up];
18     [gamePad down];
19
20     //实现作弊方法
21     [gamePad cheat];
22
23 }

使用Category更为简单

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

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

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

时间: 2024-11-09 00:25:38

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

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

一.前言 部门去年年中开始各种改造,第一步是模块服务化,这边初选dubbo试用在一些非重要模块上,慢慢引入到一些稍微重要的功能上,半年时间,学习过程及线上使用遇到的些问题在此总结下. 整理这篇文章差不多花了两天半时间,请尊重劳动成果,如转载请注明出处http://blog.csdn.net/hzzhoushaoyu/article/details/43273099 二.什么是dubbo Dubbo是阿里巴巴提供的开源的SOA服务化治理的技术框架,据说只是剖出来的一部分开源的,但一些基本的需求已经

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

一.前言 部门去年年中开始各种改造,第一步是模块服务化,这边初选dubbo试用在一些非重要模块上,慢慢引入到一些稍微重要的功能上,半年时间,学习过程及线上使用遇到的些问题在此总结下. 整理这篇文章差不多花了两天半时间,请尊重劳动成果,如转载请注明出处http://blog.csdn.NET/hzzhoushaoyu/article/details/43273099 二.什么是dubbo Dubbo是阿里巴巴提供的开源的SOA服务化治理的技术框架,据说只是剖出来的一部分开源的,但一些基本的需求已经

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

*************************************************************************************************************************** 作者:EasyWave                                                                             时间:2014.10.31 类别:Linux应用-MP4视频录制库MP4V2

python的列表,元组和字典简单介绍

引 入 java                                   python 存取多个值:数组或list集合 ------------------------> 列表,元组 key-value格式:    Map        ------------------------>    字典 自己学习发现,java跟python这两门面向对象语言在数据类型的定义上,很多思想都是互通的,这里不说java,简单介绍一下python的列表,元组和字典. 一.列表 List: 最通

javascript的return语句简单介绍

javascript的return语句简单介绍:return语句在js中非常的重要,不仅仅具有返回函数值的功能,还具有一些特殊的用法,有个清晰的把握是非常有必要的.下面就结合实例简单介绍一下return语句的作用.一.用来返回控制和函数结果:通常情况,return语句对于一个函数是很有必要的,因为往往需要函数在一系列的代码执行后会得到一个期望的返回值,而此值就是通过return语句返回,并且将控制权返回给主调函数.语法格式: return 表达式 代码实例如下: function add(){

Object-c集合的简单介绍

一.简单介绍 NSArray/NSMutableArray NSSet/NSMutableSet NSDictionary/NSMutableDictionary NSArray.NSSet.NSDictionary是不可变的,创建的时候初始化 NSMutableArray.NSMutableSet.NSMutableDictionary是可变的 二.使用介绍 NSArray是有序的数组 NSMutableArray *myArray=[[NSMutableArray alloc] init];

plsql的环境与介绍:环境的搭建和plsql的简单介绍

PLSQL编程 1.环境的搭建 (1)创建一个存储表空间 SQL> conn /as sysdbaConnected. SQL> create tablespace plsql datafile '/u01/oracle/oradata/ORCL/plsql01.dbf' size 1G; Tablespace created. (2)创建PLSQL用户SQL> create user plsql identified by plsql default tablespace plsql;

CSS之box-sizing的用处简单介绍

前几天才发现有 box-sizing 这么个样式属性,研究了一番感觉很有意思, 通过指定容器的盒子模型类型,达到不同的展示效果 例如:当一个容器宽度定义为 width:100%;  之后,如果再增加 padding 或者 border 则会溢出父容器,是向外扩张的 如果使用该样式,指定为 box-sizing: border-box; 则 padding 和 border 就不会再溢出,而是向内收缩的,这个效果感觉非常实用, 特别是 input 和 textarea 等 现在设置 100% 再直

【玩转微信公众平台之七】 PHP语法简单介绍

经过多篇的努力,我们终于成为了微信公众平台的开发者.但是别高兴的太早,就跟修真小说一样:修炼多年武破虚空,飞升到仙界后本以为成为了天仙即可跳出三界外,不在五行中.可实际到了仙界才发现,成仙只是修行的第一步......没错,成为开发者也才只是第一步,因为现在你的微信公众平台还没有任何功能,说难听点就是小白,说好听点就是白马王子,说可爱点就是小白白,说黄色点就是洗白白,说...----------------要想在微信公众平台添加功能,那就需要写代码:既然说到写代码,那么肯定是要用php(如果用AS