写一个 Android 版本的抽象工厂弹窗 + Manager 管理器,使用 DialogFragment
实现,这样能更贴近真实的开发场景。
结构设计
- 抽象产品:
BaseDialogFragment
(继承DialogFragment
) - 具体产品:
LoginDialogFragment
,UpdateDialogFragment
- 抽象工厂:
DialogFactory
- 具体工厂:
LoginDialogFactory
,UpdateDialogFactory
- 弹窗管理器:
DialogManager
(统一展示 / 关闭弹窗)
代码实现
抽象产品
import android.app.Dialog;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.DialogFragment;
public abstract class BaseDialogFragment extends DialogFragment {
@NonNull
@Override
public abstract Dialog onCreateDialog(@Nullable Bundle savedInstanceState);
public void dismissDialog() {
if (getDialog() != null && getDialog().isShowing()) {
dismiss();
}
}
}
具体产品
import android.app.AlertDialog;
import android.app.Dialog;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
public class LoginDialogFragment extends BaseDialogFragment {
@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
return new AlertDialog.Builder(requireContext())
.setTitle("登录")
.setMessage("请输入账号密码")
.setPositiveButton("确定", (dialog, which) -> {
// 登录逻辑
})
.setNegativeButton("取消", null)
.create();
}
}
import android.app.AlertDialog;
import android.app.Dialog;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
public class UpdateDialogFragment extends BaseDialogFragment {
@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
return new AlertDialog.Builder(requireContext())
.setTitle("更新提示")
.setMessage("检测到新版本,是否更新?")
.setPositiveButton("更新", (dialog, which) -> {
// 更新逻辑
})
.setNegativeButton("稍后", null)
.create();
}
}
抽象工厂
public interface DialogFactory {
BaseDialogFragment createDialog();
}
具体工厂
public class LoginDialogFactory implements DialogFactory {
@Override
public BaseDialogFragment createDialog() {
return new LoginDialogFragment();
}
}
public class UpdateDialogFactory implements DialogFactory {
@Override
public BaseDialogFragment createDialog() {
return new UpdateDialogFragment();
}
}
弹窗管理器
import androidx.fragment.app.FragmentManager;
import java.util.HashMap;
import java.util.Map;
public class DialogManager {
private static final Map<String, BaseDialogFragment> dialogCache = new HashMap<>();
public static void showDialog(String key, DialogFactory factory, FragmentManager fragmentManager) {
if (!dialogCache.containsKey(key)) {
dialogCache.put(key, factory.createDialog());
}
BaseDialogFragment dialog = dialogCache.get(key);
if (dialog != null && !dialog.isAdded()) {
dialog.show(fragmentManager, key);
}
}
public static void dismissDialog(String key) {
BaseDialogFragment dialog = dialogCache.get(key);
if (dialog != null) {
dialog.dismissDialog();
dialogCache.remove(key);
}
}
}
使用示例 (Activity 中调用)
public class MainActivity extends AppCompatActivity {
@Override
protected void onResume() {
super.onResume();
// 显示登录弹窗
DialogManager.showDialog("login", new LoginDialogFactory(), getSupportFragmentManager());
// 显示更新弹窗
DialogManager.showDialog("update", new UpdateDialogFactory(), getSupportFragmentManager());
// 关闭登录弹窗
DialogManager.dismissDialog("login");
}
}
✅ 优点:
- 扩展性强:新增一个弹窗,只需要新增
DialogFragment
+Factory
,DialogManager
无需改动 - 全局管理:可以统一控制弹窗的缓存、复用、显示/关闭逻辑
- 线程安全:使用
FragmentManager
管理生命周期,避免内存泄漏
再加一个 全局策略(比如保证同一时间只显示一个弹窗,后来的会自动关闭之前的)
在 DialogManager
里加一个 全局策略:同一时间只允许显示一个弹窗。这样新的弹窗显示时,会自动关闭之前的。
改造后的 DialogManager
import androidx.fragment.app.FragmentManager;
import java.util.HashMap;
import java.util.Map;
public class DialogManager {
private static final Map<String, BaseDialogFragment> dialogCache = new HashMap<>();
private static String currentDialogKey = null; // 当前正在显示的弹窗 key
public static void showDialog(String key, DialogFactory factory, FragmentManager fragmentManager) {
// 如果有正在显示的弹窗,先关闭
if (currentDialogKey != null && dialogCache.containsKey(currentDialogKey)) {
dismissDialog(currentDialogKey);
}
// 创建或获取弹窗
if (!dialogCache.containsKey(key)) {
dialogCache.put(key, factory.createDialog());
}
BaseDialogFragment dialog = dialogCache.get(key);
// 显示弹窗
if (dialog != null && !dialog.isAdded()) {
dialog.show(fragmentManager, key);
currentDialogKey = key;
}
}
public static void dismissDialog(String key) {
BaseDialogFragment dialog = dialogCache.get(key);
if (dialog != null) {
dialog.dismissDialog();
dialogCache.remove(key);
if (key.equals(currentDialogKey)) {
currentDialogKey = null;
}
}
}
public static void dismissCurrentDialog() {
if (currentDialogKey != null) {
dismissDialog(currentDialogKey);
}
}
public static boolean isDialogShowing() {
return currentDialogKey != null;
}
}
使用示例
public class MainActivity extends AppCompatActivity {
@Override
protected void onResume() {
super.onResume();
// 显示登录弹窗
DialogManager.showDialog("login", new LoginDialogFactory(), getSupportFragmentManager());
// 这里再显示更新弹窗时,会自动关闭上一个(login)
DialogManager.showDialog("update", new UpdateDialogFactory(), getSupportFragmentManager());
// 关闭当前正在显示的弹窗(update)
DialogManager.dismissCurrentDialog();
}
}
✅ 这样就具备了:
- 抽象工厂扩展性:新增弹窗不用改管理器。
- 缓存 & 复用:避免重复创建相同弹窗。
- 全局策略:同一时间只显示一个弹窗。
- 可选扩展:还能加优先级队列(比如:强制更新弹窗 > 登录弹窗 > 普通提示弹窗)。