定义
【创建型】为创建一组相关或者相互依赖的对象提供的一个接口,而不需要指定他们的具体类。
使用场景
一个对象族有相同的约束时可以使用抽象工厂模式。例如 Android、iOS、WindowsPhone 下面的 短信 和 拨号软件。同系列软件,但操作平台不一样,其是实现逻辑也是不同的。
角色
- AbstractFactory(抽象工厂类)
声明一组用于创建产品的方法,每一个方法对应一种产品
- ConcreteFactory(具体工厂类)
实现了在抽象工厂中定义的创建产品的方法,生成了一组具体的产品
- AbstractProduct(抽象产品类)
为每种产品声明接口
- ConcreteProduct(具体产品类)
实现抽象产品接口中声明的业务方法,定义具体的产品对象
实现方式
背景:Android 中进行主题颜色的切换
解决方案:使用抽象工厂模式
AbstractFactory
public abstract class AbstractThemeFactory {
protected Context context = null;
public AbstractThemeFactory(Context context) {
this.context = context;
}
public abstract ThemeButton createButton();
public abstract ThemeToolbar createToolbar();
}
ConcreteFactory
亮色主题
public class LightThemeFactory extends AbstractThemeFactory {
public LightThemeFactory(Context context) {
super(context);
}
@Override
public ThemeButton createButton() {
return new ButtonLight(context);
}
@Override
public ThemeToolbar createToolbar() {
return new ToolbarLight(context);
}
}
暗色主题
public class DarkThemeFactory extends ThemeFactory {
public DarkThemeFactory(Context context) {
super(context);
}
@Override
public ThemeButton createButton() {
return new ButtonDark(context);
}
@Override
public ThemeToolbar createToolbar() {
return new ToolbarDark(context);
}
}
AbstractProduct
主题按钮
public abstract class ThemeButton extends Button {
public ThemeButton(Context context) {
super(context);
initTextColor();
initBackground();
}
public abstract void initTextColor();
public abstract void initBackground();
}
主题Toolbar
public abstract class ThemeToolbar extends Toolbar {
public ThemeToolbar(Context context) {
super(context);
initTextColor();
initBackground();
initIcon();
}
public abstract void initTextColor();
public abstract void initBackground();
public abstract void initIcon();
}
ConcreteProduct
亮色按钮
public class ButtonLight extends ThemeButton {
public ButtonLight(Context context) {
super(context);
}
@Override
public void initTextColor() {
this.setTextColor(Color.White);
}
@Override
public void initBackground() {
this.setBackground(Color.parseColor("#19B5FE"));
}
}
暗色按钮
public class ButtonDark extends ThemeButton {
public ButtonDark(Context context) {
super(context);
}
@Override
public void initTextColor() {
this.setTextColor(Color.White);
}
@Override
public void initBackground() {
this.setBackground(Color.parseColor("#2C3E50"));
}
}
亮色Toolbar
public class ToolbarLight extends ThemeToolbar {
public ToolbarLight(Context context) {
super(context);
}
@Override
public void initTextColor() {
this.setTitleTextColor(Color.White);
}
@Override
public void initBackground() {
this.setBackground(Color.parseColor("#19B5FE"));
}
@Override
public void initIcon() {
this.setLogo(R.drawable.icon);
}
}
暗色Toolbar
public class ToolbarDark extends ThemeToolbar {
public ToolbarDark(Context context) {
super(context);
}
@Override
public void initTextColor() {
this.setTitleTextColor(Color.White);
}
@Override
public void initBackground() {
this.setBackground(Color.parseColor("#2C3E50"));
}
@Override
public void initIcon() {
this.setLogo(R.drawable.icon);
}
}
具体调用代码略。
优缺点
优点
- 接口与实现分离。客户端无需知道具体实现,只需面向接口
缺点
- 类文件爆炸性增加
- 不易扩展新的产品类,违反 OCP(开闭原则)
注意
抽象工厂模式在 Android 实际开发中应用的不多,一个典型应用场景就是上文提到的主题换肤的场景。
在 Android 源码中,MediaPlayerFactory 使用了该模式,用来管理 Android 内置 4 种不同的 MediaPlayer,分别是 StagefrightPlayerFactory、NuPlayerFactory、SonivoxPlayerFactory 以及 TestPlayerFactory。该 4 种工厂分别对应 4 个不同的 MediaPlayer 基类,分别是 StagefrightPlayer、NuPlayerDriver、MidiFile 以及 TestPlayerStub。
网友评论