obj-c编程18:多对多的观察者模式

简介:

    我们知道使用委托的设计模式可以实现一对一的通知关系,但是如果需要通知多个观察者状态变化又该如何呢?此时,需要实现观察者模式之类的内容,而不是实现委托者一对一的模式。

    观察者模式定义了一个对象可以将另一个对象注册成自身观察者的模式,对象被注册成观察者后,任何观察者关注者事件都会在其发生时send给观察者。obj-c中实现观察者模式是通过NSNotificationCenter类实现的。该类为观察者对象和事件提供了一个全局调度系统。观察者可以向其注册观测系统中特定的事件;而被观察对象,在事件发生时,也可以发布通知到NSNotificationCenter,这样任何被观察者对象的通知可以发送到任何观察者对象,从而达到多对多关系的观察者模式。

    为了完成观察者模式,一般要完成以下几个步骤:

1: 观察者使用NSNotificationCenter实例方法-addObserver将自身注册为特定事件的观察者;

2: 观察者要实现步骤1中注册的回调方法;

3: 被观察者对象要使用-postNotifiationName之类的发送方法发送消息;

4: 观察者最终要确保在释放时使用-removeObserver:将自己从NSNotificationCenter中移除。

下面用杜撰的代码来看看实际如何实现观察者模式。代码中狗仔队对于明星无聊中的对话可谓是八卦之极,star的每一句话都要设法得到啊。不过从实际代码看来,貌似明星也有意的想把这些对话内容传播出去啊!如果不想,那就类似于<<obj-c编程17:键值观察>>里的键值观察模式了哦。下面上代码:

#import <Foundation/Foundation.h>

#define msg(...) NSLog(__VA_ARGS__)

#define NOTIFICATION_NAME @"MY_NOTIFICATION"

@interface Star:NSObject{
	NSString *name;
}
	@property(readonly) NSString *name;
	-(void)talk:(NSString *)blabla;
@end

@implementation Star
	@synthesize name;

	-(id)initWithName:(NSString *)name_v{
		self = [super init];
		if(self){
			name = name_v;
		}
		return self;
	}

	-(void)talk:(NSString *)blabla{
		msg(@"%@ to say :%@",name,blabla);

		NSDictionary *secret = [NSDictionary dictionaryWithObject:blabla \
			forKey:@"words"];

		[[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_NAME \
			object:self userInfo:secret];
	}
@end

@interface Dog:NSObject
	-(void)broadcast:(NSNotification *)note;
@end

@implementation Dog
	-(id)init{
		self = [super init];
		if(self){
			[[NSNotificationCenter defaultCenter] addObserver:self \
				selector:@selector(broadcast:) name:NOTIFICATION_NAME \
				object:nil];
		}
		return self;
	}

	-(void)broadcast:(NSNotification *)note{
		NSString *star_name = [[note object] name];
		NSString *words = [[note userInfo] objectForKey:@"words"];
		msg(@"star %@ sayed \"%@\"",star_name,words);
	}

	-(void)dealloc{
		[[NSNotificationCenter defaultCenter] removeObserver:self];
		//[super dealloc];
	}
@end

int main(int argc,char *argv[])
{
	@autoreleasepool{
		Star *star0 = [[Star alloc] initWithName:@"lucy"];
		Star *star1 = [[Star alloc] initWithName:@"jack"];
		Dog *dog = [[Dog alloc] init];

		[star0 talk:@"no shit!"];
		[star1 talk:@"that's right!"];
	}
	return 0;
}

运行结果是我们可以预料到的:

apple@kissAir: objc_src$./9

2014-08-03 21:05:11.830 9[910:507] lucy to say :no shit!

2014-08-03 21:05:11.831 9[910:507] star lucy sayed "no shit!"

2014-08-03 21:05:11.832 9[910:507] jack to say :that's right!

2014-08-03 21:05:11.832 9[910:507] star jack sayed "that's right!"


有人会说了,你这是1对多关系哦。多对多关系也很简单,狗仔队不止一只啊,我们再来创建1个,改变的代码如下:

int main(int argc,char *argv[])
{
	@autoreleasepool{
		Star *star0 = [[Star alloc] initWithName:@"lucy"];
		Star *star1 = [[Star alloc] initWithName:@"jack"];
		Dog *dog0 = [[Dog alloc] init];
		Dog *dog1 = [[Dog alloc] init];

		[star0 talk:@"no shit!"];
		[star1 talk:@"that's right!"];
	}
	return 0;
}

运行结果如下:

apple@kissAir: objc_src$./9

2014-08-03 21:32:43.513 9[973:507] lucy to say :no shit!

2014-08-03 21:32:43.514 9[973:507] star lucy sayed "no shit!"

2014-08-03 21:32:43.515 9[973:507] star lucy sayed "no shit!"

2014-08-03 21:32:43.515 9[973:507] jack to say :that's right!

2014-08-03 21:32:43.516 9[973:507] star jack sayed "that's right!"

2014-08-03 21:32:43.516 9[973:507] star jack sayed "that's right!"



相关文章
|
4天前
|
设计模式 JavaScript Java
[设计模式Java实现附plantuml源码~结构型]对象的间接访问——代理模式
[设计模式Java实现附plantuml源码~结构型]对象的间接访问——代理模式
|
4天前
|
设计模式 Java 容器
设计模式之组合模式-创建层次化的对象结构
设计模式之组合模式-创建层次化的对象结构
|
10月前
|
设计模式
设计模式中的六种关系以及代码之间的对应
设计模式中的六种关系以及代码之间的对应
98 0
设计模式中的六种关系以及代码之间的对应
|
设计模式 监控 uml
【对象行为模式】二十三天学会设计模式之观察者模式
【对象行为模式】二十三天学会设计模式之观察者模式
【对象行为模式】二十三天学会设计模式之观察者模式
|
设计模式 数据可视化 uml
【设计模式学习笔记】类图:类与类之间的关系
【设计模式学习笔记】类图:类与类之间的关系
210 0
【设计模式学习笔记】类图:类与类之间的关系
|
设计模式 监控
23种设计模式-关系模式-观察者模式(十五)
23种设计模式-关系模式-观察者模式(十五)
23种设计模式-关系模式-观察者模式(十五)
|
设计模式 Java 调度
23种设计模式-关系模式-中介者模式(二十二)
23种设计模式-关系模式-中介者模式(二十二)
23种设计模式-关系模式-中介者模式(二十二)
|
存储 关系型数据库 数据库
[译] 如何用 Room 处理一对一,一对多,多对多关系?
[译] 如何用 Room 处理一对一,一对多,多对多关系?
[译] 如何用 Room 处理一对一,一对多,多对多关系?
|
设计模式 Java 程序员
十四、观察者模式与访问者模式详解
观 察 者 模 式 ( Observer Pattern ) , 又叫发布-订阅( Publish/Subscribe ) 模式、模型-视图 ( Model/View ) 模式、源-监听器(Source/Listener) 模式或从属者( Dependents ) 模式。定义一种一对多的依赖关系,一个主题对象可被多个观察者对象同时监听,使得每当主题对象状态变化时,所 有依赖于它的对象都会得到通知并被自动更新。属于行为型模式。
649 1
举一个多对多关联的例子,并说明如何实现多对多关联映射
例如:商品和订单、学生和课程都是典型的多对多关系。可以在实体类上通过@ManyToMany注解配置多对多关联或者通过映射文件中的和标签配置多对多关联,但是实际项目开发中,很多时候都是将多对多关联映射转换成两个多对一关联映射来实现的。
1453 0