В этом примере нет ничего особенного в отношении способности к изменчивости. Настоящий подход заключается в изменении существующих кругов путем применения побочных эффектов, которые изменяют состояние существующего круга.
Функциональный подход заключается в создании неизменной структуры данных и создании функции, которая берет данные из первой структуры и создает новую структуру. В вашем примере функциональный подход имел бы неизменный круг, т. Е. Методы setX() или setY().
private Circle wrapCircleAroundBounds(Circle circle, double width, double height) {
double newx = (circle.getPosition().getX() > width + circle.getRadius()) ? -circle.getRadius() : width + circle.getRadius()
double newy = (circle.getPosition().getY() > height + circle.getRadius()) ? -circle.getRadius() : height + circle.getRadius()
return new Circle(newx, newy)
}
Использование функциональных возможностей Java8, вы могли бы себе представить, отображение списка кругов обернутых кругов:
circles.stream().map(circ -> wrapCircleAroundBounds(circ, width, height))
повелительном и функциональные подходы имеют различные преимущества, функциональный подход, например, intrisicaly threadsafe из-за неизменности, поэтому вы должны иметь возможность более легко распараллеливать этот тип кода. Например, можно было бы одинаково смело писать:
circles.parallelStream().map(circ -> wrapCircleAroundBounds(circ, width, height))
Я не думаю, что функциональное программирование обязательно плохо подходит для разработки игр, но, хотя это будет сделано, то это, конечно, не стандартный подход, так что вы не будете получить тот же уровень поддержки библиотеки, если вы используете функциональный язык.
Как утверждает в своем ответе dfeuer, функциональные функции Java довольно примитивны - у вас нет поддержки алгебраических типов данных, сопоставления образцов и т. Д., Что значительно облегчит выражение проблем в функциональном стиле (по крайней мере один раз вы привыкаете к этим идиомам). Я согласен с тем, что, по крайней мере, немного читаю о Haskell, у которого есть отличный учебник: http://learnyouahaskell.com/chapters - хороший способ начать работу. В отличие от Scala, который является многоязычным языком, у вас не будет возможностей OOP, чтобы отпасть, когда вы изучаете новый стиль.
Не 'круги.stream(). Map (circ -> wrapCircleAroundBounds (circ))' просто вернуть новый поток? Должен ли я в конечном итоге изменить список «кругов»? Переставить его, может быть? – Michael
@Michael Вы можете использовать '.collect (Collectors.toList())', чтобы преобразовать поток обратно в список, если это форма, в которой вам нужен результат. В функциональном программировании вы не склонны изменять или переназначать вещи, вы обычно просто сохраняете результат вычисления в новом списке. – TheInnerLight
Вы 'wrapCircleAroundBounds' полагаются на внешние значения' width' и 'height' и поэтому не являются чисто функциональными. –