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

抽象工厂模式(Abstract Factory)

阅读更多

一、介绍

抽象工厂模式相对工厂方法模式(Facotry Method)要复杂的多,一个抽象的工厂可以拥有多种方法,从而来生成不同性质的对象(产品)。

 

 

二、实例
这里举一个例子,例子的UML类图如下:


创建抽象工厂,首先要定义一个抽象工厂类,用来指明有哪些个制造方法,在本例子中,我们在抽象工厂类AbstractSoupFactory中定义了制造各种炖汤的方法:

abstract class AbstractSoupFactory {    
    String factoryLocation;    
    public String getFactoryLocation() {    
        return factoryLocation;    
    }    
        
    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();    
    }    
}   
 

接下来,我们需要来一个实例化的工厂,比如说一家来自Boston的餐馆可以制作具有[波士顿]风格的炖汤,代码BostonConcreteSoupFactory内容如下:

class BostonConcreteSoupFactory extends AbstractSoupFactory {    
    public BostonConcreteSoupFactory() {    
        factoryLocation = "Boston";    
    }    
    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");    
    }    
}   
 

现在我们来写一个类,来分享这些汤料的美味吧!

import java.util.Calendar;    
   
class TestAbstractSoupFactory {     
   public static Soup MakeSoupOfTheDay(AbstractSoupFactory     
                                       concreteSoupFactory)    
   {     
       Calendar todayCalendar = Calendar.getInstance();    
       //int dayOfWeek = todayCalendar.get(Calendar.DAY_OF_WEEK);    
           
       int dayOfWeek = Calendar.TUESDAY;    
           
       if (dayOfWeek == Calendar.MONDAY) {    
           return concreteSoupFactory.makeChickenSoup();    
       } else if (dayOfWeek == Calendar.TUESDAY) {    
           return concreteSoupFactory.makeClamChowder();    
       } else if (dayOfWeek == Calendar.WEDNESDAY) {    
           return concreteSoupFactory.makeFishChowder();    
       } else if (dayOfWeek == Calendar.THURSDAY) {    
           return concreteSoupFactory.makeMinnestrone();    
       } else if (dayOfWeek == Calendar.TUESDAY) {    
           return concreteSoupFactory.makePastaFazul();    
       } else if (dayOfWeek == Calendar.WEDNESDAY) {    
           return concreteSoupFactory.makeTofuSoup();    
       } else {    
           return concreteSoupFactory.makeVegetableSoup();    
       }    
   }            
   
   public static void main(String[] args)     
   {    
       AbstractSoupFactory concreteSoupFactory =     
         new BostonConcreteSoupFactory();    
       Soup soupOfTheDay =     
         MakeSoupOfTheDay(concreteSoupFactory);    
       System.out.println("The Soup of the day " +     
                          concreteSoupFactory.getFactoryLocation() +     
                          " is " +     
                          soupOfTheDay.getSoupName());    
     
       concreteSoupFactory =     
         new HonoluluConcreteSoupFactory();    
       soupOfTheDay =     
         MakeSoupOfTheDay(concreteSoupFactory);    
       System.out.println("The Soup of the day " +     
                          concreteSoupFactory.getFactoryLocation() +     
                          " is " +     
                          soupOfTheDay.getSoupName());    
   }    
}   
 


三、分析

通过以上抽象工厂模式的实例,我们可以总结出以下这些参与者:

  • AbstractFactory 抽象工厂类,声明一个创建抽象产品(AbstractProduct)的操作接口。
  • ConcreteFactory 具体工厂类,可以有一个或多个,实现创建具体产品对象的操作。
  • AbstractProduct 抽象产品类,可以有一个或多个,为一类产品对象声明一个接口。
  • ConcreteProduct 具体产品类,定义一个被相应的具体工厂创建的产品对象,它继承或实现了相应的抽象产品类。
  • Client 客户端,仅用AbstractFactory和AbstractProduct类来声明调用接口,直到调用时才为接口传入的具体工厂或产品。

实现一个抽象工厂模式,需要以下几个关键步骤:
1、定义一个抽象的工厂类,里面定义许多同种类别但不同性质的产品的制造实现方法。简单的说,这个工厂就是一个加工中心,盛产多种不同型号的产品。值得注意的是,抽象工厂里面定义的都是抽象的产品。
2、定义相关的工厂实现类,这个类实现了第1步中的抽象工厂类,这个工厂在父抽象类的基础上,可以进一步生产出具有自己特色的产品。这些个特产是基于该父抽象类中产品扩展出来的,即继承并衍生父抽象类中定义的产品,加上了一些本地特色。
3、实际调用过程中,我们可以定义一个通用的Factory类,其类别名称即父抽象类。具体的产品取决于我们提供的实际工厂类是什么。

 

该模式的优点是可以不用知道产品具体的制造实现细节,客户只需要指定到哪个工厂就可以了,客户不会直接与产品打交道。

 

该模式的缺点是当产品修改时,工厂类也要做相应的修改,增加或修改一种产品,可能要涉及到所有相关工厂类的改动。

评论

相关推荐

Global site tag (gtag.js) - Google Analytics