Oh!Coder

Coding Life

Objective C--建造者模式

| Comments

今天和大家一起分享的是建造者模式。

如果你需要将一个复杂对象的构建于它的表示分离,使得同样的构建过程可以创建不同的表示的意图时,那我们就需要这个模式,建造者模式又叫生成器模式。建造者模式可以将一个产品的内部表象与产品的生成过程分割开来,从而可以使一个建造过程生成具有不同的内部表象的产品对象。如果我们用了建造者模式,那么用户就只需要指定需要建造的类型就可以得到它们,而具体建造的过程和细节就不需知道了。

下面给出建造者模式的定义:

建造者模式(Builder),将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

其实,基本上来说,建造者模式是在当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时适用的模式。

下面,给大家呈现一下建造者模式的类结构图:

pic

让我们简单了解一下上面这张图中各个类表示的意思。其中Builder是为创建一个Product对象指定的抽象接口,这里面的Product顾名思义,就是我们要最终展现的具体产品类。继承自Builder接口的ConcreteBuilder类,是具体建造者,构造和装配各个部件。那么Director是什么呢?它是指挥具体建造者构建产品的总指挥,相当于一个指挥员。好吧,说的有些抽象,下面给大家展示一下简单的代码实现,大家可以慢慢体会一下。

注意:本文所有代码均在ARC环境下编译通过。

  • Product类接口
1
2
3
4
5
6
7
8
9
#import <Foundation/Foundation.h>

@interface Product :NSObject{
@private NSMutableString *mus;
}
-(Product*)MyInit;
-(void)Add:(NSString*)s;
-(void)Show;
@end
  • Product类实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#import "Product.h"

@implementation Product
-(Product*)MyInit{
    mus= [NSMutableString stringWithString:@""];
    return self;
}
-(void)Add:(NSString*)s{
    [mus appendString:s];
    [mus appendString:@"\n"];
}
-(void)Show{
    NSLog(@"The Parts are: %@",mus);
}
@end
  • Builder类接口
1
2
3
4
5
6
7
8
#import <Foundation/Foundation.h>

@class Product;
@interface Builder:NSObject
-(void)BuildPartA;
-(void)BuildPartB;
-(Product*)GetResult;
@end
  • Builder类实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#import "Builder.h"
#import "Product.h"

@implementation Builder
-(void)BuildPartA{
    return;
}
-(void)BuildPartB{
    return;
}
-(Product*)GetResult{
    return [[Product alloc]init];
}
@end
  • ConcreteBuilder1类接口
1
2
3
4
5
6
7
8
#import "Builder.h"

@class Product;
@interface ConcreteBuilder1:Builder{
@private Product *pro;
}
-(ConcreteBuilder1*)MyInit;
@end
  • ConcreteBuilder1类实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#import "ConcreteBuilder1.h"
#import "Product.h"

@implementation ConcreteBuilder1
-(ConcreteBuilder1*)MyInit{
    pro= [[Product alloc]MyInit];
    return self;
}
-(void)BuildPartA{
    [pro Add:@"部件A"];
}
-(void)BuildPartB{
    [pro Add:@"部件B"];
}
-(Product*)GetResult{
    return pro;
}
@end
  • ConcreteBuilder2类接口
1
2
3
4
5
6
7
8
#import "Builder.h"

@class Product;
@interface ConcreteBuilder2:Builder{
@private Product *pro;
}
-(ConcreteBuilder2*)MyInit;
@end
  • ConcreteBuilder2类实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#import "ConcreteBuilder2.h"
#import "Product.h"

@implementation ConcreteBuilder2
-(ConcreteBuilder2*)MyInit{
    pro= [[Product alloc]MyInit];
    return self;
}
-(void)BuildPartA{
    [pro Add:@"部件X"];
}
-(void)BuildPartB{
    [pro Add:@"部件Y"];
}
-(Product*)GetResult{
   return pro;
}
@end
  • Director类接口
1
2
3
4
5
6
#import <Foundation/Foundation.h>

@class Builder;
@interface Director:NSObject
-(void)Construct:(Builder*)builder;
@end
  • Director类实现
1
2
3
4
5
6
7
8
9
#import "Director.h"
#import "Builder.h"

@implementation Director
-(void)Construct:(Builder*)builder{
    [builder    BuildPartA];
    [builder    BuildPartB];
}
@end
  • Main方法调用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#import <Foundation/Foundation.h>
#import "Director.h"
#import "ConcreteBuilder1.h"
#import "ConcreteBuilder2.h"
#import "Product.h"  

int main(int argc,const char * argv[])
{
    @autoreleasepool{
        Director *director = [[Director alloc]init];
        Builder *b1 = [[ConcreteBuilder1 alloc]MyInit];
        Builder *b2 = [[ConcreteBuilder2 alloc]MyInit];
        [director Construct:b1];
        Product *p1 = [b1 GetResult];
        [p1 Show];
        [director Construct:b2];
        Product *p2 = [b2 GetResult];
        [p2 Show];
    }
    return 0;
}

好啦,以上是类结构图中所需要简单实现的代码。

最后说一下,一般都什么时候可能会用到建造者模式。一般来说,建造者模式主要用于创建一些复杂的对象,这些对象内部构建的建造顺序通常是稳定的,但对象内部的构建通常面临着复杂的变化,那么建造者模式的好处就是使得建造代码和表示代码分离,由于建造者隐藏了该产品是如何组装的,所以若需要改变一个产品的内部表示,只需要再定义一个具体的建造者就可以了。

Comments