大话设计模式之装饰模式代码实现-OC版

    这篇文章是我对大话设计模式-装饰模式中所举三个例子的OC代码实现,所以配合大话设计模式这本书来阅读更容易理解装饰模式的概念。OK,按照本书的思路,让我们首先来看一下‘小菜扮靓第一版’的代码实现:

  Person.h
 -(void)wearTShirts;
-(void)wearBigTrouser;//垮裤
-(void)wearSneakers;//破球鞋
-(void)wearSuit;//西装
-(void)wearTie;//领带
-(void)wearLeatherShoes;
-(void)showName:(NSString *)name;


Person.m
-(void)wearTShirts;
{
    NSLog(@"大T恤");
}
-(void)wearBigTrouser;
{
    NSLog(@"垮裤");
}
-(void)wearSneakers;
{
    NSLog(@"破球鞋");
}
-(void)wearSuit;
{
    NSLog(@"西装");
}
-(void)wearTie;
{
    NSLog(@"领带");
}
-(void)wearLeatherShoes;
{
    NSLog(@"皮鞋");
}
-(void)showName:(NSString *)name;
{
    NSLog(@"装扮的%@",name);
}


        main.m
        Person *per=[Person new];
        [per wearTShirts];
        [per wearBigTrouser];
        [per wearLeatherShoes];
        [per showName:@"张三"];

打印:

2015-05-21 20:05:02.537 第一次[12080:1856669] 大T恤
2015-05-21 20:05:02.539 第一次[12080:1856669] 垮裤
2015-05-21 20:05:02.539 第一次[12080:1856669] 皮鞋
2015-05-21 20:05:02.539 第一次[12080:1856669] 装扮的张三

分析:不易扩展,代码繁琐;


'小菜扮靓第二版'

/*Person是一个类,Finery是TShirts、BigTrouser、Sneakers的父类,继承Finery的show装扮方法*/
Person.h
-(void)showName:(NSString *)name;

Person.m
-(void)showName:(NSString *)name
{
    NSLog(@"装扮的%@",name);
}


Finery.h
-(void)show;

Finery.m
-(void)show
{
    NSLog(@"穿衣服");
}


TShirts.m
-(void)show
{
   NSLog(@"大T恤");
}


BigTrouser.m
-(void)show
{
    NSLog(@"垮裤");
}


Sneakers.m
-(void)show
{
    NSLog(@"破球鞋");
}

        main.m//导入头文件
        Person *per=[Person new];
        Finery *fin=[Finery new];
        TShirts *tshirts=[TShirts new];
        BigTrouser *bigT=[BigTrouser new];
        Sneakers *sn=[Sneakers new];
        [per showName:@"张三"];
        [fin show];
        [tshirts show];
        [bigT show];
        [sn show];

打印:
2015-05-21 20:14:53.593 第二次[12117:1862009] 装扮的张三
2015-05-21 20:14:53.637 第二次[12117:1862009] 穿衣服
2015-05-21 20:14:53.638 第二次[12117:1862009] 大T恤
2015-05-21 20:14:53.638 第二次[12117:1862009] 垮裤
2015-05-21 20:14:53.638 第二次[12117:1862009] 破球鞋

分析:不能把所需的功能按照正确的顺序串联起来进行控制

‘小菜扮靓第三版’

/*Person是父类,Decorator是子类,TShirts、BigTrouser、Leathershoes继承自Decorator*/

Person.h
@property(strong ,nonatomic)NSString *name;
-(NSString *)show;

Person.m
-(NSString *)show
{
    return [NSString stringWithFormat:@"装扮的%@",_name];
}

/*Decorator类是装饰模式的精髓,通过赋值运算符'='将per2赋给per1,使per1可以调用per2,让程序更加灵活了*/
Decorator.h
//声明一个和父类同类型的属性per1
@property(strong ,nonatomic)Person *per1;
//声明和父类同类型的输入成员变量per2
-(void)setPerson:(Person *)per2;

Decorator.m
-(void)setPerson:(Person *)per2
{
    _per1=per2;
}
-(NSString *)show
{
    return _per1.show;
}

TShirts.m
-(NSString *)show
{
    return [NSString stringWithFormat:@"T恤 %@ ",[super show]];
}

BigTrouser.m
-(NSString *)show
{
    return [NSString stringWithFormat:@" 垮裤 %@ ",[super show]];
}

LeatherShoes.m
-(NSString *)show
{
    return [NSString stringWithFormat:@"皮鞋 %@",[super show]];
}

        main.m//导入头文件
        Person *per=[Person new];
        per.name=@"张三";
        NSLog(@"%@",per.show);
        TShirts *tshirt=[TShirts new];
        [tshirt setPerson:per];
        NSLog(@"%@",tshirt.show);
        BigTrouser *big=[BigTrouser new];
        [big setPerson:tshirt];
        NSLog(@"%@",big.show);
        LeatherShoes *lea=[LeatherShoes new];
        [lea setPerson:big];
        NSLog(@"%@",lea.show);

打印:
2015-05-21 20:29:48.114 第三次[12151:1868387] 装扮的张三
2015-05-21 20:29:48.115 第三次[12151:1868387] T恤 装扮的张三
2015-05-21 20:29:48.115 第三次[12151:1868387]  垮裤 T恤 装扮的张三  
2015-05-21 20:29:48.115 第三次[12151:1868387] 皮鞋  垮裤 T恤 装扮的张三  

    书上的例子到此为止,但是即便是第三次装饰的代码也由于实际情况省略了Component接口类,所以补充一个能基本展示装饰模式各部分功能的例子:
    对某个手机的内容功能扩展 首先,我们需要一个手机的接口或者抽象类,我这里就用抽象类来实现,代码如下:
@interface Phone : NSObject
-(NSString *)callNumber;
-(NSString *)sendMassage;
@end


@implementation Phone
-(NSString *)callNumber
{
    return @"Phone call GF";
}
-(NSString *)sendMassage
{
    return @"Phone send a massage to GF";
}
@end

    Phone也就是结构图中的Component,然后,我再来实现iphone手机类,这类要继承Phone,也就是图中ConcreteComponent类要继承Component,实现代码如下:
@interface Iphone : Phone
@end

@implementation Iphone
-(NSString *)callNumber
{
    return @"Using iphone6plus call GF";
}
-(NSString *)sendMassage
{
    return @"Using iphone6plus send a message to GF";
}
@end


    接下来我需要一个Decorator接口或者抽象类,实现代码如下:
@interface Decroato : Phone
@property(copy,nonatomic)Phone *phone;
-(void)setPhone:(Phone *)phones;
@end


@implementation Decroato
@synthesize phone;
-(void)setPhone:(Phone *)phones
{
    phone=phones;
}
-(NSString *)callNumber
{
    return phone.callNumber;
}
-(NSString *)sendMassage
{
    return phone.sendMassage;
}

@end

    正如结构图中,这个Decorator即继承了Phone,又包含了一个私有的Phone的对象。这样做的意义是:Decorator类又使用了另外一个Phone类。我们可以使用一个或多个Decorator对象来“装饰”一个Phone对象,且装饰后的对象仍然是一个Phone对象。在下来,我要实现内容(Content)的功能扩展,它们要继承自Decorator,代码如下:
@interface Content : Decroato
@end


@implementation Content
-(NSString *)callNumber
{
    return [NSString stringWithFormat:@"%@ say:I LOVE YOU",[super callNumber]];
}
-(NSString *)sendMassage
{
    return [NSString stringWithFormat:@"%@ say:I LOVE YOU",[super sendMassage]];
}

@end

    最后,用客户端程序验证一下:
        Phone *phone=[Iphone new];
        NSLog(@"%@",phone.callNumber);
        NSLog(@"%@",phone.sendMassage);
        Content *content=[Content new];
        [content setPhone:phone];
        NSLog(@"%@",content.callNumber);
        NSLog(@"%@",content.sendMassage);

打印:
2015-05-21 21:03:06.375 Decrotor[12220:1880459] Using iphone6plus call GF
2015-05-21 21:03:06.376 Decrotor[12220:1880459] Using iphone6plus send a message to GF
2015-05-21 21:03:06.376 Decrotor[12220:1880459] Using iphone6plus call GF say:I LOVE YOU
2015-05-21 21:03:06.376 Decrotor[12220:1880459] Using iphone6plus send a message to GF say:I LOVE YOU

OVER...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值