23种设计模式之抽象工厂模式
参考资料
- Java设计模式:23种设计模式全面解析(超级详细)
- 韩顺平老师的Java设计模式(图解+框架源码剖析)
- 秦小波老师的《设计模式之禅》
下文如有错漏之处,敬请指正
一、简介
定义
-
用来生产固定产品线组成的不同产品族,抽象工厂规定生产的产品集合(即固定产品线),产品集合中的每个产品由抽象工厂的子类工厂(产品族工厂)负责生产。
-
固定产品线:由固定产品组成的一条生产线,如轮胎生产、轮毂生产等
-
产品族:由同一产品等级组成的产品,如奔驰由奔驰轮胎、轮毂组成,宝马由宝马轮胎、轮毂组成等
-
-
抽象工厂不仅可以生产轮胎,还可以生产轮毂、气缸,成为汽车工厂(固定产品线)。各个部件的生产可以交于其子类工厂(产品族工厂)生产。比如奔驰汽车厂继承抽象工厂,那么奔驰汽车厂就可以生产奔驰的各个部件。同理当增加特斯拉工厂时,特斯拉汽车厂就可以生产特斯拉的各个部件。
特点
- 抽象工厂模式是一种创建型设计模式
- 解决工厂模式的单一产品等级的缺陷
优点
- 良好的封装性,代码结构清晰,只要知道产品的类名(或约束字符串)就可以创建对象,不用知道创建对象的艰辛过程,降低模块间的耦合。
- 抽象工厂规定了所有可能被创建产品的集合,增加一个产品族非常简单,只需要增加一个工厂即可。
缺点
- 由于抽象工厂模式是用来生产固定产品线组成的不同产品族,因此在产品线里面扩展一个新的产品非常困难。
如果要增加一个产品,就要更改产品线,一更改产品线,那么就要更改所有产品线的子类实现工厂,不符合开闭原则。
通用类图
- Product:抽象产品类,负责定义产品的共性
- ConcreteProduct:具体产品类
- Creator:抽象工厂类,负责定义工厂的共性,
- ConcreteCreator:具体工厂类
应用场景
- 一键风格替换
二、抽象工厂模式
需求:抽象工厂定义了可以生产轮胎与轮毂,奔驰轮胎工厂生产奔驰轮胎与轮毂,宝马轮胎工厂生产宝马轮胎与轮毂。
Product:轮胎类(Tyre)、轮毂类(Wheel)
ConcreteProduct:奔驰轮胎(BenzTyre)、宝马轮胎(BmwTyre)、奔驰轮毂(BenzWheel)、宝马轮毂(BmwWheel)
Creator:汽车工厂(CarFactory)
ConcreteCreator:奔驰轮胎工厂(BenzTyreFactory)、宝马轮胎工厂(BmwTyreFactory)
Tyre:
package factory.abstractFactory;
interface Tyre {
public void createTyre();
}
Wheel:
package factory.abstractFactory;
public interface Wheel {
public void createWheel();
}
BenzTyre:
package factory.abstractFactory;
public class BenzTyre implements Tyre {
@Override
public void createTyre() {
System.out.println("生产奔驰的轮胎……");
}
}
BenzWheel:
package factory.abstractFactory;
public class BenzWheel implements Wheel {
@Override
public void createWheel() {
System.out.println("生产奔驰的轮毂……");
}
}
BmwTyre:
package factory.abstractFactory;
public class BmwTyre implements Tyre {
@Override
public void createTyre() {
System.out.println("生产宝马的轮胎");
}
}
BmwWheel:
package factory.abstractFactory;
public class BmwWheel implements Wheel {
@Override
public void createWheel() {
System.out.println("生产宝马的轮毂");
}
}
CarFactory:
package factory.abstractFactory;
interface CarFactory {
public Wheel createWheel();
public Tyre createTyre();
}
BenzTyreFactory:
package factory.abstractFactory;
public class BenzFactory implements CarFactory {
@Override
public Wheel createWheel() {
return new BenzWheel();
}
@Override
public Tyre createTyre() {
return new BenzTyre();
}
}
BmwFactory:
package factory.abstractFactory;
public class BmwFactory implements CarFactory {
@Override
public Wheel createWheel() {
return new BmwWheel();
}
@Override
public Tyre createTyre() {
return new BmwTyre();
}
}
Client:
package factory.abstractFactory;
public class Client {
public static void main(String[] args) {
CarFactory benzFactory=new BenzFactory();
Wheel benzWheel = benzFactory.createWheel();
benzWheel.createWheel();
Tyre benzTyre = benzFactory.createTyre();
benzTyre.createTyre();
CarFactory bmwFactory=new BmwFactory();
Wheel bmwWheel = bmwFactory.createWheel();
bmwWheel.createWheel();
Tyre bmwTyre = bmwFactory.createTyre();
bmwTyre.createTyre();
}
}
三、总结
-
抽象工厂模式使用的场景非常多,在软件产品开发过程中,涉及不同操作系统的时候,都可以考虑使用抽象工厂模式。
例如一个应用,需要在三个不同平台(Windows、Linux、MacOS)上运行,通过抽象工厂模式屏蔽掉操作系统对应用的影响。三个不同操作系统上的软件功能、应用逻辑、UI都应该是非常类似的,唯一不同的是调用不同的工厂方法,由不同的产品类去处理与操作系统交互的信息。