Decorator(装饰着模式)

定义:Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.

装饰模式是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象


关于 Decorator,我实在想不到什么简单的例子,于是 就只能直接用一个稍微复杂点的例子作为开场了


例子:玩过梦幻西游什么的么。。。。然后我对这个例子稍微改动改动,我们有一个英雄 英雄有他的基础伤害,然后 可以装备一些武器(就拿2个好了)比如 剑和头盔,这两个武器可以帮组英雄添加不同的攻击力,然后叫你写这样一个代码。

这个例子中,我确实不知道除了Decorate的话,你会怎么做。。(千万不要用if。。。。因为有好多好多武器。。我只是拿2个做例子)

好了 废话不多说,来看看Decorate是怎么工作的

首先 你会想到至少 我们 有一个叫做Hero的类 和Sword  Helmet两种武器。这3个类都应该有一个共同的方法 getAttackNum,这里 如果我们分的更细一点的话,Hero 和 两种武器是不一样的,所以 两种武器不应该和Hero平行,那么 就让两种武器同时继承自一个叫做Decorator的类(实际上两种武器就是对Hero的一种装饰),代码如下

#import <Foundation/Foundation.h>

@interface Component : NSObject

-(int) getAttackNum;

@end

#import "Component.h"

@interface Hero : Component

@end

#import "Component.h"

@interface Decorator : Component

@end

#import "Decorator.h"

@interface Helmet : Decorator

@end

#import "Decorator.h"

@interface Sword : Decorator

@end

5个类。。。。希望你还有耐心读下去,但是这5个类都不复杂,主要是弄清楚他们的继承关系。目前,我们只提供了一个getAttackNum的方法,但是没有任何一个地方给出了实现,接下去 我们要开始实现这个方法了。

最重要的一步。。。我们在Component中添加一个变量,这个变量就是一个Component类型的变量,变成这样

#import <Foundation/Foundation.h>

@interface Component : NSObject

@property (nonatomic,strong) Component* component;

-(int) getAttackNum;

@end

这样 所有的子类都有了这个变量,因此 我们在给hero添加decorator的时候 只要

hero.component=[[Sword alloc] init];


但其实 这不是我们想要的效果,因为我们希望 hero 可以装饰多个decorator。好了 这里 也就是最关键的地方了,我们的所有Decorator都是继承自Component,也就是说 Decorator也有这个component的变量。那么 我们装饰的时候 就可以这样装饰让 sword装饰Helmet,然后让Helmet装饰Hero,代码变成这样

    Sword* sword=[[Swordalloc]init];

   Helmet* helmet=[[Helmetalloc]init];

    helmet.component=sword;

    hero.component=helmet;


这样 一层一层的装饰以后,我们的hero其实就已经装饰了 helmet 和 sword下面 

就是最后一步 实现getAttackNum了,首先 我们的抽象类 Component没有变化

#import <Foundation/Foundation.h>

@interface Component : NSObject

@property (nonatomic,strong) Component* component;

-(int) getAttackNum;

@end

然后 Hero去实现getAttackNum

#import "Component.h"

@interface Hero : Component

@end

#import "Hero.h"

@implementation Hero

-(int) getAttackNum
{
    int attckNum=10;
    if (self.component!=nil)
    {
        attckNum+=[self.component getAttackNum];
    }
    return attckNum;
}

@end

在废话一句,这里假定英雄没有武器的攻击力是10,然后 我们检查 英雄是否有component,如果有得话,程序会去计算这个component的攻击力(也就是sword)

然后看看Decorator,也不需要做任何的改动

#import "Component.h"

@interface Decorator : Component

@end

关于这里为什么要插入这个Decorator的类,你可以理解为 这些装饰 比如 武器啊 头盔啊 他们还会有一些共同点 这些共同点是Hero没有的,只是在这个例子中省略了

最后 我们实现Sword和Helmet这两个类

#import "Decorator.h"

@interface Sword : Decorator

@end

#import "Helmet.h"

@implementation Helmet

-(int) getAttackNum
{
    int attckNum=1;
    if (self.component!=nil)
    {
        attckNum+=[self.component getAttackNum];
    }
    return attckNum;
}

@end

假定它的attckNum是1,同样 因为Helmet的Component是Sword,因为,这里还会去找Sword的AttackNum。

到了这里 我相信你可以自己写出Sword的代码了

#import "Decorator.h"

@interface Sword : Decorator

@end

#import "Sword.h"

@implementation Sword

-(int) getAttackNum
{
    int attckNum=2;
    if (self.component!=nil)
    {
        attckNum+=[self.component getAttackNum];
    }
    return attckNum;
}

@end

这一步,因为这里的sword的component是空,所以到这里不会继续递归下去,于是 我们就得到了 被装饰了Sword和Helmet的Hero的AttackNum了。

这就是Decorator模式,Decorator在没有改变原来类的继承关系情况下,如果我们还需要一个叫做Shoes的装饰,只需要在添加一个类 然后给Sword装饰Shoes即可,这样又很好的保证了OCP原则

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值