拉模型是指主题对象在通知观察者的时候,只传递少量信息或者只是通知变化。如果观察者需求要更具体的信息,由观察者主动从主题对象中拉取数据。相比推模型来说,拉模型更加自由,观察者只要知道有情况发生就好了,至于什么时候获取、获取那些内容、甚至是否获取都可以自主决定。但是,却存在两个问题:
如果某个观察者响应过慢,可能会漏掉之前通知的内容
观察者必须保存一个对目标对象的引用,而且还需要了解主题对象的结构,这就使观察者产生了对主题对象的依赖。
可能每种设计模式都会存在或多或少的一些弊端,但是他们的确能够解决问题,也有更多有用的地方。在使用的时候,就需要我们权衡利弊,做出一个合适的选择。而工程师的价值就体现在,能够在纷繁复杂的工具世界中找到最有效的那个。而如果核桃没被砸开,不是你手力气不大的问题,而是你选错了工具,谁让你非得用门缝夹,不用锤子呢!
当然,上面那段属于题外话。言归正传,在OBJC编程中,典型的一种拉模型的实现是delegate。可能很多人会不同意我的观点,说delegate应当是委托模式。好吧,我不否认,delegate的确是委托模式的一种极度典型的实现方式。但是这并不妨碍,他也是一种观察者模式。其实本来各种设计模式之间就不是泾渭分明的。在使用和解释的时候,只要你能够说得通,而且能够解决问题就好了,没必要纠缠他们的名字。而在通知变化这个事情上delegate的确是能够解决问题的。
我们来看一个使用delegate实现拉模型的观察者的例子:
先实现一个delegate方便注册观察者,和回调函数
@class DZClient;
@protocol DZClientChangedDelegate <NSObject>
- (void) client:(DZClient*)client didChangedContent:(NSString*)key;
@end
@interface DZClient : NSObject
@property (nonatomic, weak) id<DZClientChangedDelegate> delegate;
@property (nonatomic, strong) NSString* key;
@end
注册观察者
//DZAppDelegate
DZClient* client = [DZClient new];
client.delegate = self;
client.key = @"aa";
当主题对象的属性发生改变的时候,发送内容有变化的通知
@implementation DZClient
- (void) setKey:(NSString *)key
{
if (_key != key) {
_key = key;
if ([_delegate respondsToSelector:@selector(client:didChangedContent:)]) {
[_delegate client:self didChangedContent:@"key"];
}
}
}










