iOS观察者模式学习(如果钲鼓突然间敲起?)

先来读几句余光中老先生的诗吧。

秦俑

作者: 余光中 

  ——临潼出土战士陶俑 

铠甲未解,双手犹紧紧地握住

我看不见的弓箭或长矛

如果钲鼓突然间敲起

你会立刻转身吗,立刻

向两千年前的沙场奔去

去加入一行行一列列的同袍?

如果你突然睁眼,威武闪动

胡髭翘着骁悍与不驯

吃惊的观众该如何走避?

幸好,你仍是紧闭着双眼,似乎

已惯于长年阴间的幽暗

乍一下子怎能就曝光?

如果你突然开口,浓厚的秦腔

又兼古调,谁能够听得清楚?

隔了悠悠这时光的河岸

不知有汉,更无论后来

你说你的咸阳吗,我呢说我的西安事变

谁能说得清长安的棋局?

而无论你的箭怎样强劲

再也射不进桃花源了

问今世是何世吗,我不能瞒你

始皇的帝国,车同轨,书同文

威武的黑旗从长城飘扬到交址

只传到二世,便留下了你,战士

留下满坑满谷的陶俑

严整的纪律,浩荡六千兵骑

岂曰无衣

与子同袍

王于兴师

修我戈矛

慷慨的歌声里,追随着祖龙

统统都入了地下,不料才叁?

外面不再是姓嬴的天下

不再姓嬴,从此我们却姓秦

秦哪秦哪,番邦叫我们

秦哪秦哪,黄河清过了几次?

秦哪秦哪,哈雷回头了几回?

黑漆漆禁闭了两千年后

约好了,你们在各地出土

在博物馆中重整队伍

眉目栩栩,肃静无哗的神情

为一个失踪的帝国作证

而喧嚷的观众啊,我们

一转眼也都会转入地下

要等到哪年啊哪月啊才出土

啊不能,我们是血肉之身

转眼就朽去,像你们陪葬的贵人

只留下不朽的你们,六千兵马

潼关已陷,唉,咸阳不守

阿房宫的火灾谁来抢救? 只留下

再也回不去了的你们,成了

隔代的人质,永远的俘虏

叁缄其口岂止十二尊金人?

始作俑者谁说无后呢,你们正是

最尊贵的后人,不跟始皇帝遁入过去

却跟徐福的六千男女

奉派向未来探讨长生

其中,注红字的诗句与小陈今天要与大家探讨的“观察者模式”有关。

在软件系统中,一个对象的状态改变可能会使得许多对象的状态发生改变。观察者模式是处理这类问题的常用方法。观察者模式(Observer pattern)又叫发布/订阅(public/subcribe)模式。

在余老先生的这首诗中,

铮鼓是信息的发布者。

秦俑是信息的订阅者。

我们可以这样用Objective-C实现观察者模式。

一、创建Objective-C protocol:

1.Observer.h观察者协议(接口)

//  Observer.h
#import <Foundation/Foundation.h>
@protocol Observer

@required
//观察者观察到现象时所做的事。
-(void)update;

@end

2.Subject.h通知主题协议(接口)

//  Subject.h
@class Observer;
@protocol Subject

@required
//增加观察者
-(void)attach:(Observer*) theObserver;
//移除观察者
-(void)detach:(Observer*) theObserver;
//通知观察者
-(void)notifyObservers;

@end

注:接口的使用并不是必要的;接口可以起到点“多继承”的作用,集“万千功能于一身”;类是对对象的抽象,接口是对行为的抽象;对于行为出格的对象,可以使用接口。比如说,一般的狗不拿耗子,而非一般的狗拿耗子。在这里,非一般的狗 = 实现了拿耗子接口的一般的狗。

二、创建实现Objective-C protocol的类:

1.TerracottaArmy类(观察者,秦俑类)

//  TerracottaArmy.h
#import <Foundation/Foundation.h>
#import "Observer.h"
//实现了Observer protocol
@interface TerracottaArmy : NSObject<Observer>

@end


//  TerracottaArmy.m
#import "TerracottaArmy.h"

@implementation TerracottaArmy

-(void)update
{
    NSLog(@"Yes sir!立刻转身,立刻向两千年前的沙场奔去,去加入一行行一列列的同袍。");
}

@end


2.Drum类(通知主题,钲鼓类)

//  Drum.h
#import <Foundation/Foundation.h>
#import "Subject.h"
@class Observer;
//实现了Subject protocol
@interface Drum : NSObject<Subject>
@property (nonatomic,strong)NSMutableArray *observers;
+(Drum*)sharedInstance;
@end


//  Drum.m
#import "Drum.h"
@implementation Drum
@synthesize observers;
static  Drum* instance = nil;
+ (Drum*)sharedInstance{
    
    @synchronized(self){
        if(instance == nil){
            instance = [[super allocWithZone:NULL] init];
        }
    }
    return instance;
}

+ (id) allocWithZone:(NSZone *)zone {
    return [self sharedInstance];
}

- (id) copyWithZone:(NSZone*)zone {
    return self;
}

-(void)attach:(Observer*) theObserver
{
    [self.observers addObject:theObserver];
}
-(void)detach:(Observer*) theObserver
{
    [self.observers removeObject:theObserver];
}
-(void)notifyObservers
{
    NSLog(@"钲鼓响起");
    for(id obs in self.observers)
    {
        [obs update];
    }
}

@end

注:Drum只需要一个实例,所以采用了单例模式来实现。


三、做实验
编写JJViewController的viewDidLoad方法:

- (void)viewDidLoad
{
    [super viewDidLoad];
    NSLog(@"实验1");
    //实例化观察者:秦俑1、秦俑2、秦俑3
    Observer* terracottaArmy1 = [[TerracottaArmy alloc]init];
    Observer* terracottaArmy2 = [[TerracottaArmy alloc]init];
    Observer* terracottaArmy3 = [[TerracottaArmy alloc]init];
    
    //实例化通知主题:钲鼓
    Drum *drum = [Drum sharedInstance];
    drum.observers = [[NSMutableArray alloc] init];
    
    //铮鼓增加订阅者:秦俑1、秦俑2、秦俑3
    [drum attach:terracottaArmy1];
    [drum attach:terracottaArmy2];
    [drum attach:terracottaArmy3];
    
    //钲鼓通知所有已注册的订阅者
    [drum notifyObservers];
    
    NSLog(@"实验2");
    //钲鼓删除订阅者秦俑1
    [drum detach:terracottaArmy1];
    //钲鼓再次通知所有已注册的订阅者
    [drum notifyObservers];
}

实验结果:


参考了:关东升《iOS开发指南 从零基础到App Store上架》p184& 程杰《大话设计模式》p354

                
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值