Objective-C 裝飾模式--簡單介紹和使用

裝飾模式是在不必改變原類文件和使用繼承的情況下,動(dòng)態(tài)地?cái)U(kuò)展一個(gè)對象的功能。它是通過創(chuàng)建一個(gè)包裝對象,也就是裝飾來包裹真實(shí)的對象。

比如游戲機(jī)有一個(gè)GamePad類, 現(xiàn)在要增加一個(gè)作弊功能(例如100條命), 如果直接在GamePad類中去添加可能會(huì)影響其他子類的使用

我們考慮裝飾模式思維, 先建立一個(gè)裝飾器實(shí)現(xiàn)GamePad的所有功能, 然后在裝飾器類的子類中去添加作弊放方法

上代碼

比如GamePad類是這樣

#import <Foundation/Foundation.h>

@interface GamePad : NSObject

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

@end

我們創(chuàng)建一個(gè)裝飾器類, 讓它持有一個(gè)GamePad實(shí)例并實(shí)現(xiàn)相同的方法接口

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

現(xiàn)在我們新增一個(gè)子類來實(shí)現(xiàn)作弊方法

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類去實(shí)現(xiàn)GamePad的所有功能還能額外實(shí)現(xiàn)作弊方法

#import "ViewController.h"
#import "CheatGamePadDecorator.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //創(chuàng)建CheatGamePadDecorator實(shí)例
    CheatGamePadDecorator *cheaterGamePad = [[CheatGamePadDecorator alloc] init];
    
    //實(shí)現(xiàn)GamePad的功能
    [cheaterGamePad up];
    [cheaterGamePad down];
    
    //實(shí)現(xiàn)作弊方法
    [cheaterGamePad cheat];
}

@end

這樣就完成了一個(gè)裝飾模式思路的代碼構(gòu)建

下面說說cocoa touch中自帶的Category, 它也是對裝飾模式的一個(gè)實(shí)現(xiàn)

我們用Category來實(shí)現(xiàn)上面GamePad添加作弊功能

我們創(chuàng)建一個(gè)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來實(shí)現(xiàn)上面功能

#import "ViewController.h"
#import "GamePad+Cheat.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //創(chuàng)建GamePad實(shí)例
    GamePad *gamePad = [[GamePad alloc] init];
    
    //實(shí)現(xiàn)GamePad原有方法
    [gamePad up];
    [gamePad down];
    
    //實(shí)現(xiàn)作弊方法
    [gamePad cheat];
    
}

使用Category更為簡單

但是在使用Category時(shí)有個(gè)細(xì)節(jié)一定要注意, 盡量不要在Category類中去重寫基類方法

假如我們在GamePad+Cheat.h中重寫了- (void)up方法, 則整個(gè)工程中的up方法都被重載了

即使我們不在任何地方引用GamePad+Cheat.h, 只要這個(gè)文件在工程里面就會(huì)讓GamePad方法被重載

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容