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

工厂方法模式(Factory Method)

阅读更多

一、介绍

工厂方法模式是通过工厂方法,用不同方式来创建并返回一个对象。

 

 

二、实例

实例的UML图如下:

Factory Method

 

在本模式的例子中,SoupFactoryMethod定义了一个makeSoupBuffet方法,用来返回一个SoupBuffet对象。在SoupFactoryMethod中同样也定义了用来创建SoupBuffet的其它子方法。

class SoupFactoryMethod {        
    public SoupFactoryMethod() {}        
                
    public SoupBuffet makeSoupBuffet() {        
        return new SoupBuffet();        
    }        
       
    public ChickenSoup makeChickenSoup() {        
        return new ChickenSoup();        
    }        
    public ClamChowder makeClamChowder() {        
        return new ClamChowder();        
    }        
    public FishChowder makeFishChowder() {        
        return new FishChowder();        
    }        
    public Minnestrone makeMinnestrone() {        
        return new Minnestrone();        
    }        
    public PastaFazul makePastaFazul() {        
        return new PastaFazul();        
    }        
    public TofuSoup makeTofuSoup() {        
        return new TofuSoup();        
    }        
    public VegetableSoup makeVegetableSoup() {        
        return new VegetableSoup();        
    }        
       
    public String makeBuffetName() {        
        return "Soup Buffet";        
    }        
}    

 

BostonSoupFactoryMethodSubclass继承了SoupFactoryMethod,子类覆写了父类中的makeFishChowder方法,返回一个拥有FishChowder子类BostonFishChowder实例的SoupBffet对象。

class BostonSoupFactoryMethodSubclass extends SoupFactoryMethod {        
    public String makeBuffetName() {        
        return "Boston Soup Buffet";        
    }        
    public ClamChowder makeClamChowder() {        
        return new BostonClamChowder();        
    }        
    public FishChowder makeFishChowder() {        
        return new BostonFishChowder();        
    }        
}        
       
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");        
    }        
}     

 

同样,我们也定义了HonoluluSoupFactoryMethodSubclass:

class HonoluluSoupFactoryMethodSubclass extends SoupFactoryMethod {        
    public String makeBuffetName() {        
        return "Honolulu Soup Buffet";        
    }        
    public ClamChowder makeClamChowder() {        
        return new HonoluluClamChowder();        
    }        
    public FishChowder makeFishChowder() {        
        return new HonoluluFishChowder();        
    }        
}        
       
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");                  
    }        
}   

 

前面两个模式中,我们都没有写下定义Soup父子类的创建代码,这里顺便提及以下:

import java.util.ArrayList;        
import java.util.ListIterator;        
       
abstract class Soup         
{        
   ArrayList soupIngredients = new ArrayList();            
   String soupName;        
           
   public String getSoupName()        
   {        
       return soupName;        
   }        
           
   public String toString()        
   {        
        StringBuffer stringOfIngredients = new StringBuffer(soupName);        
        stringOfIngredients.append(" Ingredients: ");        
        ListIterator soupIterator = soupIngredients.listIterator();        
        while (soupIterator.hasNext())        
        {        
            stringOfIngredients.append((String)soupIterator.next());        
        }        
        return stringOfIngredients.toString();        
   }        
}                
       
class ChickenSoup extends Soup        
{        
    public ChickenSoup()         
    {        
        soupName = "ChickenSoup";        
        soupIngredients.add("1 Pound diced chicken");        
        soupIngredients.add("1/2 cup rice");            
        soupIngredients.add("1 cup bullion");              
        soupIngredients.add("1/16 cup butter");            
        soupIngredients.add("1/4 cup diced carrots");                  
    }        
}           
       
class ClamChowder extends Soup        
{        
    public ClamChowder()         
    {        
        soupName = "ClamChowder";        
        soupIngredients.add("1 Pound Fresh Clams");        
        soupIngredients.add("1 cup fruit or vegetables");            
        soupIngredients.add("1/2 cup milk");              
        soupIngredients.add("1/4 cup butter");            
        soupIngredients.add("1/4 cup chips");                  
    }        
}        
       
class FishChowder extends Soup        
{        
    public FishChowder()         
    {        
        soupName = "FishChowder";        
        soupIngredients.add("1 Pound Fresh fish");        
        soupIngredients.add("1 cup fruit or vegetables");            
        soupIngredients.add("1/2 cup milk");              
        soupIngredients.add("1/4 cup butter");            
        soupIngredients.add("1/4 cup chips");                  
    }        
}        
       
class Minnestrone extends Soup        
{        
    public Minnestrone()         
    {        
        soupName = "Minestrone";        
        soupIngredients.add("1 Pound tomatos");        
        soupIngredients.add("1/2 cup pasta");            
        soupIngredients.add("1 cup tomato juice");                     
    }        
}        
       
class PastaFazul extends Soup        
{        
    public PastaFazul()         
    {        
        soupName = "Pasta Fazul";        
        soupIngredients.add("1 Pound tomatos");        
        soupIngredients.add("1/2 cup pasta");            
        soupIngredients.add("1/2 cup diced carrots");                  
        soupIngredients.add("1 cup tomato juice");                     
    }        
}        
       
class TofuSoup extends Soup        
{        
    public TofuSoup()         
    {        
        soupName = "Tofu Soup";        
        soupIngredients.add("1 Pound tofu");        
        soupIngredients.add("1 cup carrot juice");            
        soupIngredients.add("1/4 cup spirolena");                 
    }        
}        
       
class VegetableSoup extends Soup        
{        
    public VegetableSoup()         
    {        
        soupName = "Vegetable Soup";        
        soupIngredients.add("1 cup bullion");            
        soupIngredients.add("1/4 cup carrots");                 
        soupIngredients.add("1/4 cup potatoes");                 
    }        
}   
   

当然,这里也定义了集合对象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();                  
   }        
} 

 

实际过程中,我们实践工厂方法模式代码如下:

class TestSoupFactoryMethod {                 
       
   public static void main(String[] args) {        
               
       SoupFactoryMethod soupFactoryMethod =         
         new SoupFactoryMethod();        
       SoupBuffet soupBuffet =         
         soupFactoryMethod.makeSoupBuffet();        
       soupBuffet.setSoupBuffetName(        
         soupFactoryMethod.makeBuffetName());        
       soupBuffet.setChickenSoup(        
         soupFactoryMethod.makeChickenSoup());        
       soupBuffet.setClamChowder(        
         soupFactoryMethod.makeClamChowder());         
       soupBuffet.setFishChowder(        
         soupFactoryMethod.makeFishChowder());        
       soupBuffet.setMinnestrone(        
         soupFactoryMethod.makeMinnestrone());        
       soupBuffet.setPastaFazul(        
         soupFactoryMethod.makePastaFazul());         
       soupBuffet.setTofuSoup(        
         soupFactoryMethod.makeTofuSoup());        
       soupBuffet.setVegetableSoup(        
          soupFactoryMethod.makeVegetableSoup());         
       System.out.println("At the  " +         
                           soupBuffet.getSoupBuffetName() +         
                           soupBuffet.getTodaysSoups());        
               
               
       SoupFactoryMethod bostonSoupFactoryMethod =         
         new BostonSoupFactoryMethodSubclass();        
       SoupBuffet bostonSoupBuffet =         
         bostonSoupFactoryMethod.makeSoupBuffet();        
       bostonSoupBuffet.setSoupBuffetName(        
         bostonSoupFactoryMethod.makeBuffetName());        
       bostonSoupBuffet.setChickenSoup(        
         bostonSoupFactoryMethod.makeChickenSoup());        
       bostonSoupBuffet.setClamChowder(        
         bostonSoupFactoryMethod.makeClamChowder());        
       bostonSoupBuffet.setFishChowder(        
         bostonSoupFactoryMethod.makeFishChowder());        
       bostonSoupBuffet.setMinnestrone(        
         bostonSoupFactoryMethod.makeMinnestrone());        
       bostonSoupBuffet.setPastaFazul(        
         bostonSoupFactoryMethod.makePastaFazul());        
       bostonSoupBuffet.setTofuSoup(        
         bostonSoupFactoryMethod.makeTofuSoup());        
       bostonSoupBuffet.setVegetableSoup(        
         bostonSoupFactoryMethod.makeVegetableSoup());         
       System.out.println("At the  " +         
                           bostonSoupBuffet.getSoupBuffetName() +         
                           bostonSoupBuffet.getTodaysSoups());        
               
       SoupFactoryMethod honoluluSoupFactoryMethod =         
         new HonoluluSoupFactoryMethodSubclass();        
       SoupBuffet honoluluSoupBuffet =         
         honoluluSoupFactoryMethod.makeSoupBuffet();        
       honoluluSoupBuffet.setSoupBuffetName(        
         honoluluSoupFactoryMethod.makeBuffetName());        
       honoluluSoupBuffet.setChickenSoup(        
         honoluluSoupFactoryMethod.makeChickenSoup());        
       honoluluSoupBuffet.setClamChowder(        
         honoluluSoupFactoryMethod.makeClamChowder());         
       honoluluSoupBuffet.setFishChowder(        
         honoluluSoupFactoryMethod.makeFishChowder());        
       honoluluSoupBuffet.setMinnestrone(        
         honoluluSoupFactoryMethod.makeMinnestrone());        
       honoluluSoupBuffet.setPastaFazul(        
         honoluluSoupFactoryMethod.makePastaFazul());         
       honoluluSoupBuffet.setTofuSoup(        
         honoluluSoupFactoryMethod.makeTofuSoup());        
       honoluluSoupBuffet.setVegetableSoup(        
         honoluluSoupFactoryMethod.makeVegetableSoup());         
       System.out.println("At the  " +         
                           honoluluSoupBuffet.getSoupBuffetName() +         
                           honoluluSoupBuffet.getTodaysSoups());        
     }        
} 

 

 

 

三、分析

从例子中,我们可以针对工厂方法模式,统计出的以下这些角色:

  • Prodcut 定义工厂方法所创建的对象的接口,如我们例子中Soup类。 ConcreteProduct 实际产品,扩展了Soup接口类。如这里的FishChowder,BostonFishChowder等等。
  • Creator 工厂方法,该方法返回一个Product对象。如这SoupFactoryMethod里的makeFishChowder方法。
  • ConcreteCreator 重定义一个方法,并返回一个ConcreteProduct对象。如BostonSoupFactoryMethodSubclass中的makeFishChowder方法。

实现一个工厂方法模式,需要以下几个关键步骤:
1、定义基础产品类和相关的扩展产品类。
2、定义一个基础的工厂方法类,其中定义make产品的方法。
3、扩展基础工厂方法类,覆写已有的make方法,输出的产品含有扩展产品的信息。

 

以上的例子,我自己理解的时候,也感觉有点含糊。到底抽象工厂模式和工厂方法模式有什么差别?这里我自己总结了一下,欢迎指正。

 

区别于抽象工厂模式(Abstract Factory),工厂方法模式只用来make一种产品SoupBuffet,工厂接口本身不关心其子类Soup如何定义产生。确切的说,工厂方法模式的最终目的就是制造某种具体的产品,但返回的结果根据实际加工工艺的不同,会生成不同风格的成品。

 

换一种说法,抽象工厂模式可以生成多种产品,而工厂方法模式却只用来生成一种产品。如果把抽象工厂模式中的多种产品削减到一个品种,那么也就成了我们这里的工厂方法模式的一个简单模型。

 

可能在其它的设计模式的书本中,会接触到“简单工厂模式”,这种模式就更简单了。直接一个ConcreteCreator类就可以了,根据传入的参数不同,直接make返回该品种的实际产品。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics