观察者

作者: XZhongWen | 来源:发表于2019-03-06 11:00 被阅读0次

iOS 设计模式 - 观察者

原理图

Observer.png

说明

  • 在定义的一对多的对象间, 使对象间的关系为松耦合
  • 当被观察者对象的状态改变时, 所有依赖的观察者对象的update行为会被自动调用
  • 被观察者对象能够向所有观察者发送通知

代码实现

订阅者对象都遵守的协议

//
//  SubscriptionProtocol.h
//  Observer
//
//  Created by mye on 2019/3/4.
//  Copyright © 2019 mye. All rights reserved.
//

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@protocol SubscriptionProtocol <NSObject>
@optional
/**
 *  接收到的订阅信息
 *
 *  @param message            订阅信息
 *  @param subscriptionNumber 订阅编号
 */
- (void)subscriptionMessage:(id)message subscriptionNumber:(NSString *)subscriptionNumber;

@end

NS_ASSUME_NONNULL_END

订阅服务中心

//
//  SubscriptionServerCenter.h
//  Observer
//
//  Created by mye on 2019/3/4.
//  Copyright © 2019 mye. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "SubscriptionProtocol.h"

NS_ASSUME_NONNULL_BEGIN

@interface SubscriptionServerCenter : NSObject

/**
 *  创建订阅号
 *
 *  @param subscriptionNumber 订阅号码
 */
- (void)createSubscriptionNumber:(NSString *)subscriptionNumber;

/**
 *  移除订阅号(参与到该订阅号码的所有客户不会再收到订阅信息)
 *
 *  @param subscriptionNumber 订阅号码
 */
- (void)removeSubscriptionNumber:(NSString *)subscriptionNumber;

/**
 *  客户订阅指定的订阅号
 *
 *  @param customer           客户对象
 *  @param subscriptionNumber 订阅号码
 */
- (void)addCustomer:(id<SubscriptionProtocol>)customer
withSubscriptionNumber:(NSString *)subscriptionNumber;

/**
 *  将指定客户从指定订阅号上移除掉
 *
 *  @param customer           客户对象
 *  @param subscriptionNumber 订阅号码
 */
- (void)removeCustomer:(id<SubscriptionProtocol>)customer
fromSubscriptionNumber:(NSString *)subscriptionNumber;

/**
 *  通知签订了订阅号码的对象
 *
 *  @param message            信息对象
 *  @param subscriptionNumber 订阅号码
 */
- (void)sendMessage:(id)message
toSubscriptionNumber:(NSString *)subscriptionNumber;

@end

NS_ASSUME_NONNULL_END

//
//  SubscriptionServerCenter.m
//  Observer
//
//  Created by mye on 2019/3/4.
//  Copyright © 2019 mye. All rights reserved.
//

#import "SubscriptionServerCenter.h"

static NSMutableDictionary *_subscriptionNumberDictionary = nil;

@implementation SubscriptionServerCenter

+ (void)initialize {
    _subscriptionNumberDictionary = [NSMutableDictionary dictionary];
}

/**
 *  创建订阅号
 *
 *  @param subscriptionNumber 订阅号码
 */
- (void)createSubscriptionNumber:(NSString *)subscriptionNumber {
    NSParameterAssert(subscriptionNumber);
    NSHashTable *hashTable = _subscriptionNumberDictionary[subscriptionNumber];
    if (hashTable == nil) {
        hashTable = [NSHashTable weakObjectsHashTable];
        [_subscriptionNumberDictionary setObject:hashTable forKey:subscriptionNumber];
    }
}

/**
 *  移除订阅号(参与到该订阅号码的所有客户不会再收到订阅信息)
 *
 *  @param subscriptionNumber 订阅号码
 */
- (void)removeSubscriptionNumber:(NSString *)subscriptionNumber {
    NSParameterAssert(subscriptionNumber);
    NSHashTable *hashTable = _subscriptionNumberDictionary[subscriptionNumber];
    if (hashTable) {
        [_subscriptionNumberDictionary removeObjectForKey:subscriptionNumber];
    }
}

/**
 *  客户订阅指定的订阅号
 *
 *  @param customer           客户对象
 *  @param subscriptionNumber 订阅号码
 */
- (void)addCustomer:(id<SubscriptionProtocol>)customer
withSubscriptionNumber:(NSString *)subscriptionNumber {
    NSParameterAssert(subscriptionNumber);
    NSHashTable *hashTable = _subscriptionNumberDictionary[subscriptionNumber];
    if (hashTable && customer) {
        [hashTable addObject:customer];
    }
}

/**
 *  将指定客户从指定订阅号上移除掉
 *
 *  @param customer           客户对象
 *  @param subscriptionNumber 订阅号码
 */
- (void)removeCustomer:(id<SubscriptionProtocol>)customer
fromSubscriptionNumber:(NSString *)subscriptionNumber {
    NSParameterAssert(subscriptionNumber);
    NSHashTable *hashTable = _subscriptionNumberDictionary[subscriptionNumber];
    if (hashTable && customer) {
        [hashTable removeObject:customer];
    }
}

/**
 *  通知签订了订阅号码的对象
 *
 *  @param message            信息对象
 *  @param subscriptionNumber 订阅号码
 */
- (void)sendMessage:(id)message
toSubscriptionNumber:(NSString *)subscriptionNumber {
    NSParameterAssert(subscriptionNumber);
    NSHashTable *hashTable = _subscriptionNumberDictionary[subscriptionNumber];
    for (id<SubscriptionProtocol> customer in hashTable) {
        if ([customer respondsToSelector:@selector(subscriptionMessage:subscriptionNumber:)]) {
            [customer subscriptionMessage:message subscriptionNumber:subscriptionNumber];
        }
    }
}

@end

  • 订阅服务中心添加订阅号
SubscriptionServerCenter *center = [[SubscriptionServerCenter alloc] init];
[center createSubscriptionNumber:@"COMPUTER"];
  • 添加遵守SubscriptionProtocol协议的对象到订阅号对应的订阅者集合
[center addCustomer:self withSubscriptionNumber:@"COMPUTER"];
  • 当订阅服务中心的订阅号收到消息时, 该订阅号对应的所有订阅者的协议方法会被自动调用
[center sendMessage:@"apple" toSubscriptionNumber:@"COMPUTER"];

相关文章

  • 前端面试考点之手写系列

    1、观察者模式 观察者模式(基于发布订阅模式) 有观察者,也有被观察者。 观察者需要放到被观察者列表中,被观察者的...

  • 观察者模式

    观察者模式,包括观察者和被观察者。观察者们将自己的需求告知被观察者,被观察者负责通知到观察者。 一、Java自带的...

  • 设计模式(三行为模式)

    观察者模式 构成 抽象被观察者 + 具体被观察者 + 抽象观察者 + 具体观察者 定义 被观察者具有修改观察列表 ...

  • Laravel5.8 模型事件与 Observer

    Observer 观察者模式创建步骤 观察者监听多个事件观察者 注册观察者注册观察者 观察者中事件的发生顺序 la...

  • PHP设计模式-观察者

    适用性 观察者观察被观察者,被观察者通知观察者 代码示例 /** * 观察者接口 */ interface Obs...

  • RxJava 原理篇

    一、框架思想 观察者模式观察者自下而上注入被观察者被观察者自上而下发射事件观察者模式 装饰器模式自上而下,被观察者...

  • java观察者模式

    案例: 定义被观察者 定义观察者 调用 优点 观察者和被观察者之间抽象耦合。观察者模式容易扩展,被观察者只持有观察...

  • RxJava 再 "用力" 一点点

    RxJava 里面采用了观察者的设计模式,因此存在观察者与被观察者,被观察者发送消息通知观察者,观察者接收到消息更...

  • RXJava

    传统的观察者模式 RxJava 四个要素 被观察者 观察者 订阅 事件 创建被观察者subscriber就是观察者...

  • 设计模式之观察者模式

    被观察者 观察者抽象 观察者的实现类 被观察者的实现 客户端 结果 同时是观察者和被观察者 客户端 执行结果

网友评论

      本文标题:观察者

      本文链接:https://www.haomeiwen.com/subject/roviuqtx.html