`
tailsherry
  • 浏览: 134965 次
  • 性别: Icon_minigender_1
  • 来自: 珠海
社区版块
存档分类
最新评论

建造模式(Builder)

UML 
阅读更多

一、介绍
建造模式(Builder)主要是为了将一个复杂的对象的构建和它的实际表示分离,使得同样的构建过程可以创建不同的表示。

 

建造模式是一步一步创建一个复杂的对象,它允许用户可以只通过指定复杂对象的类型和内容就可以构建它们,用户不知道内部的具体构建细节,该模式非常类似与抽象工厂模式。

 

 

二、实例
在看建造模式的实例之前,请最好先理解抽象工厂模式(Abstract Factory) ,这里也依旧是上次那个炖汤的例子!先看看这个Builder模式的大致的UML图。

Builder Design Pattern

 

首先定义一个抽象的建造类SoupBuffetBuilder,和抽象工厂模式一样,在这个抽象类里定义了各种炖汤的制作方法。值得注意的是,这里和抽象工厂不同的是,其中额外定义了一个建造和获取目标集合对象的方法buildSoupBuffet()和getSoupBuffet(),所有的builder都是围绕这个soupBuffet展开,而不再直接返回一种炖汤。

 abstract class SoupBuffetBuilder {    
    SoupBuffet soupBuffet;    
            
    public SoupBuffet getSoupBuffet() {    
        return soupBuffet;    
    }    
        
    public void buildSoupBuffet() {    
        soupBuffet = new SoupBuffet();    
    }    
        
    public abstract void setSoupBuffetName();    
            
    public void buildChickenSoup() {    
        soupBuffet.chickenSoup = new ChickenSoup();    
    }    
    public void buildClamChowder() {    
        soupBuffet.clamChowder = new ClamChowder();    
    }    
    public void buildFishChowder() {    
        soupBuffet.fishChowder = new FishChowder();    
    }    
    public void buildMinnestrone() {    
        soupBuffet.minnestrone = new Minnestrone();    
    }    
    public void buildPastaFazul() {    
        soupBuffet.pastaFazul = new PastaFazul();    
    }    
    public void buildTofuSoup() {    
        soupBuffet.tofuSoup = new TofuSoup();    
    }    
    public void buildVegetableSoup() {    
        soupBuffet.vegetableSoup = new VegetableSoup();    
    }    
}

 

同样,接下来我们实例化这个builder抽象类和其中相关的子对象,类似于抽象工厂模式中的实例化过程。[波士顿]炖汤加工中心的代码BostonSoupBuffetBuilder如下:

class BostonSoupBuffetBuilder extends SoupBuffetBuilder {    
    public void buildClamChowder() {    
       soupBuffet.clamChowder = new BostonClamChowder();    
    }    
    public void buildFishChowder() {    
       soupBuffet.fishChowder = new BostonFishChowder();    
    }        
        
    public void setSoupBuffetName() {    
       soupBuffet.soupBuffetName = "Boston Soup Buffet";    
    }    
}    
   
class BostonClamChowder extends ClamChowder {    
    public BostonClamChowder() {    
        soupName = "QuahogChowder";    
        soupIngredients.clear();            
        soupIngredients.add("1 Pound Fresh Quahogs");    
        soupIngredients.add("1 cup corn");        
        soupIngredients.add("1/2 cup heavy cream");    
        soupIngredients.add("1/4 cup butter");        
        soupIngredients.add("1/4 cup potato chips");    
    }    
}    
   
class BostonFishChowder extends FishChowder {    
    public BostonFishChowder() {    
        soupName = "ScrodFishChowder";    
        soupIngredients.clear();            
        soupIngredients.add("1 Pound Fresh Scrod");    
        soupIngredients.add("1 cup corn");        
        soupIngredients.add("1/2 cup heavy cream");    
        soupIngredients.add("1/4 cup butter");        
        soupIngredients.add("1/4 cup potato chips");    
    }    
}  

 

[檀香山]炖汤加工中心,代码HonoluluSoupBuffetBuilder内容如下:
class HonoluluSoupBuffetBuilder extends SoupBuffetBuilder {    
    public void buildClamChowder() {    
        soupBuffet.clamChowder = new HonoluluClamChowder();    
    }    
    public void buildFishChowder() {    
        soupBuffet.fishChowder = new HonoluluFishChowder();    
    }    
        
    public void setSoupBuffetName() {    
        soupBuffet.soupBuffetName = "Honolulu Soup Buffet";    
    }    
}    
   
class HonoluluClamChowder extends ClamChowder {    
    public HonoluluClamChowder() {    
        soupName = "PacificClamChowder";    
        soupIngredients.clear();            
        soupIngredients.add("1 Pound Fresh Pacific Clams");    
        soupIngredients.add("1 cup pineapple chunks");    
        soupIngredients.add("1/2 cup coconut milk");    
        soupIngredients.add("1/4 cup SPAM");        
        soupIngredients.add("1/4 cup taro chips");    
    }    
}    
   
class HonoluluFishChowder extends FishChowder {    
    public HonoluluFishChowder() {    
        soupName = "OpakapakaFishChowder";    
        soupIngredients.clear();            
        soupIngredients.add("1 Pound Fresh Opakapaka Fish");    
        soupIngredients.add("1 cup pineapple chunks");    
        soupIngredients.add("1/2 cup coconut milk");    
        soupIngredients.add("1/4 cup SPAM");        
        soupIngredients.add("1/4 cup taro chips");    
    }    
}  

 

不管加工中心如何,我们应该最初定一个目标集合对象SoupBuffet,可以把它理解为是一个集装箱吧!里面盛装了各种各样的炖汤。当然你也可以在里面公布一些额外的方法,比如说对这些炖汤的筛选或者组合等。

class SoupBuffet {    
   String soupBuffetName;    
       
   ChickenSoup chickenSoup;    
   ClamChowder clamChowder;    
   FishChowder fishChowder;    
   Minnestrone minnestrone;    
   PastaFazul pastaFazul;    
   TofuSoup tofuSoup;    
   VegetableSoup vegetableSoup;    
   
   public String getSoupBuffetName() {    
       return soupBuffetName;    
   }    
   public void setSoupBuffetName(String soupBuffetNameIn) {    
      soupBuffetName = soupBuffetNameIn;    
   }    
       
   public void setChickenSoup(ChickenSoup chickenSoupIn) {    
       chickenSoup = chickenSoupIn;    
   }    
   public void setClamChowder(ClamChowder clamChowderIn) {    
       clamChowder = clamChowderIn;    
   }    
   public void setFishChowder(FishChowder fishChowderIn) {    
      fishChowder = fishChowderIn;    
   }    
   public void setMinnestrone(Minnestrone minnestroneIn) {    
      minnestrone = minnestroneIn;    
   }    
   public void setPastaFazul(PastaFazul pastaFazulIn) {    
       pastaFazul = pastaFazulIn;    
   }    
   public void setTofuSoup(TofuSoup tofuSoupIn) {    
       tofuSoup = tofuSoupIn;    
   }    
   public void setVegetableSoup(VegetableSoup vegetableSoupIn) {    
       vegetableSoup = vegetableSoupIn;    
   }    
       
   public String getTodaysSoups() {    
        StringBuffer stringOfSoups = new StringBuffer();    
        stringOfSoups.append(" Today's Soups!  ");    
        stringOfSoups.append(" Chicken Soup: ");            
        stringOfSoups.append(this.chickenSoup.getSoupName());     
        stringOfSoups.append(" Clam Chowder: ");            
        stringOfSoups.append(this.clamChowder.getSoupName());     
        stringOfSoups.append(" Fish Chowder: ");            
        stringOfSoups.append(this.fishChowder.getSoupName());     
        stringOfSoups.append(" Minnestrone: ");            
        stringOfSoups.append(this.minnestrone.getSoupName());    
        stringOfSoups.append(" Pasta Fazul: ");            
        stringOfSoups.append(this.pastaFazul.getSoupName());    
        stringOfSoups.append(" Tofu Soup: ");            
        stringOfSoups.append(this.tofuSoup.getSoupName());    
        stringOfSoups.append(" Vegetable Soup: ");            
        stringOfSoups.append(this.vegetableSoup.getSoupName());    
        return stringOfSoups.toString();              
   }    
} 

 

在建造模式里面,还应该有一个指导者(Director)类,它可以接受一个抽象建造类参数,并进一步包装、生产相应的集成产品。

class soupBuffetDirector {    
   private SoupBuffetBuilder soupBuffetBuilder;    
   
   public soupBuffetDirector(SoupBuffetBuilder soupBuffetBuilder) {    
      this.soupBuffetBuilder = soupBuffetBuilder;    
   }    
   
   public SoupBuffet CreateSoupBuffet() {    
      soupBuffetBuilder.buildSoupBuffet();    
   
      soupBuffetBuilder.setSoupBuffetName();    
   
      soupBuffetBuilder.buildChickenSoup();    
      soupBuffetBuilder.buildClamChowder();    
      soupBuffetBuilder.buildFishChowder();    
      soupBuffetBuilder.buildMinnestrone();    
      soupBuffetBuilder.buildPastaFazul();    
      soupBuffetBuilder.buildTofuSoup();    
      soupBuffetBuilder.buildVegetableSoup();    
   
      return soupBuffetBuilder.getSoupBuffet();    
   }    
}  

 

 

三、分析

通过以上建造模式的实例,我们可以总结出以下这些参与者:

  • Builder 一个抽象类,其中包含了对各个部件建造的抽象定义。
  • ConcreteBuilder 具体建造实现类,可以有一个或多个,实现创建具体部件的过程。
  • AbstractProduct 抽象部件类,可以有一个或多个,为一类部件对象声明一个接口。
  • ConcreteProduct 具体部件类,定义一个被相应的具体Builder类创建的部件对象,它继承或实现了相应的抽象部件类。
  • Director 指导类,实际使用Builder对象的中介类,也是使用该建造模式的一般入口。
  • Client 客户端,通过Director来实现建造模式。

实现一个建造模式,需要以下几个关键步骤:
1、定义一个抽象建造类,其中定义获取目标产品的建造以及出口,如buildObject和getObject。
2、定义一个或多个抽象建造类的实现类,顺带的定义了该实现类对应的实际产品种类等。
3、定义一个指导类,用抽象建造类作为参数,来实际使用已有的实际建造类。

 

建造模式(Builder)有着与抽象工厂模式(Abstract Factory) 一样的优缺点,它一般是用来创建一个比较复杂的大对象,里面包含了多步部件拼装的过程,而最终输出的是一个完整的大对象。

 

如果说和抽象工厂(Abstract Factory) 的目标是输出许多同等的产品的话,那么建造模式(Builder)应该就是输出一个完整的大对象,里面涵盖了许多个同等的子部件。

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics