Decorator(装饰着模式)

来源:互联网 发布:淘宝店铺游戏专营 编辑:程序博客网 时间:2024/05/16 07:40

定义: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