工厂方法模式有一个缺点,他的一个工厂只能生产一种产品,那么要解决工厂类爆炸,我们就引入的产品族的概念,产品族就是把产品分类,
比如:
大众的汽车厂只能生产大众的轮子、底盘、引擎
奔驰的汽车厂只能生产奔驰的轮子、底盘、引擎
轮子、底盘、引擎分别就属于不同的产品族(轮子族、底盘族、引擎族)
抽象工厂的模式角色分析:
1. 抽象的各种产品族(产品接口)
2. 集成各种产品族的具体实现类(具体产品)
3. 能生产各种产品族的抽象工厂(工厂接口)
4. 能生产不同品牌产品族的具体工厂(工厂接口的实现类)
上代码:
首先是属于各产品族的接口
轮子接口:
/**
* 汽车的轮子
*/
public interface Wheel {
void run();
}
引擎接口:
/**
* 汽车引擎
*/
public interface Engine {
void work();
}
底盘接口:
/**
* 汽车底盘
*/
public interface Chassis {
void canBuild();
}
接下来是实现产品族各种具体的产品:
奔驰的各种产品:
/**
* 奔驰的轮子
*/
public class BenzWheel implements Wheel{
public void run() {
System.out.println("我是奔驰的轮子,我转起来超稳");
}
}
/**
* 奔驰引擎
*/
public class BenzEngine implements Engine{
public void work() {
System.out.println("我是奔驰的引擎,我的工作转速超高");
}
}
/**
* 奔驰底盘
*/
public class BenzChassis implements Chassis{
public void canBuild() {
System.out.println("我是奔驰的底盘,我能完美组装其他部分");
}
}
大众的各种产品:
/**
* 大众的轮子
*/
public class VWWheel implements Wheel{
public void run() {
System.out.println("我是大众的轮子,我运行起来比较稳");
}
}
/**
* 大众引擎
*/
public class VWEngine implements Engine{
public void work() {
System.out.println("我是大众的引擎,我运行的转速比较高");
}
}
/**
* 大众的底盘
*/
public class VWChassis implements Chassis{
public void canBuild() {
System.out.println("我是大众的地盘,我能比较好的组装其他零件");
}
}
接下来是抽象的工厂接口:
public interface CarFactory {
Engine createEngine();
Wheel createWheel();
Chassis createChassis();
}
有了抽象的工厂就要有具体的工厂实现:
奔驰的工厂:
public class BenzFactory implements CarFactory{
public Engine createEngine() {
return new BenzEngine();
}
public Wheel createWheel() {
return new BenzWheel();
}
public Chassis createChassis() {
return new BenzChassis();
}
}
大众的工厂:
public class VWFactory implements CarFactory {
public Engine createEngine() {
return new VWEngine();
}
public Wheel createWheel() {
return new VWWheel();
}
public Chassis createChassis() {
return new VWChassis();
}
}
测试一下:
public class AbstractFactoryTest {
public static void main(String[] args) {
CarFactory carFactory;
//首先使用奔驰的工厂创建奔驰的汽车零件
carFactory = new BenzFactory();
Engine benzEngine = carFactory.createEngine();
benzEngine.work();
Chassis benzChassis = carFactory.createChassis();
benzChassis.canBuild();
Wheel benzWheel = carFactory.createWheel();
benzWheel.run();
//然后使用大众的工厂创建大众的汽车零件
carFactory = new VWFactory();
Engine vwEngine = carFactory.createEngine();
vwEngine.work();
Chassis vwChassis = carFactory.createChassis();
vwChassis.canBuild();
Wheel vwWheel = carFactory.createWheel();
vwWheel.run();
}
}
运行结果:
我是奔驰的引擎,我的工作转速超高
我是奔驰的底盘,我能完美组装其他部分
我是奔驰的轮子,我转起来超稳
我是大众的引擎,我运行的转速比较高
我是大众的地盘,我能比较好的组装其他零件
我是大众的轮子,我运行起来比较稳
从上面的代码看:
抽象工厂节约了资源的浪费,结合现实的想一想,如果使用工厂方法模式去生产零件,那一百个零件就需要一百个工厂类,加入了产品族的概念,我们就会有以下的优势:
1. 定义了某一族产品的规范后,具体产品只要按照规范来生产就好
2. 工厂能生产多种产品,这节约了资源。(这样不会工厂类爆炸),虽然这有点不符合开闭和单一职责,但是防止了类的爆炸
但是会有以下的劣势:
1. 增加一个产品族,抽象工厂就要加一个抽象方法,具体工厂就要实现。违背了开闭原则。
2. 在具体工厂类的方法中,对于产品族里的产品,只能使用其中一个。这也比较容易理解,比如,一款车子不可以搭载两种空调。