OC装饰模式

穿衣问题,要求写一个给人搭配不同服饰的系统,那种可以换各种各样衣服和裤子的服饰系统,如下图:

首先排除这样的结果设计,如果我需要新增加超人的服饰设计,又得更改Person类,很明显违背了开发-封闭原则(ocp,对扩展的开放,对修改的封闭)。其实把这些服饰类写成子类就好,代码结构

如此,需要增加超人的装扮 ,只需要增加子类即可。不需要对已有的代码进行修改。但是这样还打不到最好,我们需要在控制器里面来开辟诸如'破球鞋'、“垮裤”等对象,将他们一个词一个词的显示出来,就好比是在众目睽睽下穿衣服。

对于这些,应当去优化它们。就可以用到装饰模式:动态的给一个对象添加一些额外的职能,就增加功能来说,装饰模式比添加子类更加灵活。无论是衣服、鞋子、裤子等,其实我们都可以把它理解为对Person的装饰,那么有下图结构:

Person类

1 #import <Foundation/Foundation.h>
2 
3 @interface Person : NSObject
4 @property(copy,nonatomic)NSString *name;
5 -(instancetype)initWithName:(NSString *)name;
6 -(void)zhuangban;
7 @end
 1 #import "Person.h"
 2 
 3 @implementation Person
 4 - (instancetype)initWithName:(NSString *)name
 5 {
 6     self = [super init];
 7     if (self) {
 8         _name=name;
 9     }
10     return self;
11 }
12 -(void)zhuangban
13 {
14     NSLog(@"装扮的是:%@",_name);
15 }
16 @end

Clothing类   继承与人类

1 #import "Person.h"
2 
3 @interface Clothing : Person  //服装类继承与人类
4 @property(strong,nonatomic) Person *decorate;//装饰
5 -(instancetype)initWithDecorate:(Person *)decorate;
6 @end
 1 #import "Clothing.h"
 2 
 3 @implementation Clothing
 4 -(instancetype)initWithDecorate:(Person *)decorate
 5 {
 6     if (self=[super init]) {
 7         _decorate=decorate;
 8     }
 9     return self;
10 }
11 
12 -(void)zhuangban
13 {
14     if (self.decorate) {
15         [self.decorate zhuangban];
16     }
17 }
18 @end

TShirts类

1 #import "Clothing.h"
2 
3 @interface TShirts : Clothing
4 
5 @end
1 #import "TShirts.h"
2 
3 @implementation TShirts
4 -(void)zhuangban
5 {
6     [super zhuangban];
7     NSLog(@"破T恤");
8 }
9 @end

Pants类

1 #import "Clothing.h"
2 
3 @interface Pants : Clothing
4 
5 @end
 1 #import "Pants.h"
 2 
 3 @implementation Pants
 4 -(void)zhuangban
 5 {
 6     [super zhuangban];
 7     NSLog(@"破裤子");
 8 }
 9 
10 
11 @end

Shoe类

1 #import "Clothing.h"
2 
3 @interface Shoe : Clothing
4 
5 @end
1 #import "Shoe.h"
2 
3 @implementation Shoe
4 -(void)zhuangban
5 {
6     [super zhuangban];
7     NSLog(@"破鞋子");
8 }
9 @end

在main.m里

 1 #import <Foundation/Foundation.h>
 2 #import "Pants.h"
 3 #import "Clothing.h"
 4 #import "TShirts.h"
 5 #import "Pants.h"
 6 #import "Shoe.h"
 7 
 8 
 9 int main(int argc, const char * argv[]) {
10     @autoreleasepool {
11         Person *person=[[Person alloc]initWithName:@"叫花子"];
12         Clothing *clothing=[[Clothing alloc]initWithDecorate:(person)];
13         TShirts *tshirts=[TShirts new];
14         Pants *pants=[Pants new];
15         Shoe *shoe=[Shoe new];
16         
17         //装饰的顺序可以任意的选择
18         //装饰一
19         tshirts.decorate=clothing;
20         pants.decorate=tshirts;
21         shoe.decorate=pants;
22         [shoe zhuangban];
23         
24         //装饰二
25         shoe.decorate=clothing;
26         tshirts.decorate=shoe;
27         pants.decorate=tshirts;
28         [pants zhuangban];
29         
30         
31         
32     }
33     return 0;
34 }

运行效果

2016-03-06 22:06:08.089 装饰模式[1280:78257] 装扮的是:叫花子

2016-03-06 22:06:08.091 装饰模式[1280:78257] T

2016-03-06 22:06:08.091 装饰模式[1280:78257] 破裤子

2016-03-06 22:06:08.091 装饰模式[1280:78257] 破鞋子

2016-03-06 22:06:08.091 装饰模式[1280:78257] 装扮的是:叫花子

2016-03-06 22:06:08.092 装饰模式[1280:78257] 破鞋子

2016-03-06 22:06:08.092 装饰模式[1280:78257] T

2016-03-06 22:06:08.092 装饰模式[1280:78257] 破裤子

Program ended with exit code: 0

装饰模式的优点:

  • 把类中的装饰功能从类中搬移出去,这样可以简化原有的类。
  • 当有效的把类中的核心功能和装饰功能区分开了,可以去除相关类中重复的装饰逻辑。

 

posted @ 2016-03-06 22:07  远方的狼  阅读(400)  评论(0编辑  收藏  举报