代理模式类图:
Objective-C中实现代理模式有:NSProxy
通常,发送给代理的消息会转发到真实对象,或使代理加载(或将自身转换为)真实对象。 NSProxy的子类可用于实现透明的分布式消息传递(例如NSDistantObject)或用于懒惰实例化创建成本很高的对象。
NSProxy实现了根类所需的基本方法,包括在NSObject协议中定义的方法。但是,作为抽象类,它不提供初始化方法,并且在收到任何未响应的消息时会引发异常。因此,具体的子类必须提供初始化或创建方法,并覆盖forwardInvocation:和methodSignatureForSelector:方法以处理自身未实现的消息。子类的forwardInvocation的实现:应该执行处理调用所需的所有操作,例如通过网络转发调用或加载实际对象并将其传递给调用。 methodSignatureForSelector:需要为给定消息提供参数类型信息;子类的实现应能够确定其需要转发的消息的参数类型,并应相应地构造一个NSMethodSignature对象,让开销比较大的对象实行懒实例化如:(邮件Mail应用)收到邮件消息中只会显示一些基本信息,当用户点击站位图形时,开始加载真正的图形内容,原先的站位图标作为一个代理
Client:需要去香港买便宜货如化妆品,港货手机
Proxy:代理商实现去真正去买商品,并打包运回来
RealObject:化妆品提供商,港货手机提供商
具体代码:
需要代理类和真正实体类实现统一接口;
1、代理:
1.1、代理基础类:
#import <Foundation/Foundation.h>
#import "NSProvider.h"
NS_ASSUME_NONNULL_BEGIN
@interface Agent : NSProxy<NSPhoneProviderProtocol,NSBookProviderProtocol,NSComputerProviderProtocol,NSClothesProviderProtocol>
+ (instancetype)proxy;
- (void)registerObject:(id)target;
@end
NS_ASSUME_NONNULL_END
1.2、代理具体实现通过消息转发机制:
#import <objc/runtime.h>
#import "Agent.h"
@interface Agent()
@property (nonatomic,strong) NSMutableArray* targets;
@end
@implementation Agent
+ (instancetype)proxy{
static Agent* sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[Agent alloc] init];
});
return sharedInstance;
}
static NSArray* g_targetArray;
#pragma mark - init
- (instancetype)init{
_targets = [NSMutableArray array];
return self;
}
-(void)registerObject:(id)target{
if (target) {
[_targets addObject:target];
}
}
#pragma mark - NSProxy override methods
- (void)forwardInvocation:(NSInvocation *)invocation{
for (id target in _targets){
if (target && [target respondsToSelector:invocation.selector]){
[invocation invokeWithTarget:target];
}
}
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel{
for (id target in _targets){
if (target && [target respondsToSelector:sel]){
return [target methodSignatureForSelector:sel];
}
}
return [super methodSignatureForSelector:sel];
}
@end
2、供应商:
2.1、书供应商、手机供应商、电脑供应商
//
// NSProvider.h
// NSProxy
//
// Created by xiang lin on 2020/5/27.
// Copyright © 2020 xiang lin. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface Provider : NSObject
@end
#pragma mark NSBookProviderProtocol
@protocol NSBookProviderProtocol <NSObject>
- (void)buyBook;
@end
@interface NSBookProvider : Provider<NSBookProviderProtocol>
@end
#pragma mark NSPhoneProviderProtocol
@protocol NSPhoneProviderProtocol <NSObject>
- (void)buyIphone;
- (void)buyHuaWeiPhone;
@end
@interface NSPhoneProvider : Provider<NSPhoneProviderProtocol>
@end
#pragma mark NSComputerProviderProtocol
@protocol NSComputerProviderProtocol <NSObject>
- (void)buyMac;
- (void)buyMacBook;
- (void)buyHuaWeiComputer;
@end
@interface NSComputerProvider : Provider<NSComputerProviderProtocol>
@end
#pragma mark NSClothesProviderProtocol
@protocol NSClothesProviderProtocol <NSObject>
- (void)buyBigclothes;
- (void)buyMiddleclothes;
- (void)buyTinyclothes;
@end
@interface NSClothesProvider : Provider<NSClothesProviderProtocol>
@end
NS_ASSUME_NONNULL_END
2.2、去供应商执行真正的动作:
#import "NSProvider.h"
#import "Agent.h"
@implementation Provider
@end
@implementation NSBookProvider
- (void)buyBook{
NSLog(@"buyBook:%s,%d",__FUNCTION__,__LINE__);
}
@end
@implementation NSPhoneProvider
- (void)buyIphone{
NSLog(@"buyIphone:%s,%d",__FUNCTION__,__LINE__);
}
- (void)buyHuaWeiPhone{
NSLog(@"buyHuaWeiPhone:%s,%d",__FUNCTION__,__LINE__);
}
@end
@implementation NSComputerProvider
- (void)buyMac{
NSLog(@"buyMac:%s,%d",__FUNCTION__,__LINE__);
}
- (void)buyMacBook{
NSLog(@"buyMacBook:%s,%d",__FUNCTION__,__LINE__);
}
- (void)buyHuaWeiComputer{
NSLog(@"buyHuaWeiComputer:%s,%d",__FUNCTION__,__LINE__);
}
@end
@implementation NSClothesProvider
- (void)buyBigclothes{
NSLog(@"buyBigclothes:%s,%d",__FUNCTION__,__LINE__);
}
- (void)buyMiddleclothes{
NSLog(@"buyMiddleclothes:%s,%d",__FUNCTION__,__LINE__);
}
- (void)buyTinyclothes{
NSLog(@"buyTinyclothes:%s,%d",__FUNCTION__,__LINE__);
}
@end
3、实体需要向代理中心注册自己:
//实体对象在自己的模块向代理中心注册当前实体,为了便于添加,这里统一在代理中实现
// 在单独的模块可以接管当前app的生命周期,在每个模块的applicationDidFinishLaunching
// 单独注册,这样代理就不会被污染
// NSBookProvider 模块
[[Agent proxy] registerObject:[NSBookProvider new]];
// NSComputerProvider 模块
[[Agent proxy] registerObject:[NSComputerProvider new]];
// NSPhoneProvider 模块
[[Agent proxy] registerObject:[NSPhoneProvider new]];
// NSClothesProvider 模块
[[Agent proxy] registerObject:[NSClothesProvider new]];
4、向代理中心买东西:
// 1、初始化代理商
Agent *agent = [Agent proxy];
// 2.1、向代理商买华为手机
[agent buyHuaWeiPhone];
// 2.2、向代理商mac
[agent buyMac];
// 2.3、向代理商买书
[agent buyBook];
// 2.4、向代理商iphone手机
[agent buyIphone];
// 2.5、向代理商买华为电脑
[agent buyHuaWeiComputer];
// 2.6、向代理商买macbook
[agent buyMacBook];
// 2.7、向代理商买大尺寸衣服
[agent buyBigclothes];
// 2.7、向代理商买中号衣服
[agent buyMiddleclothes];
// 2.8、向代理商买小尺寸衣服
[agent buyTinyclothes];