什么是抽象工厂设计模式?
由于工厂方法模式中每个工厂只创建一类具体类的对象,这将会导致系统当中的工厂类过多,这势必会增加系统的开销。此时,我们可以考虑将一些相关的具体类组成一个“具体类族”,由同一个工厂来统一生产,这就是抽象工厂模式。
在抽象工厂模式中,每一个具体工厂都提供了多个工厂方法用于产生多种不同类型的产品。
抽象工厂模式的优点
- 允许客户使用抽象的接口创建一组相关产品,而不需要知道(或者关心)产出的具体产品是什么,这样客户就可以从具体的产品中解耦出来。
- 一个具体工厂可以创建多个产品,与工厂方法模式相比,可以少产生具体工厂的类数量。
- 易于交换产品系列,只要更换具体工厂,就可以改变这个产品系列。
使用场景
当需要创建的对象是一系列相互关联或相互依赖的产品族时,便可以使用抽象工厂模式。说的更明白一点,就是一个继承体系中,如果存在着多个等级结构(即存在着多个抽象类),并且分属各个等级结构中的实现类之间存在着一定的关联或者约束,就可以使用抽象工厂模式。假如各个等级结构中的实现类之间不存在关联或约束,则使用多个独立的工厂来对产品进行创建,则更合适一点。
UML图
抽象工厂的具体实现
角色
AbstractFactory(抽象工厂):它声明了一组用于创建一族产品的方法,每一个方法对应一种产品。
ConcreteFactory(具体工厂):它实现了在抽象工厂中声明的创建产品的方法,生成一组具体产品,这些产品构成了一个产品族,每一个产品都位于某个产品等级结构中。
AbstractProduct(抽象产品):它为每种产品声明接口,在抽象产品中声明了产品所具有的业务方法
ConcreteProduct(具体产品):它定义具体工厂生产的具体产品对象,实现抽象产品接口中声明的业务方法。
示例
抽象产品类Article和Video
abstract class Article {
public abstract void produce();
}
abstract class Video {
public abstract void produce();
}
具体产品类JavaArticle、PythonArticle、PythonVideo、JavaVideo
class JavaArticle extends Article {
@Override
public void produce() {
System.out.println("编写Java课程笔记记");
}
}
class PythonArticle extends Article {
@Override
public void produce() {
System.out.println("编写Python课程笔记");
}
}
class JavaVideo extends Video {
@Override
public void produce() {
System.out.println("录制Java课程视频");
}
}
class PythonVideo extends Video {
@Override
public void produce() {
System.out.println("录制Python课程视频");
}
}
抽象工厂类CourseFactory
interface CourseFactory {
Video getVideo();
Article getArticle();
}
具体工厂 JavaCourseFactory 和 PythonCourseFactory
class JavaFactory implements CourseFactory {
@Override
public Video getVideo() {
return new JavaVideo();
}
@Override
public Article getArticle() {
return new JavaArticle();
}
}
class PythonFactory implements CourseFactory {
@Override
public Video getVideo() {
return new PythonVideo();
}
@Override
public Article getArticle() {
return new PythonArticle();
}
}
客户端只需要指定具体工厂,就可以获取该工厂生产的一族产品
public class AbstractFactory {
public static void main(String[] args) {
CourseFactory javaFactory = new JavaFactory();
Article javaArticle = javaFactory.getArticle();
Video javaVideo = javaFactory.getVideo();
javaArticle.produce();
javaVideo.produce();
}
}
再借用一个更实际的例子
汽车的生产需要轮胎、发动机和制动系统,不同的汽车使用的轮胎、发动机和制动系统也不尽相同,所以制造的过程和车间会有区别。
制造汽车的UML图
抽象汽车工厂类:用来抽象化整个汽车
public abstract class CarFactory {
/**
* 生产轮胎
* return 生产轮胎
*/
public abstract ITire createTire();
/**
* 生产发动机
* return 发动机
*/
public abstract IEngine createEngine();
/**
* 生产制动系统
* return 制动系统
*/
public abstract IBrake createBrake();
}
每种零部件定义一个接口,分别创建两个不同的实现类表示不同的零部件。
轮胎接口-抽象:
public interface ITire {
void tire();
}
通用轮胎:
public class NormalTire implements ITire{
@Override
public void tire() {
System.out.println("normal tire");
}
}
SUV轮胎:
public class SUVTire implements ITire{
@Override
public void tire() {
System.out.println("SUV tire");
}
}
发动机接口-抽象:
public interface IEngine {
void engine();
}
国产发动机:
public class DomesticEngine implements IEngine{
@Override
public void engine() {
System.out.println("domestic engine");
}
}
进口发动机:
public class ImportEngine implements IEngine{
@Override
public void engine() {
System.out.println("Import engine");
}
}
制动系统接口-抽象
public interface IBrake {
void brake();
}
普通发动机:
public class NormalBrake implements IBrake{
@Override
public void brake() {
System.out.println("Normal Brake");
}
}
高级发动机:
public class SeniorBrake implements IBrake{
@Override
public void brake() {
System.out.println("Senior Brake");
}
}
生产这些零件需要具体的工厂,对于Q3和Q7,对应的车间不同
具体生产工厂Q3Factory:
public class Q3Factory extends CarFactory {
@Override
public ITire createTire() {
return new NormalTire();
}
@Override
public IEngine createEngine() {
return new DomesticEngine();
}
@Override
public IBrake createBrake() {
return new NormalBrake();
}
}
具体生产工厂Q7Factory:
public class Q7Factory extends CarFactory {
@Override
public ITire createTire() {
return new SUVTire();
}
@Override
public IEngine createEngine() {
return new ImportEngine();
}
@Override
public IBrake createBrake() {
return new SeniorBrake();
}
}
客户端调用:
public class Client {
public static void main(String[] args) {
//构造一个生产Q3的工厂
CarFactory Q3Factory = new Q3Factory();
Q3Factory.createTire().tire();
Q3Factory.createEngine().engine();
Q3Factory.createBrake().brake();
System.out.println("===================");
//构造一个生产Q7的工厂
CarFactory Q7Factory = new Q7Factory();
Q7Factory.createTire().tire();
Q7Factory.createEngine().engine();
Q7Factory.createBrake().brake();
}
}