iOS开发之设计模式 - 装饰模式

2020-08-11  本文已影响0人  JoeyM

由《大话设计模式 - 装饰模式》的OC和部分Swift的语言转义

装饰模式

继上一篇《策略模式》

装饰模式

OC

// Compoenet类
@interface Component : NSObject
- (void)operation;
@end

@implementation Component
- (void)operation {}
@end

// ConcreteComponent类
@interface ConcreteComponent : Component
@end

@implementation ConcreteComponent
- (void)operation
{
    NSLog(@"具体对象的操作");
}
@end

// Decorator类
@interface Decorator : Component
@property (nonatomic, strong) Component *priviteComponent;
@end

@implementation Decorator

- (void)setPriviteComponent:(Component *)priviteComponent
{
    _priviteComponent = priviteComponent;
}

- (void)operation
{
    if (_priviteComponent != nil) {
        // 重写 operation方法, 实际执行的是 Component的 operation
        // 父类属性,调用父类方法而已, 别紧张
        [_priviteComponent operation];
    }
}
@end


@interface ConcreteDecoratorA : Decorator
@end

@implementation ConcreteDecoratorA

- (void)operation
{
    [super operation];
    NSLog(@"%@", @"ConcreteDecoratorA");
}
@end


@interface ConcreteDecoratorB : Decorator
- (void)concreteDecoratorBUniqueMethod; // B特有的方法
@end

@implementation ConcreteDecoratorB

- (void)operation
{
    [super operation];
    NSLog(@"%@", @"ConcreteDecoratorB");
    [self concreteDecoratorBUniqueMethod];
}

- (void)concreteDecoratorBUniqueMethod {
    NSLog(@"B特有的方法");
}
@end


@interface ViewController2 ()
@end

@implementation ViewController2

- (void)viewDidLoad {
    [super viewDidLoad];
    
    ConcreteComponent *c = [ConcreteComponent new];
    ConcreteDecoratorA *cA = [ConcreteDecoratorA new];
    ConcreteDecoratorB *cB = [ConcreteDecoratorB new];
    
    [cA setPriviteComponent:c];
//    [cB setPriviteComponent:cA];
    [cB operation];
    
}

// 结果打印 
ConcreteDecoratorB
B特有的方法

@end

还是大话设计模式的样例,模仿人穿衣服的代码。


@interface Person : NSObject
- (instancetype)person:(NSString *)name;
- (void)show;
@end

@implementation Person
{
    NSString *_name;
}

- (instancetype)person:(NSString *)name {
    _name = name;
    return self;
}

- (void)show {
    NSLog(@"装扮的%@", _name);
}
@end


// 服饰类
@interface Finery : Person
- (void)decorate:(Person *)component;
@end

@implementation Finery
{
    Person *_component;
}

- (void)decorate:(Person *)component
{
    _component = component;
}

- (void)show
{
    if (_component != nil) {
        [_component show]; // 父类属性调用父类
    }
}
@end

// 具体服饰类
@interface TShirts : Finery
@end

@implementation TShirts

- (void)show {
    NSLog(@"T恤");
    [super show];
}
@end

@interface BigTrouser : Finery
@end

@implementation BigTrouser

- (void)show {
    NSLog(@"大裤子");
    [super show];
}
@end

@interface NormalTrouser : Finery
@end

@implementation NormalTrouser

- (void)show {
    NSLog(@"NormalTrouser");
    [super show];
}
@end


@interface ViewController2 ()
@end

@implementation ViewController2

- (void)viewDidLoad {
    [super viewDidLoad];
    
    Person *p1 = [[Person new] person:@"Joey"];
    NSLog(@"第一种装扮");
    
    TShirts *ts = [TShirts new];
    BigTrouser *bt = [BigTrouser new];
    [ts decorate:p1];
    [bt decorate:ts];
    [bt show];
    NSLog(@"=============");
    
    Person *p2 = [[Person new] person:@"小白"];
    NSLog(@"第2种装扮");

    TShirts *ts2 = [TShirts new];
    NormalTrouser *bt2 = [NormalTrouser new];
    [ts2 decorate:p2];
    [bt2 decorate:ts2];
    [bt2 show];
}

@end

// 打印结果
第一种装扮
大裤子
T恤
装扮的Joey
=============
第2种装扮
NormalTrouser
T恤
装扮的小白

稍稍总结

当系统需要新功能的时候, 是向旧的类中添加新的代码。 这些新家的代码通常装饰了原有类的核心职责或者主要行为, 比如上面的代码逻辑中 要新增一条短裤来装饰Joey。 这种做法的问题在于, 他们在主类中加入了新的字段, 新的方法, 和新的逻辑,从而增加了主类的复杂度, 而这些新加入的东西仅仅是为了满足一下只在某种特定的情况下才会执行的特殊行为的需要, 而装饰模式却提供了一个好的解决方案,它吧每个要装饰的功能放在单独的类中,并让这个类包装他所想要的服饰的对象, 因此, 当需要执行特殊行为时, 客户端代码就可以在运行时根据需要有选择滴、按顺序地使用装饰功能包装对象了。

然而了解了之后,我发现,我还是不想用这个模式。 囧 _

下一篇 代理模式

上一篇下一篇

猜你喜欢

热点阅读