iOS设计模式之装饰者模式

一,什么是装饰模式

  • 模式定义
    装饰者包含被装饰者的所有接口和引用,方法实现完全是引用调用自己的方法,在装饰者子类添加新功能。
    注释:
    Category不要重写被装饰对象的方法,否则改变了被装饰对象的行为,不符合装饰者模式,只可适用特殊场景。分类主要用于对被装饰者类的方法和属性拓展
  • 需求场景
    静态库扩展功能。不改变(原始类)、不继承、动态扩展功能。
    • 不知道原始类实现细节,只提供接口,动态扩展功能。
    • 不想有更多子类,不想通过继承的方式添加功能。
    • 动态扩展对象的功能。
    • 必须持有对象的引用,包含实例化的被装饰类。

二,装饰模式结构图

  实现方式:

  1. 定义装饰者类,并在.h定义被装饰者类中的所有暴漏到.h的方法(也可以添加自定义的操作方法)和对被装饰者类的引用。
  2. 在装饰者类用用被装饰者对象对其方法调用,已输出我们想要的结果。
  3. 如果想拓展被装饰者类,可通过分类的方法,这样可以不破坏被装饰者类原生逻辑。  

三,代码示例

  • Target(被装饰者类)
    • Target.h
      @interface Target : NSObject
      /**
       * 游戏币的数量
       */
      @property(nonatomic,assign) NSInteger coin;
      
      /**
       * 上下左右的操作
       */
      - (void)up;
      
      - (void)down;
      
      - (void)left;
      
      - (void)right;
      /**
       * 选择与开始的操作
       */
      - (void)select;
      - (void)start;
      /**
       * 按钮 A + B 的操作
       */
      - (void)commandA;
      - (void)commandB;
      @end
    • Target.m
      @implementation Target
      
      - (void)up{
          NSLog(@"up");
      }
      
      - (void)down{
          NSLog(@"down");
      }
      
      - (void)left{
          NSLog(@"left");
      }
      
      - (void)right{
           NSLog(@"right");
      }
      
      - (void)select {
          
          NSLog(@"select");
      }
      
      - (void)start {
          
          NSLog(@"start");
      }
      
      - (void)commandA {
          
          NSLog(@"commandA");
      }
      
      - (void)commandB {
          
          NSLog(@"commandB");
      }
      
      @end  
  • Decorator(装饰者类)
    • Decorator.h
      #import <Foundation/Foundation.h>
      
      NS_ASSUME_NONNULL_BEGIN
      
      @interface Decorator : NSObject
      
      #pragma mark --被装饰者类方法
      
      @property (nonatomic) NSInteger coin;
      
      - (void)up;
      - (void)down;
      - (void)left;
      - (void)right;
      - (void)select;
      - (void)start;
      - (void)commandA;
      - (void)commandB;
      
      #pragma mark - 以下为装饰对象新添加的功能
      
      /**
       *  剩余几条命
       */
      @property (nonatomic, readonly) NSInteger  lives;
      
      /**
       *  作弊 (上下上下左右左右ABAB)
       */
      - (void)cheat;
      
      @end
    • Decorator.m
      #import "Decorator.h"
      #import "Target.h"
      @interface Decorator()
      
      @property (nonatomic,strong) Target target; //持有被装饰者类对象
      
      @end
      
      @implementation Decorator
      
      #pragma mark - 初始化
      
      - (instancetype)init {
          
          if (self = [super init]) {
              
              // 装饰对象包含一个真实对象的引用
              self.target = [Target new];
          }
          
          return self;
      }
      
      
      #pragma mark - 让真实对象的引用执行对应的方法
      
      - (void)up {
          
          [_target up];
      }
      
      - (void)down {
          
          [_target down];
      }
      
      - (void)left {
          
          [_target left];
      }
      
      - (void)right {
          [_target right];
      }
      
      - (void)select {
          [_target select];
      }
      
      - (void)start {
          
          [_target start];
      }
      
      - (void)commandA {
          
          [_target commandA];
      }
      
      - (void)commandB {
          
          [_target commandB];
      }
      
      #pragma mark - 装饰器新添加的方法
      - (void)cheat {
          [_target up];
          [_target down];
          [_target up];
          [_target down];
          [_target left];
          [_target right];
          [_target left];
          [_target right];
          [_target commandA];
          [_target commandB];
          [_target commandA];
          [_target commandB];
      }
      
      @synthesize lives = _lives;
      - (NSInteger)lives {
          // 相关处理逻辑
          return 10;
      }
      
      @end

四,装饰模式优缺点

  • 优点
    在不改变目标类业务逻辑的情况下,拓展原有的方法和功能

五,demo

  装饰者模式

posted on 2019-09-07 21:35  梁飞宇  阅读(818)  评论(0编辑  收藏  举报