您的位置:首页 > 编程语言

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

2015-05-21 21:06 399 查看
这篇文章是我对大话设计模式-装饰模式中所举三个例子的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...
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: