美文网首页
装饰器模式(Decorator Pattern)

装饰器模式(Decorator Pattern)

作者: long弟弟 | 来源:发表于2022-09-12 01:08 被阅读0次

装饰器模式,包装模式

意图:动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更为灵活。

通过一种对客户端透明的方式来扩展对象的功能,是继承关系的一种替换方案。

装饰模式就是把要添加的附加功能放在单独的类中,并让这个类包含它要装饰的对象,当需要执行时,客户端就可以有选择地、按顺序地使用装饰功能包装对象。

装饰器模式.jpg

角色和职责

  1. Component 原始类,抽象类(或者说是静态库,不知道具体的实现,又不想使用继承)
    定义一个对象接口,可以给这些对象动态地添加职责。
  2. ConcreteComponent
    定义一个对象,可以给这个对象添加一些职责。
  3. Decorator 抽象装饰者
    维持一个指向Component对象的指针,并定义一个与Component接口一致的接口。当仅添加一个职责时,可省略该抽象类。
  4. ConcreteDecorator 具体装饰者
    向组件添加职责。

代码示例

#import <Foundation/Foundation.h>
//此处用协议Car来表示抽象类
@protocol Car <NSObject>
- (void)run1;
@end

@interface RunCar : NSObject<Car>
@end
@implementation RunCar
- (void)run1 {
    NSLog(@"汽车在行驶");
}
@end

@interface Decorator : NSObject<Car>
@end
@implementation Decorator
- (void)run1 {
    NSLog(@"抽象装饰者");
}
@end

@interface SwimDecorator : Decorator
@property (nonatomic, strong) RunCar *car;
@end
@implementation SwimDecorator
- (instancetype)initWithCar:(id<Car>)car {
    if (self = [super init]) {
        self.car = car;
    }
    return self;
}
- (void)swim {
    NSLog(@"可以游");
}
- (void)run1 {
    [self.car run1];
    [self swim];
}
@end

@interface FlyDecorator : Decorator
@property (nonatomic, strong) RunCar *car;
@end
@implementation FlyDecorator
- (instancetype)initWithCar:(id<Car>)car {
    if (self = [super init]) {
        self.car = car;
    }
    return self;
}
- (void)fly {
    NSLog(@"可以飞");
}
- (void)run1 {
    [self.car run1];
    [self fly];
}
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        RunCar *car = [[RunCar alloc] init];
        [car run1];
        NSLog(@"-----------1");
        
        SwimDecorator *swimCar = [[SwimDecorator alloc]initWithCar:car];
        [swimCar run1];
        NSLog(@"-----------2");
        
        FlyDecorator *flyCar = [[FlyDecorator alloc]initWithCar:swimCar];
        [flyCar run1];
        NSLog(@"-----------3");
    }
    return 0;
}
/*
汽车在行驶
-----------1
汽车在行驶
可以游
-----------2
汽车在行驶
可以游
可以飞
-----------3
*/

用处

主要解决继承关系过于复杂的问题,通过组合替代继承。

分类和装饰器模式的细微区别:

iOS中一般将分类、扩展看作是装饰模式。需要注意分类是在运行时决议的,扩展是在编译时。

另外:

  1. 分类添加属性关联对象
  2. 分类重写被装饰者的方法会"覆盖"
  3. 不能为系统类添加扩展
  4. 扩展只以声明的形式存在,多数情况下寄生于宿主类的.m

优点

  1. 比静态继承更灵活
  2. 避免在层次结构高层的类有太多的特征
    可以先定义一个简单的类,用装饰器者逐渐的添加功能。

缺点

  1. Decorator与它的Component不一样
    Decorator是一个透明的包装。如果我们从对象标识的观点出发,一个被装饰了的组件与这个组件是有差别的,因此,使用装饰时不应该依赖对象标识。
  2. 有许多小对象
    采用装饰器模式进行系统设计往往会产生许多看上去类似的小对象,这些对象仅仅在他们相互连接的方式上有所不同,而不是他们的类或是他们的属性值有所不同。尽管对于那些了解系统的人来说,很容易对他们进行定制,但是很难学习这些系统,排错也很困难。

相关文章

网友评论

      本文标题:装饰器模式(Decorator Pattern)

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