在前面已经讲解过工厂方法模式,这俩者有什么区别呢?前面所说的工厂方法模式只会生产一种具体的产品,而抽象工厂模式生产出来的产品是不确定的。例如不同操作系统中控件的实现不一样,展示效果也不一样,对于操作系统如Android,iOS,WindowPhone本身构成一个产品类,而其控件如Button,TextView也构成产品类,两种产品类两种变化,各有各的特性。
为创建一组相关或者相互依赖的对象提供一个接口,而不需要指定它们的具体类。
一个对象族有相同约束时可以使用抽象工厂方法。举个例子:Android,iOS,Phone下都有Button,TextView,两者属于控件的范围,但是它们所在操作系统不一样,所以代码逻辑实现也是不一样的,这时就可以考虑使用抽象工厂方法模式来生产Android,iOS,phone下控件。
角色介绍:
虽然抽象工厂方法种类繁多,但是主要分成四类:
在工厂方法模式中,我们生产了三种车型,虽然整体流程一样,但是各个车型的零件差别很大,而且厂家也不一样,三种车型对应是一系列车,而零件比如轮胎、发动机、制动系统等对应的是一系列零件部件,两者是俩种不同的产品类型,这时候就可以将抽象工厂模式运用到其中。
首先汽车需要生产轮胎,发动机,制动系统这三种部件
轮胎相关类
抽象产品角色
public abstract class Tire {
public abstract void tire();
}
具体产品角色
public class NormalTire extends Tire {
@Override
public void tire() {
System.out.println("普通轮胎");
}
}
public class SUVTire extends Tire {
@Override
public void tire() {
System.out.println("越野轮胎");
}
}
发动机相关类
抽象产品角色
public abstract class Engine {
public abstract void engine();
}
具体产品角色
public class DomesticEngine extends Engine {
@Override
public void engine() {
System.out.println("国产发动机");
}
}
public class ImportEngine extends Engine {
@Override
public void engine() {
System.out.println("进口发动机");
}
}
制动系统相关类
抽象产品角色
public abstract class Brake {
public abstract void brake();
}
具体产品角色
public class NormalBrake extends Brake {
@Override
public void brake() {
System.out.println("普通制动");
}
}
public class SeniorBrake extends Brake {
@Override
public void brake() {
System.out.println("高级制动");
}
}
有了零件就要有工厂生产
抽象汽车工厂,即抽象工厂角色
public abstract class CarFactory {
public abstract Tire createTire();//生产轮胎
public abstract Engine createEngine();//生产发动机
public abstract Brake createBrake();//生产制动
}
每种车型的零件部件不同
奥迪工厂, 具体工厂角色
public class AudiCarFactory extends CarFactory {
@Override
public Tire createTire() {
return new NormalTire();
}
@Override
public Engine createEngine() {
return new DomesticEngine();
}
@Override
public Brake createBrake() {
return new NormalBrake();
}
}
奔驰工厂, 具体工厂角色
public class BenzCarFactory extends CarFactory {
@Override
public Tire createTire() {
return new SUVTire();
}
@Override
public Engine createEngine() {
return new ImportEngine();
}
@Override
public Brake createBrake() {
return new SeniorBrake();
}
}
宝马工厂, 具体工厂角色
public class BWMCarFactory extends CarFactory {
@Override
public Tire createTire() {
return new NormalTire();
}
@Override
public Engine createEngine() {
return new ImportEngine();
}
@Override
public Brake createBrake() {
return new SeniorBrake();
}
}
最后在一个Client中模拟
public class Client {
public static void main(String[] args){
//创建一个生产奥迪的工厂
CarFactory carFactoryAudi = new AudiCarFactory();
carFactoryAudi.createTire().tire();
carFactoryAudi.createEngine().engine();
carFactoryAudi.createBrake().brake();
System.out.println();
//创建一个生产奔驰的工厂
CarFactory carFactoryBenz = new BenzCarFactory();
carFactoryBenz.createTire().tire();
carFactoryBenz.createEngine().engine();
carFactoryBenz.createBrake().brake();
System.out.println();
//创建一个生产宝马的工厂
CarFactory carFactoryBWM = new BWMCarFactory();
carFactoryBWM.createTire().tire();
carFactoryBWM.createEngine().engine();
carFactoryBWM.createBrake().brake();
}
}
输出结果
普通轮胎
国产发动机
普通制动
越野轮胎
进口发动机
高级制动
普通轮胎
进口发动机
高级制动
上面只是模拟生产三种车系的情况,如果要生产其他车系,就要增加其他车系的工厂,不同车系构成一个产品类。如果对于奥迪工厂,我们把普通轮胎换成越野轮胎,虽然生产出来的车还是奥迪车型,但零件又和原本第一次生产出来的不一样,不同零件又构成一个产品类。两种产品类两种变化。
我们在开发中很少会出现多个产品种类的情况,大部分情况我们使用工厂方式模式就可以解决。
优点:
分离接口与实现,客户端使用抽象工厂来创建需要的对象,而客户端根本不知道具体的实现类是谁,使其从具体的产品实现中解耦。
缺点:
(1)类文件变多
(2)每当增加一个产品类就要修改抽象工厂,那么所有具体的工厂类均会被修改,不容易扩展新的产品类
本文源码位置