如何简化仅动态调用不同对象方法的重复按钮事件处理代码
如何简化仅动态调用不同对象方法的重复按钮事件处理代码
嘿,我完全懂你现在的感受——看着一堆几乎一模一样的代码重复五六遍,简直想挠头!别担心,咱们可以用Java里的函数式接口来搞定这个问题,完美解决你说的“把方法当参数传”的需求。
问题核心分析
你的代码里每个分支的逻辑几乎完全一致,唯一的差异只有两点:
- 给
inputType赋值的字符串 - 从
myList[i]对象中获取对应属性的方法(比如getFirstName()、getLastName())
所以我们可以把这两个可变部分抽象成参数,把重复的逻辑抽成一个通用方法。
步骤1:定义函数式接口
首先,我们需要一个接口来描述“从对象中提取字符串属性”这个行为,用@FunctionalInterface标记它(表示这是一个只有单一抽象方法的函数式接口,支持Lambda表达式):
@FunctionalInterface private interface AttributeExtractor<T> { String extract(T item); }
这里的T是你myList中元素的实际类型(比如你的用户对象类名),extract方法负责从对象中取出我们需要比对的属性字符串。
步骤2:编写通用处理方法
接下来把所有重复的循环、判断逻辑放进这个通用方法里,把可变的部分作为参数传入:
private void handleSearch(Object button, String typeLabel, AttributeExtractor<YourObjectType> extractor, String input) { if (event.getSource() == button) { this.inputType = typeLabel; for (int i = 0; i < myList.length; i++) { YourObjectType item = myList[i]; if (extractor.extract(item).equals(input)) { returnList[returnLength] = item; returnLength++; } } } }
记得把YourObjectType替换成你实际的对象类型哦!
步骤3:简化原来的if-else分支
现在,原来冗长的if-else块可以直接替换成几个简洁的方法调用,用方法引用(::语法)把对象的get方法传递进去:
handleSearch(firstNameButton, "first name", YourObjectType::getFirstName, input); handleSearch(lastNameButton, "last name", YourObjectType::getLastName, input); handleSearch(usernameButton, "username", YourObjectType::getUsername, input); handleSearch(domainNameButton, "domain name", YourObjectType::getDomainName, input); handleSearch(domainExtensionButton, "domain extension", YourObjectType::getDomainExtension, input);
进阶优化:用映射实现更灵活的扩展
如果以后还要加更多搜索按钮,上面的写法还是要加新的方法调用。我们可以用Map来把按钮和对应的参数绑定,进一步简化:
// 先创建按钮与参数的映射(可以放在初始化方法里,比如init()或者构造函数) Map<Object, Pair<String, AttributeExtractor<YourObjectType>>> buttonMappings = new HashMap<>(); buttonMappings.put(firstNameButton, new Pair<>("first name", YourObjectType::getFirstName)); buttonMappings.put(lastNameButton, new Pair<>("last name", YourObjectType::getLastName)); buttonMappings.put(usernameButton, new Pair<>("username", YourObjectType::getUsername)); buttonMappings.put(domainNameButton, new Pair<>("domain name", YourObjectType::getDomainName)); buttonMappings.put(domainExtensionButton, new Pair<>("domain extension", YourObjectType::getDomainExtension)); // 事件处理逻辑只需要这一段 Pair<String, AttributeExtractor<YourObjectType>> mapping = buttonMappings.get(event.getSource()); if (mapping != null) { inputType = mapping.getKey(); AttributeExtractor<YourObjectType> extractor = mapping.getValue(); for (int i = 0; i < myList.length; i++) { YourObjectType item = myList[i]; if (extractor.extract(item).equals(input)) { returnList[returnLength] = item; returnLength++; } } }
这里的Pair如果你的Java环境没有现成的(比如非JavaFX项目),可以自己写一个简单的Pair类:
private static class Pair<K, V> { private final K key; private final V value; public Pair(K key, V value) { this.key = key; this.value = value; } public K getKey() { return key; } public V getValue() { return value; } }
这样一来,以后新增搜索按钮只需要在映射里加一行代码就行,完全不用修改核心的处理逻辑,代码的可维护性直接拉满!
备注:内容来源于stack exchange,提问作者Adrian Maciuca
相关产品推荐
相关产品推荐

