zoukankan      html  css  js  c++  java
  • IOS设计模式浅析之建造者模式(Builder)

    定义                                                                                                        

      "将一个复杂对象的构建与它的表现分离,使得同样的构建过程可以创建不同的表现"

    • 最初的定义出现于《设计模式》(Addison-Wesley,1994)

      看这个概念,可能感觉很是抽象,能看懂但是不知道有什么用。我们打一个比方来理解上面的定义。打比方之前,咱们先来聊聊这个设计模式是干什么用的?我们为什么要用这个模式呢?建造者模式负责将构建复杂对象的过程和它的部件解耦,也就是过程和部件的解耦。比如说汽车,是一个很复杂的对象,它有很多的部件,车轮、发动机、座椅、车门、油箱等等;它的组装过程也很复杂(需要专业人士按步骤进行装配),建造者模式就是为了将部件和组装过程分开的。同样的,我们使用的计算机也一样,有很多的部件,组装过程也很复杂(当然,对于我们这样的专业人士可能感觉不复杂)。建造者模式最大的好处就是使得构建过程和表现分离,因此若需要改变一个产品的表现,只需要重新定义一个具体的建造者就可以了(这句话理解起来有点难度,还是拿车来打比方,我们将车的组装过程独立出来,用这个组装过程,我们即可以组装宝马车,也可以组装奔驰车,或者其他的车型,我们只需要重新定义一个具体的建造者(用于产品表现的类)就可以了)

    动机                                                                                                        

      在软件系统中,有时候会遇到一个复杂对象(比如说上面例子中的汽车)的创建,它通常由几个部分的子对象采用一定的算法(过程)构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化(比如上面例子中,各种车型用的车门、方向盘、发动机等,是不一样的),但是将各个部分组合在一起的算法(过程)是相对稳定的

      建造者模式就是在这样的需求下诞生的,它封装了变化点(组成部分),使得同样的构建过程可以创建不同的表现。

    结构图                                                                                                    

     

      从结构图可以看到,生成器模式有两个重要的角色:Director(指导者)Builder(建造者)Director知道Builder应该建造什么(建造的过程)Builder知道如何建造(表现)。在Director类中定义了一个construct方法,指导具体的建造者ConcreteBuilder的对象去buildPartBuilder是一个抽象接口(协议),该协议中包含建造各个部分的方法(buildPart),用来构建实际的产品Product,另外还有一个getResult方法,用来向客户端返回构建完成的Product

      这样说不知道大家是不是感觉很抽象?那咱们用一个生活的例子来通俗点说。比如现在我要在老家修一个房子,首先我不知道怎么修房子(砌墙,缺建造者),然后我也不知道怎么设计(修几个房间,房间的布局,房间的窗户怎么设计等等,缺指导者),于是我找来一帮民工(建造者),他们会砌墙;另外我还得找设计师(指导者),他知道怎么设计;最后,我还要确保民工(建造者)听设计师(指导者)的指导,哪里需要砌一堵墙,哪里需要安装窗户等等,这样民工(建造者)就开始盖房子,在这个建造过程中,设计师(指导者)只负责设计和下达命令。房子建成功后,民工(建造者)向我交房。说白了,就是Director(指导者)负责把控宏观方面(过程)Builder(建造者)负责把控微观方面(表现)

      下面咱们还是通过代码来说明这个结构图。

    建造者模式的代码                                                                                     

      Product.m(部分代码)

     1 - (id)init
     2 
     3 {
     4 
     5     self = [superinit];
     6 
     7     
     8 
     9     if (self)
    10 
    11     {
    12 
    13         arrParts = [NSMutableArrayarray];
    14 
    15     }
    16 
    17     
    18 
    19     returnself;
    20 
    21 }
    22 
    23  
    24 
    25 - (void)addPart:(NSString *)part
    26 
    27 {
    28 
    29     [arrPartsaddObject:part];
    30 
    31 }
    32 
    33  
    34 
    35 - (void)show
    36 
    37 {
    38 
    39     for (NSString *strPart inarrParts)
    40 
    41     {
    42 
    43         NSLog(@"%@",strPart);
    44 
    45     }
    46 
    47 }

      Builder.h(部分代码)

     1 @classProduct;
     2 
     3 @protocol Builder <NSObject>
     4 
     5  
     6 
     7 - (void)addPartOne;
     8 
     9 - (void)addPartTwo;
    10 
    11 - (Product *)getResult;
    12 
    13  
    14 
    15 @end

      ConcreteBuilder.m(部分代码)

     1 - (id)init
     2 
     3 {
     4 
     5     self = [superinit];
     6 
     7     
     8 
     9     if (self)
    10 
    11     {
    12 
    13         product = [[Productalloc] init];
    14 
    15     }
    16 
    17     
    18 
    19     returnself;
    20 
    21 }
    22 
    23  
    24 
    25 - (void)addPartOne
    26 
    27 {
    28 
    29     [productaddPart:@"part one"];
    30 
    31 }
    32 
    33  
    34 
    35 - (void)addPartTwo
    36 
    37 {
    38 
    39     [productaddPart:@"part two"];
    40 
    41 }
    42 
    43  
    44 
    45 - (Product *)getResult
    46 
    47 {
    48 
    49     returnproduct;
    50 
    51 }
    52 
    53 Director.m(部分代码):
    54 
    55 - (void)construct:(id<Builder>)builder
    56 
    57 {
    58 
    59     [builder addPartOne];
    60 
    61     [builder addPartTwo];
    62 
    63 }

      客户端调用代码:

     1         Director *director = [[Directoralloc] init];
     2 
     3         id<Builder> builder = [[ConcreteBuilderalloc] init];
     4 
     5         
     6 
     7         [director construct:builder];
     8 
     9         Product *product = [builder getResult];
    10 
    11         [product show];
    12 
    13         
    14 
    15         [builder release];
    16 
    17         [director release];

    何时使用建造者模式                                                                                 

      建造者模式常用于如下情形:

    • 需要创建涉及各种部件的复杂对象。创建对象的算法应该独立于部件的装配方式。
    • 构建过程需要以不同的方式构建对象。

      源码下载  返回目录

  • 相关阅读:
    用WinForm写的员工考勤项目!!!!!!
    洛谷P1892《[BOI2003]团伙》
    洛谷P1821《[USACO07FEB]银牛派对Silver Cow Party》
    洛谷P1149《火柴棒等式》
    2017 国庆清北刷题冲刺班《角谷猜想》
    洛谷P2330《[SCOI2005]繁忙的都市》
    洛谷P1955《[NOI2015]程序自动分析》
    洛谷P1536《村村通》
    Windows 10 体验记
    洛谷P1102《A-B数对》
  • 原文地址:https://www.cnblogs.com/eagle927183/p/3468340.html
Copyright © 2011-2022 走看看