专栏首页APP自动化测试Objective-C 装饰模式--简单介绍和使用

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方法被重载

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • iOS自动化探索(二)WDA API的使用

    前面我们已经安装好了WebdriverAgent, 现在可以用Facebook官方提供的API来进行一些操作

    周希
  • Objective-C 桥接模式 -- 简单实用和说明

    比如XBox遥控器跟XBox主机, 我们抽象出主机和遥控器两个抽象类, 让这两个抽象类耦合

    周希
  • 创建简单动画(一) --- 常规hud

    先说下当前我为处理动画的思路: (新手上路, 老司机轻喷,如果有更好的实现方法请大神指教 感恩戴德)

    周希
  • 学习|OpenCV匹配相似轮廓

    其实查找相似的东西用机器学习训练的方式处理应该是最好的,今天做的这个小练习主要是针对OpenCV的matchShapes函数的练习,正好把OpenCV的几个函数...

    Vaccae
  • Nginx的location规则迷之匹配

    Nginx,一个改变世界的软件,其作者是一个俄罗斯人,俗称毛子,在国人的印象中,是一群晚饭后牵着大灰熊在小区楼下散步的彪汉。能写出这般顺滑的软件,可谓是心有猛虎...

    laulzgoay
  • 实习申请被Apple Music拒了之后,我重新设计它

    Jason Yuan,美国西北大学一名大学生,今年早些时候申请了Apple Music平面设计实习生。被拒后,花费了近3个月时间,重新设计了Apple Musi...

    CSDN技术头条
  • C/C++黑魔法-枚举骇客

    Qt君
  • 使用 RAIL 模型评估前端性能 [每日前端夜话(0x09)]

    RAIL 是一种以用户为中心的性能模型。每个网络应用均具有与其生命周期有关的四个不同方面,且这些方面以不同的方式影响着性能:

    疯狂的技术宅
  • 从引文分析看计算机科学:Salton 和Bergmark Redux

    原文题目: Viewing Computer Science through Citation Analysis; Salton and Bergmark Re...

    吴亚芳
  • String类的compareTo方法的源码解析

    ----------------------------------------------------------------------------- St...

    黑泽君

扫码关注云+社区

领取腾讯云代金券