为其它对象提供一种代理以控制对这个对象的访问。代理设计模式的英文名是 Proxy pattern,和我们常见的 delegate(委托) 没关系。
代理模式的组成
抽象角色:通过接口或抽象类声明真实角色实现的业务方法。
代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。
真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。百度百科
实现步骤:
结构图:
@interface AbstractProxy : NSProxy /** * 被代理对象 */ @property (nonatomic,weak) id customer; /** * @breif 代理客户 * @param customer 实现了某种协议的客户 * @return 代理对象 */ - (instancetype)initWithCustomer:(id)customer; @end
#import <objc/runtime.h> #import "AbstractProxy.h" #import "AbstractExcute.h" @implementation AbstractProxy - (instancetype)initWithCustomer:(id)customer { self.customer = customer; return self; } - (NSMethodSignature *)methodSignatureForSelector:(SEL)aselector { if ([self.customer respondsToSelector:aselector]) { return [self.customer methodSignatureForSelector:aselector]; } else { AbstractExcute *excute = [AbstractExcute shareInstance]; return [excute methodSignatureForSelector:NSSelectorFromString(@"nullExcute:")]; } } - (void)forwardInvocation:(NSInvocation *)invocation { SEL selector = [invocation selector]; if ([self.customer respondsToSelector:selector]) { [invocation setTarget:self.customer]; [invocation invoke]; } else { NSString *selectorString = NSStringFromSelector(invocation.selector); invocation.selector = NSSelectorFromString(@"nullExcute:"); AbstractExcute *excute = [AbstractExcute shareInstance]; [invocation setTarget:excute]; const char *className = class_getName([self class]); NSArray *classNameArray = nil; if (self.customer) { classNameArray = @[[NSString stringWithUTF8String:className], selectorString, @""]; } else { classNameArray = @[[NSString stringWithUTF8String:className], selectorString]; } [invocation setArgument:&classNameArray atIndex:2]; [invocation invoke]; } } @end
#import "AbstractProxy.h" #import "MessageProtocol.h" NS_ASSUME_NONNULL_BEGIN @interface ConcreteProxy : AbstractProxy<MessageProtocol> @end NS_ASSUME_NONNULL_END
#import "ConcreteProxy.h" @implementation ConcreteProxy @end
#import <Foundation/Foundation.h> NS_ASSUME_NONNULL_BEGIN @interface AbstractExcute : NSObject + (instancetype)shareInstance; @end NS_ASSUME_NONNULL_END
#import "AbstractExcute.h" @implementation AbstractExcute + (instancetype)shareInstance { static AbstractExcute *sharedAbstractExcute = nil; static dispatch_once_t predicate; dispatch_once(&predicate, ^{ sharedAbstractExcute = [[self alloc]init]; }); return sharedAbstractExcute; } - (void)nullExcute:(NSArray *)className { if (className.count == 3) { NSLog(@"%@ 设置了代理,但该代理没有实现 %@ 方法", className[0], className[1]); } else { NSLog(@"%@ 没有设置代理,方法 %@ 没有执行", className[0], className[1]); } } @end
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@end
#import "ViewController.h" #import "MessageProtocol.h" #import "ConcreteProxy.h" @interface ViewController ()<MessageProtocol> @property(nonatomic,strong) ConcreteProxy *proxy; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.proxy = [[ConcreteProxy alloc]initWithCustomer:self]; [self.proxy helloWorld]; [self.proxy goodByte]; } - (void)helloWorld { NSLog(@"helloWorld"); } - (void)goodByte { NSLog(@"goodByte"); } @end
五,代码示例
代理模式
原文:https://www.cnblogs.com/lxlx1798/p/11607712.html