23种设计模式-抽象工厂模式(Android应用场景介绍)
抽象工厂模式是一种创建型设计模式,它提供了一个接口,用于创建相关或依赖对象的家族,而无需指定具体类。
在这种模式中,客户端不关心对象是如何创建的,只需要知道每个工厂能够生产什么类型的对象即可。这种模式使得系统更加灵活,因为可以在运行时切换工厂以获得不同的对象组合。
下面我们通过一个简单的示例来了解抽象工厂模式的具体实现方式。假设我们要开发一款模拟游戏,该游戏支持多种操作系统,包括Windows、macOS和Linux。为了在不同的操作系统上实现相同的功能,我们需要使用不同的UI控件,例如按钮、文本框和标签等。因此,我们可以通过抽象工厂模式来创建UI组件的不同家族,如Windows UI家族、macOS UI家族和Linux UI家族。
首先,我们需要定义UI控件的基本接口,例如Button、TextBox和Label:
interface Button {void paint();
}interface TextBox {void paint();
}interface Label {void paint();
}
然后,我们定义不同操作系统的UI组件家族:
interface GUIFactory {Button createButton();TextBox createTextBox();Label createLabel();
}class WindowsFactory implements GUIFactory {public Button createButton() {return new WindowsButton();}public TextBox createTextBox() {return new WindowsTextBox();}public Label createLabel() {return new WindowsLabel();}
}class macOSFactory implements GUIFactory {public Button createButton() {return new macOSButton();}public TextBox createTextBox() {return new macOSTextBox();}public Label createLabel() {return new macOSLabel();}
}class LinuxFactory implements GUIFactory {public Button createButton() {return new LinuxButton();}public TextBox createTextBox() {return new LinuxTextBox();}public Label createLabel() {return new LinuxLabel();}
}
接下来,我们定义具体的UI控件类:
class WindowsButton implements Button {public void paint() {System.out.println("WindowsButton");}
}class WindowsTextBox implements TextBox {public void paint() {System.out.println("WindowsTextBox");}
}class WindowsLabel implements Label {public void paint() {System.out.println("WindowsLabel");}
}class macOSButton implements Button {public void paint() {System.out.println("macOSButton");}
}class macOSTextBox implements TextBox {public void paint() {System.out.println("macOSTextBox");}
}class macOSLabel implements Label {public void paint() {System.out.println("macOSLabel");}
}class LinuxButton implements Button {public void paint() {System.out.println("LinuxButton");}
}class LinuxTextBox implements TextBox {public void paint() {System.out.println("LinuxTextBox");}
}class LinuxLabel implements Label {public void paint() {System.out.println("LinuxLabel");}
}
最后,我们在客户端代码中,我们可以使用不同的工厂对象来创建不同操作系统下的UI组件家族:
public class Client {public static void main(String[] args) {GUIFactory factory = new WindowsFactory();Button button = factory.createButton();TextBox textBox = factory.createTextBox();Label label = factory.createLabel();button.paint();textBox.paint();label.paint();factory = new macOSFactory();button = factory.createButton();textBox = factory.createTextBox();label = factory.createLabel();button.paint();textBox.paint();label.paint();factory = new LinuxFactory();button = factory.createButton();textBox = factory.createTextBox();label = factory.createLabel();button.paint();textBox.paint();label.paint();}
}
运行客户端代码,将会得到不同操作系统下的UI组件输出结果。
在Android开发中,抽象工厂模式可以用于创建不同风格或主题的UI控件。例如,在实现日间模式和夜间模式时,我们可以定义两个UI组件家族,分别对应不同的主题样式。然后,我们可以根据当前的主题样式来使用不同的工厂对象来创建相应的UI组件。
在第三方开源代码中,抽象工厂模式也经常被使用。例如,Retrofit是一个非常流行的网络库,它允许开发者使用不同的转换器工厂来创建网络请求响应的转换器。转换器工厂可以根据不同的数据类型来创建相应的转换器。这样,开发者可以根据自己的需求来选择不同的转换器工厂,以便在不同的网络请求场景下使用不同的转换器。
在Retrofit中,抽象工厂模式被应用于网络请求响应的转换器。Retrofit允许开发者通过设置不同的转换器工厂来支持不同的数据格式,例如JSON、XML等等。转换器工厂是一个抽象工厂,它定义了一个创建转换器的工厂方法。
以下是Retrofit中的转换器工厂抽象类:
public interface Converter.Factory {Converter<?, RequestBody> requestBodyConverter(Type type,Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit);Converter<ResponseBody, ?> responseBodyConverter(Type type,Annotation[] annotations, Retrofit retrofit);
}
在这个抽象类中,我们定义了两个工厂方法,分别用于创建请求体的转换器和响应体的转换器。具体的转换器工厂需要实现这两个工厂方法,以便创建相应的转换器对象。
以下是一个示例的JSON转换器工厂:
public final class GsonConverterFactory extends Converter.Factory {private final Gson gson;private GsonConverterFactory(Gson gson) {if (gson == null) throw new NullPointerException("gson == null");this.gson = gson;}public static GsonConverterFactory create() {return create(new Gson());}public static GsonConverterFactory create(Gson gson) {return new GsonConverterFactory(gson);}@Overridepublic Converter<?, RequestBody> requestBodyConverter(Type type,Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));return new GsonRequestBodyConverter<>(gson, adapter);}@Override public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,Retrofit retrofit) {TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));return new GsonResponseBodyConverter<>(gson, adapter);}
}
在这个转换器工厂中,我们使用Gson库来创建JSON格式的转换器。该转换器工厂实现了Converter.Factory抽象类中的两个工厂方法,并返回了相应的JSON请求体和响应体转换器对象。
在使用Retrofit时,我们可以通过以下方式来使用这个JSON转换器工厂:
Retrofit retrofit = new Retrofit.Builder().baseUrl("https://api.example.com/").addConverterFactory(GsonConverterFactory.create()).build();
在这个示例中,我们通过addConverterFactory()方法向Retrofit实例中添加了一个JSON转换器工厂。这样,Retrofit将会使用该工厂来创建JSON格式的请求体和响应体转换器对象,以便在网络请求中进行数据的转换。