概念
前面的工厂方法模式中考虑的只是一类产品的生产,如汽车厂只生产汽车,电视机厂只生产电视机等。同种类称为同等级,也就是说:工厂方法模式只考虑生产同等级的产品,但是在现实生活中许多工厂是综合型的工厂,能生产多等级(种类)的产品,如机车厂里既生产传统汽车也生产电动汽车,电器厂既生产电视机又生产洗衣机或空调等。
为了更清晰地理解工厂方法模式,我们先理解下面两个概念:
-
产品等级结构
:产品等级结构即产品的继承结构,如一个抽象类是电视机,其子类有海尔电视机、海信电视机、TCL电视机,则抽象电视机与具体品牌的电视机之间构成了一个产品等级结构,抽象电视机是父类,而具体品牌的电视机是其子类。 -
产品族
:在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品,如海尔电器工厂生产的海尔电视机、海尔电冰箱,海尔电视机位于电视机产品等级结构中,海尔电冰箱位于电冰箱产品等级结构中。
实现方式
抽象工厂模式是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品。
抽象工厂模式同工厂方法模式一样,也是由抽象工厂、具体工厂、抽象产品和具体产品等 4 个要素构成,但抽象工厂中方法个数不同,抽象产品的个数也不同。
模式结构如下:
- 抽象工厂(abstract factory): 提供了创建产品的接口,它包含多个创建产品的方法,可以创建多个不同等级的产品。
- 具体工厂实现(real factory): 主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。
- 抽象产品(abstract product): 工厂角色生产的所有对象都需要依赖此抽象。一般通过接口或者抽象类来实现。
- 具体产品实现(real product): 实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间是多对一的关系。
下面我们就通过设计一个农场例子来熟悉一下抽象工厂吧。
抽象产品
/**
* 动物抽象
*/
public interface Animal {
/**
* 小动物出生
*/
Animal bornAnimal();
}
/**
* 植物抽象
*/
public interface Plant {
/**
* 开花结果
*/
Plant bloom();
}
产品实现
public class CatAnimal implements Animal{
@Override
public Animal bornAnimal() {
System.out.println("小猫咪出生啦");
return new CatAnimal();
}
}
public class DogAnimal implements Animal{
@Override
public Animal bornAnimal() {
System.out.println("小旺仔出生啦");
return new DogAnimal();
}
}
public class ApplePlant implements Plant{
@Override
public Plant bloom() {
System.out.println("苹果熟了");
return new ApplePlant();
}
}
public class OrangePlant implements Plant{
@Override
public Plant bloom() {
System.out.println("橘子熟了");
return new OrangePlant();
}
}
抽象工厂
/**
* 抽象农场
*/
public interface FramFactory {
/**
* 创建动物
*/
Animal newAnimal();
/**
* 创建植物
*/
Plant newPlant();
}
工厂实现
/**
* 天天农场
*/
public class DayDayFramFactory implements FramFactory{
@Override
public Animal newAnimal() {
return new CatAnimal();
}
@Override
public Plant newPlant() {
return new OrangePlant();
}
}
/**
* 开心农场
*/
public class HappyFramFactory implements FramFactory{
@Override
public Animal newAnimal() {
return new DogAnimal();
}
@Override
public Plant newPlant() {
return new ApplePlant();
}
}
至此我们就实现了一个非常简单的抽象工厂模式的样例。
抽象工厂模式的扩展有一定的“开闭原则”倾斜性:
- 当增加一个新的产品族时只需增加一个新的具体工厂,不需要修改原代码,满足开闭原则
- 当产品族中需要增加一个新种类的产品时,则所有的工厂类都需要进行修改,不满足开闭原则 。
另一方面,当系统中只存在一个等级结构的产品时,抽象工厂模式将退化到工厂方法模式。
网友评论