AbstractFactory抽象工厂模式

1.概念  

  抽象工厂模式,顾名思义,所谓工厂即是批量制造产品的地方。在Java中,抽象工厂模式用来创建对象。根据GOF对模式的分类,抽象工厂模式属于创建型对象模式。

  先来说一些概念,《设计模式》中对抽象工厂模式的定义如下:

提供一个创建一系列相关或相互依赖对象的接口,而无需制定它们具体的类。

  为了更好的描述抽象工厂,吸取前人对抽象工厂的理解,这里引入一个新的概念帮助理解抽象工厂:产品族。所谓产品族,是指位于不同产品等级结构,功能相关联的产品组成的家族。

  举个例子来帮助理解,汽车按类型可分为:轿车、客车、货车。汽车按品牌可分为:奔驰、宝马、大众。(先不管奔驰宝马有没有货车,just an example!),那么奔驰轿车、宝马轿车、大众轿车就是一个产品等级结构;奔驰轿车、奔驰客车、奔驰货车属于一个产品家族。见下图:  

          

  图中一共有三个个产品族,分布于三个不同的产品等级结构中。只要指明一个产品所处的产品族以及它所属的等级结构,就可以唯一的确定这个产品。

  现在我们再通俗的定义下抽象工厂模式:所谓的抽象工厂是指一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品族中的所有对象。

  有的人也许会问了:那就叫工厂模式不就得了,干嘛叫抽象工厂?这是因为这里有个具体工厂的概念,AbstractFactory仅仅声明一个创建产品的接口,具体创建产品是由子类来实现了,子类也叫具体工厂。用图形来表示的话如下:

  

        

2.结构

  下面来看一下抽象工厂模式的结构:

          

  可以看到具体制造商品是由ConcreteFactory1和ConcreteFactory2两个具体工厂来实现的,ConcreteFactory1制造一个产品族,ConcreteFactory2也制造一个产品族。

  图中的角色如下:

  AbstractFactory声明一个创建抽象产品对象的操作接口。

  ConcreteFactory:实现创建具体产品对象的操作。

  AbstractProduct:为一类产品对象声明一个接口。

  Product:定义一个将被相应的具体工厂创建的产品对象。实现AbstractProduct接口。

  Client:使用AbstractFactory和AbstractProduct类声明的接口。

3.程序示例

  下面用前面汽车的例子来演示抽象工厂模式的结构:

  先来看一下类结构图:

          

  下面看下代码:

 

public abstract class AbstractVehicheFactory
{
/**
* 建造轿车
*/
abstract public AbstractCar createCar();

/**
* 建造客车
*/
abstract public AbstractBus createBus();

/**
* 建造货车
*/
abstract public AbstractTruck createTruck();
}

 

public class BenzFactory extends AbstractVehicheFactory
{

@Override
public AbstractBus createBus()
{
return new BenzBus();
}

@Override
public AbstractCar createCar()
{
return new BenzCar();
}

@Override
public AbstractTruck createTruck()
{
return new BenzTruck();
}

}

 

public class BMWFactory extends AbstractVehicheFactory
{

@Override
public AbstractBus createBus()
{
return new BMWBus();
}

@Override
public AbstractCar createCar()
{
return new BMWCar();
}

@Override
public AbstractTruck createTruck()
{
return new BMWTruck();
}

}

 

public abstract class AbstractCar
{
abstract public String product();
}

 

public abstract class AbstractBus
{
abstract public String product();
}

 

public abstract class AbstractTruck
{
abstract public String product();
}

 

public class BenzCar extends AbstractCar
{
public String product()
{
return "我是一辆奔驰轿车,我被制造了";
}
}

 

public class BenzBus extends AbstractBus
{
public String product()
{
return "我是一辆奔驰客车,我被制造了";
}
}

 

public class BenzTruck extends AbstractTruck
{
public String product()
{
return "我是一辆奔驰货车,我被制造了";
}
}

 

public class BMWCar extends AbstractCar
{
public String product()
{
return "我是一辆宝马轿车,我被制造了";
}
}

 

public class BMWBus extends AbstractBus
{
public String product()
{
return "我是一辆宝马客车,我被制造了";
}
}

 

public class BMWTruck extends AbstractTruck
{
public String product()
{
return "我是一辆宝马货车,我被制造了";
}
}

 

public class Client
{
private AbstractCar car;

private AbstractBus bus;

private AbstractTruck truck;

public Client(AbstractVehicheFactory factory)
{
car = factory.createCar();
bus = factory.createBus();
truck = factory.createTruck();
}

public void output()
{
System.out.println(car.product());
System.out.println(bus.product());
System.out.println(truck.product());
}
}

 

public class Test
{

public static void main(String[] args)
{
AbstractVehicheFactory benzFactory = new BenzFactory();
Client client = new Client(benzFactory);
client.output();

AbstractVehicheFactory bmwFactory = new BMWFactory();
Client client2 = new Client(bmwFactory);
client2.output();
}

}

最后的运行结果为:

我是一辆奔驰轿车,我被制造了
我是一辆奔驰客车,我被制造了
我是一辆奔驰货车,我被制造了


我是一辆宝马轿车,我被制造了
我是一辆宝马客车,我被制造了
我是一辆宝马货车,我被制造了

4.应用场景

  在以下情况下应当考虑使用抽象工厂模式:

  • 一个系统需要独立于它的产品的创建、组合和表示。
  • 这个系统有多于一个的产品族,而系统只消费其中某一产品族。
  • 同属于同一个产品族的产品是在一起使用的,这一约束必须在系统的设计中体现出来。
  • 系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于实现。

5.优缺点

  从上面的介绍来说我们总结一下抽象工厂模式的优缺点:

  1.抽象工厂提供了一个抽象的接口来控制创建一个产品族的对象,创建产品对象的过程被封装在具体工厂中,它将客户与具体实现分离。客户通过抽象的接口来操纵实例。产品也被封装在具体工厂中,从而不出现在客户代码中。

  2.抽象工厂很容易就更换产品系列,例如上面汽车的例子,从宝马系列到奔驰系列只需要切换一下具体工厂。因为一个抽象工厂创建了一个完整的产品系列。

  3.相信大家根据第2点也看出来抽象工厂的缺点,那就是难以很方便的支持新的产品系列。我们想一下,如果我们要生产大众系列的汽车,那么只要产品族(轿车、客车、货车)不变,我们只需要在具体产品的类中添加大众轿车、大众客车以及大众货车就可以了;相反,如果我们要增加一个产品族,例如增加救火车,那么我必须修改该工厂接口,包括AbstractFactory及其子类。

 

  关于创建型模式(AbstractFactory、Builder、FactoryMethod、Prototype、singleton)之间的关系,我将会在学习完它们以后再来写,基友是一辈子的,又启在朝朝暮暮。

  

  

















  

  

  

   

  

posted @ 2012-03-26 16:07  朱样年华  阅读(1617)  评论(2编辑  收藏  举报