Java 具有两个输出的重构方法
背景 我在负责重构的代码中遇到了许多方法,它们遵循以下一般模式:Java 具有两个输出的重构方法,java,groovy,functional-programming,refactoring,Java,Groovy,Functional Programming,Refactoring,背景 我在负责重构的代码中遇到了许多方法,它们遵循以下一般模式: 接受复合输入 根据某些标准查找组合的子级 从复合中删除子项,但要跟踪它们 返回更新的组合并将删除的子项附加到输出参数集合 在代码中,它如下所示: public Composite trim(Composite composite, List<Child> removed){ for (Child child : composite.getChildren()){ if (criterion(child)
public Composite trim(Composite composite, List<Child> removed){
for (Child child : composite.getChildren()){
if (criterion(child)){
composite.remove(child);
removed.add(child);
}
}
}
def trim(Composite composite, Closure removeCriterion) {
List<Child> removedChildren = composite.children.findAll(removeCriterion)
List<Child> remainingChildren = composite.children - removedChildren
Composite filteredComposite = new Composite(children: remainingChildren)
[filteredComposite, removedChildren]
}
公共复合修剪(复合复合,列表已删除){
for(子项:composite.getChildren()){
if(标准(儿童)){
复合。移除(儿童);
删除。添加(子项);
}
}
}
这里有很多代码的味道,但我想解决的是如何将其重构为不可变的代码,从而不写入输出参数
可能,但不是那么优雅的解决方案
public Map<String, Object> trim(Composite composite){
final List<Child> removableChildren = filter(composite);
final Composite trimmed = copyCompositeWithoutChildren(composite, removableChildren);
return wrapInMap(removableChildren, trimmed);
}
公共地图修剪(复合){
最终列表removableChildren=过滤器(复合);
最终复合修剪=copyCompositeWithoutChildren(复合,removableChildren);
返回wrapInMap(removableChildren,修剪);
}
问题
public Map<String, Object> trim(Composite composite){
final List<Child> removableChildren = filter(composite);
final Composite trimmed = copyCompositeWithoutChildren(composite, removableChildren);
return wrapInMap(removableChildren, trimmed);
}
有没有更简洁的方法来实现这一点,例如,使用函数式编程方法(如groovy或Java8中的collect或splice)在JavaPre-8中提供更好(尽管更详细)的方法?如能提供任何一种语言的示例,将不胜感激
编辑:
第二种可能的解决方案
public Map<String, Object> trim(Composite composite){
final List<Child> removableChildren = filter(composite);
final Composite trimmed = copyCompositeWithoutChildren(composite, removableChildren);
return wrapInMap(removableChildren, trimmed);
}
灵感来源:使用策略模式
public interface FilterStrategy {
List<Child> filter(List<Child> children);
}
public interface RemovalResponseStrategy {
void respond(List<Child> removedChildren);
}
public class CompositeTrimmer {
private final FilterStrategy filterStrategy;
private final RemovalResponseStrategy removalResponseStrategy;
public Composite trim(final Composite composite){
final List<Child> removableChildren =
filterStrategy.filter(composite.getChildren());
final Composite trimmed =
copyCompositeWithoutChildren(composite, removableChildren);
removalResponseStrategy.respond(removableChildren);
return trimmed;
}
}
公共接口过滤器策略{
列表过滤器(列出子项);
}
公共接口移除ResponseStregy{
无效响应(列出移除的子项);
}
公共类复合器{
私人最终筛选策略筛选策略;
私人最终拆迁责任范围拆迁责任范围;
公共复合材料饰件(最终复合材料){
最终列表removableChildren=
filterStrategy.filter(composite.getChildren());
最终复合修剪=
copyCompositeWithoutChildren(复合、可移除的子对象);
RemovalResponseStregy.Response(removableChildren);
返回修剪;
}
}
你没有说你有什么样的自由来改变复合类,或者哪些方法是
已经有了。所以我只是编了些东西。它可能会重新安装到您现有的位置
很容易
更具groovy风格的解决方案如下:
public Composite trim(Composite composite, List<Child> removed){
for (Child child : composite.getChildren()){
if (criterion(child)){
composite.remove(child);
removed.add(child);
}
}
}
def trim(Composite composite, Closure removeCriterion) {
List<Child> removedChildren = composite.children.findAll(removeCriterion)
List<Child> remainingChildren = composite.children - removedChildren
Composite filteredComposite = new Composite(children: remainingChildren)
[filteredComposite, removedChildren]
}
非常感谢。关于改变复合类和注入行为的观点改变了我对这个问题的看法。我将根据这一反思编写另一个解决方案。