美文网首页
iOS开发之设计模式 - 装饰模式

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

作者: JoeyM | 来源:发表于2020-08-11 14:13 被阅读0次

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

    装饰模式

    继上一篇《策略模式》

    • 装饰模式,动态地 给一个对象添加一些额外的职责,就增加功能来说, 装饰模式比生成子类更灵活
    装饰模式
    • Component是定义一个对象接口, 可以给这些对象都没太的添加职责, ConcreteComponent是定义了一个锯条的对象,也可以给这个对象添加一些职责。Decorator,修饰出响雷, 继承了Component, 从外类来扩展Component类的功能, 但是对Component来说是无锡知道Decorator的存在的, 至于ConcreteDecorator就是具体的装饰对象, 起到给Component添加职责的功能

    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
    
    
    • 装饰模式是利用SetComponent来对对象进行包装的, 这样每个装饰的对象的实现就和如何使用这个对象分离开了。 每个装饰对象只关心自己的功能, 不需要关心如何被添加到对象链当中

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

    
    @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恤
    装扮的小白
    
    • 当我写完第一感觉就是,shit!, 王德发!?~ ,不知道你跟我有没有一样的想法, 既然是人穿(装饰)服饰。 为什么decorate这个方法 传入的东西有人有衣服? 还有衣服为什么还会继承人?难道是按照顺序来的?A调用B,B调用C ...。 看样子道行尚浅。 有待磨炼

    稍稍总结

    • 其实装饰模式,是为了自己已有的功能,动态地添加更多功能的一种方式。

    • 具体什么时候用这个设计模式呢?

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

    • 好处,就是把勒种的装饰功能从勒种搬移去除,可以简化原有的类。 而且有效的把类的核心职责和装饰功能区分开了,去除了相关类中重复的装饰逻辑

    • 但是他缺点就是装饰的顺序很重要

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

    下一篇 代理模式

    相关文章

      网友评论

          本文标题:iOS开发之设计模式 - 装饰模式

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