2 回答
TA贡献1860条经验 获得超9个赞
为了扩展我的评论,您可以或多或少地机械地转换您的示例代码,如下所示:
public List<Widget> compriseWidgets(final List<Fidget> fidgetList) {
final List<Widget> widgets = new ArrayList<Widget>();
final Widget[] currentWidget = new Widget[] {null};
for (final Fidget fidget : fidgetList) {
if (currentWidget[0] == null ||
!currentWidget[0].getFizz().equals(fidget.getFizz())) {
currentWidget[0] = new Widget();
widgets.add(currentWidget);
currentWidget.setFizz(fidget.getFizz());
currentWidget.setBuzz(fidget.getFoo().length());
}
currentWidget.getCollaborators().add(fidget);
}
return widgets;
}
许多变量可以在final没有任何特殊影响的情况下生成,包括 Fidgets 和 Widgets 的列表,以及增强for循环中的循环变量。原始方法中唯一的其他变量是currentWidget,实现对其进行了修改。这可以用final长度为 1 的 ( ) 数组替换,然后可以将其第零个元素用作原始变量的直接替换。
一个更麻烦的要求是您不能使用赋值语句(变量声明中的初始化程序不被视为“赋值”)。这正在推动一种更具功能性的编程风格,我想这可能是您的新指南的意图。然后,您可以像这样处理它:
public List<Widget> compriseWidgets(final List<Fidget> fidgetList) {
final List<Widget> widgets = new ArrayList<Widget>();
final ListIterator<Fidget> fidgets = fidgetList.listIterator();
while (addWidget(widgets, fidgets)) { /* empty */ }
return widgets;
}
private boolean addWidget(final List<Widget> widgets, final ListIterator<Fidget> fidgets) {
if (fidgets.hasNext()) {
final Fidget firstFidget = fidgets.next();
final Widget currentWidget = new Widget();
widgets.add(currentWidget);
currentWidget.setFizz(firstFidget.getFizz());
currentWidget.setBuzz(firstFidget.getFoo().length());
currentWidget.getCollaborators().add(firstFidget);
while (fidgets.hasNext()) {
final nextFidget = fidgets.next();
if (currentWidget.getFizz().equals(nextFidget.getFizz())) {
currentWidget.getCollaborators().add(nextFidget);
} else {
fidgets.previous();
return true;
}
}
}
return false;
}
这几乎是相同的技巧,只是不太明显。可变状态隐藏在调用堆栈(每次调用addWidget()代表原始方法的突变currentWidget())和容器对象中,这次是 a ListIterator。
人们可以在函数式编程方向上走得更远。例如,一般来说,您可以考虑基于流的方法,尽管我认为在这种特殊情况下,这并不是完全干净的。然而,更一般的函数式编程没有适用于 Streams 的约束。
TA贡献1796条经验 获得超10个赞
Builder 设计模式是构建不可变对象的好方法。来源: https ://stackoverflow.com/a/15461337/4245294
我喜欢这个设计模式的这个版本的地方在于它如何在创建对象之前为您提供验证规则的完美位置。
应用于此问题的示例:
public class Widget {
private final String fizz;
private final Long buzz;
private final List<Fidget> collaborators;
private Widget(Builder builder) {
this.fizz = builder.fizz;
this.buzz = builder.buzz;
this.collaborators = builder.collaborators;
}
public static Builder builder() {
return new Builder();
}
public static class Builder {
private String fizz;
private Long buzz;
private List<Fidget> collaborators = new ArrayList<>();
public Builder addFizz(String fizz) {
this.fizz = fizz;
return this;
}
public Builder addBuzz(Long buzz) {
this.buzz = buzz;
return this;
}
public Builder addCollaborators(List<Fidget> fidgets) {
collaborators.addAll(fidgets);
return this;
}
public Builder addCollaborator(Fidget fidget) {
collaborators.add(fidget);
return this;
}
private void validate() throws InvalidArgumentException{
ArrayList<String> invalidArguments = new ArrayList<>();
boolean failedValidation = false;
if (collaborators.isEmpty()) {
invalidArguments.add("collaborators");
failedValidation = true;
}
if (this.fizz == null) {
invalidArguments.add("fizz");
failedValidation = true;
}
if (this.buzz == null) {
invalidArguments.add("buzz");
failedValidation = true;
}
if (failedValidation) {
throw new InvalidArgumentException(invalidArguments.toArray(new String[0]));
}
}
public Widget build() {
validate();
return new Widget(this);
}
}
}
然后您创建一个有效的 Widget 对象,如下所示:
Widget widget = Widget.builder().addFizz("test").addBuzz(999).addCollaborators(fidgets).build();
您的compriseWidget方法存在我在对问题的评论中提到的问题,否则我也会为此提供一个示例。
添加回答
举报