如何在工厂模式中避免条件语句?符合SOLID原则的按钮创建方案
解决方案:基于注册式工厂实现符合SOLID的实例创建
当然可以实现,核心是采用基于注册机制的工厂模式,严格遵循SOLID原则中的开闭原则(对扩展开放、对修改关闭)和依赖倒置原则,新增操作系统类型时完全不需要修改现有代码。
1. 保留原有接口与实现类
你定义的基础代码可直接沿用:
interface Button { void Click(); } class AndroidButton implements Button { @Override public void Click() { System.out.println("Android按钮被点击"); } } class IOSButton implements Button { @Override public void Click() { System.out.println("iOS按钮被点击"); } }
2. 实现注册式工厂类
创建一个维护按钮类型注册表的工厂,仅负责实例创建逻辑,同时提供外部注册新类型的入口:
import java.util.HashMap; import java.util.Map; import java.util.function.Supplier; class ButtonFactory { // 注册表:key为操作系统标识,value为按钮实例的供应器 private static final Map<String, Supplier<Button>> buttonRegistry = new HashMap<>(); // 对外暴露的注册方法:允许外部添加新的按钮类型 public static void registerButton(String osType, Supplier<Button> buttonSupplier) { buttonRegistry.put(osType.toLowerCase(), buttonSupplier); } // 实例创建方法:根据操作系统标识获取对应实例 public static Button createButton(String osType) { Supplier<Button> supplier = buttonRegistry.get(osType.toLowerCase()); if (supplier == null) { throw new IllegalArgumentException("不支持的操作系统类型: " + osType); } return supplier.get(); } }
3. 初始化注册现有类型
在应用启动阶段注册已有的按钮类型(可放在静态代码块、启动类或配置类中):
// 初始化注册现有按钮 static { ButtonFactory.registerButton("android", AndroidButton::new); ButtonFactory.registerButton("ios", IOSButton::new); }
4. 使用方式
根据输入的操作系统字符串直接创建实例:
String os = "ios"; Button button = ButtonFactory.createButton(os); button.Click(); // 输出:iOS按钮被点击
5. 新增操作系统类型的扩展方式
如果需要新增WindowsButton,仅需两步操作,完全不需要修改现有代码:
- 实现Button接口:
class WindowsButton implements Button { @Override public void Click() { System.out.println("Windows按钮被点击"); } }
- 注册新类型:
ButtonFactory.registerButton("windows", WindowsButton::new);
之后就可以直接通过ButtonFactory.createButton("windows")获取对应实例。
符合SOLID原则的验证
- 单一职责原则:工厂类仅负责按钮实例的创建与注册;每个按钮类仅负责自身的点击逻辑。
- 开闭原则:新增类型时仅需添加新实现类并注册,无需修改工厂或已有类的代码。
- 依赖倒置原则:工厂与调用方均依赖
Button接口,而非具体的按钮实现类。 - 里氏替换原则:任何
Button的实现类都可替代接口使用,不会破坏原有逻辑。 - 接口隔离原则:
Button接口仅定义必要的Click方法,无冗余方法。
内容的提问来源于stack exchange,提问作者LightSouls
相关产品推荐
相关产品推荐

