概念
抽象工厂模式
提供一个“超级工厂”的接口,专门用来创建一整组互相关联的产品对象,而且不用我们关心这些产品具体是怎么实现的
简单工厂、工厂方法、抽象工厂的区别
1)简单工厂
一个工厂类负责创建所有产品的实例
2)工厂方法
每个具体工厂类负责创建某一类产品
3)抽象工厂
不仅提供了创建某一类产品的工厂方法,还提供了创建一系列相关产品的工厂方法,确保了不同产品之间的协调性
应用场景
需要创建多个相互关联的产品家族,且系统必须支持不同变体的场景,通过统一的工厂接口解耦客户端代码与具体产品实现,实现产品系列的灵活切换和扩展
使用原因:当我们有多个系列的产品,每个系列包含多个相互关联的对象时,如果直接在客户端代码中创建这些对象,会导致代码变得难以维护和扩展。抽象工厂模式通过将对象的创建过程抽象化,让客户端无需关心具体的产品实现,只需要通过工厂接口来获取相应的产品对象

基本结构

1)抽象工厂(AbstractFactory):声明一系列创建抽象产品的方法。
2)具体工厂(ConcreteFactory):实现创建具体产品对象的方法。
3)抽象产品(AbstractProduct):定义每个产品的公共接口。
4)具体产品(ConcreteProduct):实现具体的产品对象。
5)客户端(Client):只依赖抽象工厂和抽象产品,负责调用工厂去生产对象。
代码实现
以 “多平台 UI 渲染” 为例
定义抽象产品接口
统一各个产品的对外接口,比如所有平台的按钮都有 render() 方法,这样我们就能做到“面向接口编程”,平台实现细节被隐藏起来
public interface Button {
void render();
}
public interface TextBox {
void render();
}
public interface Image {
void render();
}
定义抽象工厂接口
定义了一整套产品的创建方式,比如一个平台的 UI 应该同时有按钮、文本框、图片,全部由一个工厂统一生产,保证风格一致
public interface UIFactory {
Button createButton();
TextBox createTextBox();
Image createImage();
}
定义具体产品
每种产品需要实现对应抽象产品的接口
public class WebButton implements Button {
@Override
public void render() {
System.out.println("渲染 Web 风格按钮");
}
}
public class WebTextBox implements TextBox {
@Override
public void render() {
System.out.println("渲染 Web 风格文本框");
}
}
public class WebImage implements Image {
@Override
public void render() {
System.out.println("渲染 Web 风格图片组件");
}
}
public class AndroidButton implements Button {
@Override
public void render() {
System.out.println("渲染 Android 原生按钮");
}
}
public class AndroidTextBox implements TextBox {
@Override
public void render() {
System.out.println("渲染 Android 原生文本框");
}
}
public class AndroidImage implements Image {
@Override
public void render() {
System.out.println("渲染 Android 原生图片组件");
}
}
定义具体工厂
每种工厂都要实现抽象工厂接口
public class WebUIFactory implements UIFactory {
@Override
public Button createButton() {
return new WebButton();
}
@Override
public TextBox createTextBox() {
return new WebTextBox();
}
@Override
public Image createImage() {
return new WebImage();
}
}
public class AndroidUIFactory implements UIFactory {
@Override
public Button createButton() {
return new AndroidButton();
}
@Override
public TextBox createTextBox() {
return new AndroidTextBox();
}
@Override
public Image createImage() {
return new AndroidImage();
}
}
使用
客户端只需要为抽象工厂UIFactory指定对应的具体工厂,就可以创建出同一系列下的各类产品。
public class Client {
public static void main(String[] args) {
// 假设当前运行环境为 Web
UIFactory factory = new WebUIFactory();
Button button = factory.createButton();
TextBox textBox = factory.createTextBox();
Image image = factory.createImage();
button.render();
textBox.render();
image.render();
}
}
优缺点
优点
1)产品族一致:保证同一个产品族中的组件搭配使用时不会出错
2)便于切换产品系列:只需要替换一个工厂类,就能完成整套产品的切换
3)封装对象创建逻辑:客户端不用关心具体怎么创建,只要调用对应的工厂方法就行,降低了使用门槛
缺点
1)扩展产品族比较困难:后期要再加一个新产品,需要更改所有的工厂实现类,违反了开闭原则
