iOS Design Patterns proxy mode

First, what is a proxy mode

  • definition

    Providing a proxy to control access to the object to other objects. Proxy design pattern English name is Proxy pattern, and our common delegate (delegate) does not matter.

  • Proxy pattern composed of
    abstract roles: the role of real business methods implemented through an interface or abstract class declaration. 
    Acting roles: to achieve abstract role, the role of agents is real, abstract methods to achieve real business logic methods by role, and can attach their own operations. 
    Real Role: Implement the abstract roles, define business logic real role to be achieved, calls for acting role. Baidu Encyclopedia

  • Use scene
    in iOS, we usually use a proxy to do message passing, as we often used to develop iOS UITableView it is to use a proxy to create a cell, click on a series of operations cell, etc.

Second, the pattern configuration diagram of the proxy (forwarding message broker implementation formula)  

  Implementation steps :

  1. Create an abstract proxy class ( AbstractProxy ), and a mechanism for forwarding agents are reserved to define the message Customer.
  2. Create a proxy class inherits from the abstract (AbstractProxy) subclass (ConcreteProxy), mainly used for message forwarding agent.

  Structure diagram :
  

Third, code implementation

  • Message forwarding class
    • AbstractProxy.h
      AbstractProxy @interface: NSProxy 
      
      / * * 
       * is a proxy object 
       * / 
      the @Property (nonatomic, weak) the above mentioned id the Customer; 
      
      / * * 
       * @breif proxy client 
       * @param customer to achieve the customer some kind of agreement 
       * @return proxy object 
       * / 
      - (instanceType) initWithCustomer: (the above mentioned id) the Customer; 
      
      @end
    • AbstractProxy.m
      #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
  • The broker
    • ConcreteProxy.h
      #import "AbstractProxy.h"
      #import "MessageProtocol.h"
      
      NS_ASSUME_NONNULL_BEGIN
      
      @interface ConcreteProxy : AbstractProxy<MessageProtocol>
      
      @end
      
      NS_ASSUME_NONNULL_END
    • ConcreteProxy.m
      #import "ConcreteProxy.h"
      
      @implementation ConcreteProxy
      
      @end
  • An exception handler
    • AbstractExcute.h
      #import <Foundation/Foundation.h>
      
      NS_ASSUME_NONNULL_BEGIN
      
      @interface AbstractExcute : NSObject
      
      + (instancetype)shareInstance;
      
      @end
      
      NS_ASSUME_NONNULL_END
    • AbstractExcute.m
      #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 ]); 
          } the else { 
              NSLog ( @ " % @ proxy is not set, the method not implemented% @ " , className [ 0 ], className [ . 1 ]); 
          } 
      } 
      
      @end
  • An exception handler
    • ViewController.h
      #import <UIKit/UIKit.h>
      
      @interface ViewController : UIViewController
      
      @end
    • ViewController.m
      #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

Fourth, the advantages and disadvantages

  • Advantages :
    1, clear responsibilities: is the real role do not need to know the details of the agent, as long as know the result, that is to say, I do not know how the intermediary match for me listings, these processes need to match only agency to do I just know what I can for the listing. 
    2, a high scalability 
    3, between us and the real proxy object and target objects only play the role of intermediary. 
    4, decoupling, the proxy class and the agency made a direct need to know what each other
  • Drawback : the agent is one to one, it requires an agreement between the commission and the agency.

V. Code Example
  proxy mode

Guess you like

Origin www.cnblogs.com/lxlx1798/p/11607712.html