Java中如何将Setter方法作为方法参数传入?附代码重构场景
解决Java遗留代码中重复循环的高效重构方案
兄弟,你这个重构思路完全找对方向了!50多个重复的循环确实是维护噩梦,用Java 8引入的函数式接口就能完美解决把Setter作为参数传入通用方法的问题,下面给你一步步拆解实现方案:
核心思路:用Consumer<Customer>抽象变化的Setter逻辑
Java 8的java.util.function.Consumer接口专门用来表示“接收一个参数并执行操作、无返回值”的行为,正好匹配你需要的“给Customer对象调用某个Setter”的场景。我们只需要把这个接口作为参数传入你的magicMethod,就能把不同渠道的Setter逻辑解耦出来。
第一步:修改通用方法magicMethod
先优化你的通用方法,添加Consumer<Customer>参数,同时做两个小优化:
- 把
containsKey+get改成直接get后判空,减少一次Map查找,提升效率 - 移除多余的
map.put:因为Customer是引用类型,修改对象内部属性后,Map中保存的引用指向的对象已经是修改后的状态,不需要再重新put回去
修改后的代码:
private static void magicMethod( Map<Integer, Customer> customerMap, List<Integer> contactedCustomerIds, Consumer<Customer> contactUpdater ) { for (Integer customerId : contactedCustomerIds) { Customer customer = customerMap.get(customerId); if (customer != null) { // 执行传入的Setter逻辑 contactUpdater.accept(customer); // 公共的标记逻辑 customer.setCustomerHasBeenContactedAtLeastBySomethingOnce(true); } } }
第二步:调用通用方法替换所有重复循环
现在你可以用方法引用或Lambda表达式,把不同渠道的Setter逻辑传入magicMethod,一行代码替换原来的整个循环:
示例:不同渠道的调用方式
// 电话渠道 magicMethod( customerID_and_customer_Map, getListOfCustomersContactedByTelephone(), Customer::setCustomerContactedByTelephone // 方法引用,最简洁 ); // Twitter渠道 magicMethod( customerID_and_customer_Map, getListOfCustomersContactedByTwitter(), Customer::setCustomerContactedByTwitter ); // 邮件渠道(如果习惯用Lambda也可以) magicMethod( customerID_and_customer_Map, getListOfCustomersContactedByEmail(), customer -> customer.setCustomerContactedByEmail(true) );
进阶:处理多属性设置场景
如果某个渠道需要同时设置多个属性(比如不仅标记“已联系”,还要记录联系渠道),可以用Consumer.andThen()组合多个操作:
// 组合两个操作:标记Twitter已联系 + 设置最后联系渠道 Consumer<Customer> twitterUpdater = Customer::setCustomerContactedByTwitter; twitterUpdater = twitterUpdater.andThen(c -> c.setLastContactedChannel("Twitter")); // 调用通用方法 magicMethod( customerID_and_customer_Map, getListOfCustomersContactedByTwitter(), twitterUpdater );
最终效果
原来的50多个重复循环,现在都可以替换成一行简洁的调用代码,代码量骤减,后续新增渠道也只需要添加一行调用,完全避免重复代码的维护成本。
内容的提问来源于stack exchange,提问作者PatPanda
相关产品推荐
相关产品推荐

