Чтобы расширить мой комментарий, вы можете преобразовать пример кода более или менее механически, например так:
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и виджеты, и переменная цикла в расширенном цикле 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()
) и в объекте контейнера, на этот раз ListIterator
.
Можно было быидти дальше в направлении функционального программирования.В общем, например, вы могли бы взглянуть на потоковые подходы, хотя я не думаю, что в данном конкретном случае это работает совершенно чисто.Однако более общее функциональное программирование не имеет ограничений, применимых к потокам.