Callback Functions PHP vs Java
Tags: java, php, functional
Published: 2023-03-01 12:09:21

Callback Functions, ou Funções de Retorno, são funções em linguagens de programação que são passadas como argumentos para outras funções e que são executadas pelo programa em momentos específicos durante a execução da função principal.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5t2cfg7fkq73v5v716u3.png)

Essas funções são utilizadas para permitir que a função principal chame outras funções de forma assíncrona, ou seja, sem precisar esperar que a função chamada termine sua execução antes de continuar com o restante do código. Quando a função principal chega a um ponto em que precisa de um resultado ou de uma ação específica, ela chama a função de retorno (callback function) e a execução do código continua normalmente após a chamada.

Essa técnica é muito utilizada em linguagens de programação assíncronas, como JavaScript, para lidar com eventos e processos que podem levar um tempo indeterminado para serem concluídos, como a leitura de um arquivo ou o carregamento de dados de uma API. Ao utilizar uma callback function, o programa pode continuar a executar outras tarefas enquanto aguarda o retorno da função chamada.

## PHP Callback Functions

No PHP, as **callback functions** são comumente utilizadas em funções de array, como `array_filter()` e `array_map()`, que permitem que o programador passe uma função como argumento e execute essa função em cada elemento do array. Além disso, o PHP suporta a utilização de funções anônimas (também conhecidas como **closures**), que são funções sem nome que podem ser passadas como **callbacks**.

Exemplo de utilização da função array_filter() com uma callback function anônima:

```php
$numbers = [1, 2, 3, 4, 5, 6];
$evenNumbers = array_filter($numbers, function($number) {
    return $number % 2 == 0;
});
print_r($evenNumbers); // saída: Array ( [1] => 2 [3] => 4 [5] => 6 )
```

Nesse exemplo, a função array_filter() recebe um array e uma função anônima como argumentos. A função anônima é executada em cada elemento do array e retorna true se o elemento deve ser mantido no array resultante, ou false caso contrário. No caso, a função anônima verifica se o número é par e retorna true se for verdadeiro.

## Java Callback Functions

Java também suporta funções callback, que são implementadas através de interfaces, que são como contratos que definem os métodos que devem ser implementados pelas classes que as implementam. Isso significa que, para criar uma **callback function** em **Java**, é necessário criar uma interface com o método que será executado como **callback** e, em seguida, criar uma classe que implementa essa interface e sobrescreve o método da interface.

Exemplo de utilização de uma interface para criar uma callback function:

```java
public interface Calculation {
    int calculate(int x, int y);
}

public class Calculator {
    public int performCalculation(int x, int y, Calculation calculation) {
        return calculation.calculate(x, y);
    }
}

public class Main {
    public static void main(String[] args) {
        Calculator calculator = new Calculator();
        int sum = calculator.performCalculation(10, 5, new Calculation() {
            public int calculate(int x, int y) {
                return x + y;
            }
        });
        System.out.println(sum); // saída: 15
    }
}
```

Nesse exemplo, a interface **Calculation** define um método calculate() que recebe dois argumentos inteiros e retorna um valor inteiro. A classe Calculator possui um método `performCalculation()` que recebe dois argumentos inteiros e um objeto que implementa a interface Calculation. O método `performCalculation()` executa o método `calculate()` da interface com os dois argumentos recebidos e retorna o resultado.

No método main(), é criado um objeto anônimo que implementa a interface Calculation e sobrescreve o método calculate() para realizar a soma entre os dois números recebidos. Esse objeto é passado como argumento para o método performCalculation() da classe Calculator, que executa a soma e retorna o resultado.

Em **Java**, a função equivalente a `array_filter()` do **PHP** é a `filter()` da **API Stream** da classe **Collection**. A **API Stream** foi introduzida no **Java 8** e permite o processamento de coleções de elementos de forma mais flexível e eficiente.

Segue um exemplo de utilização da **API Stream** para filtrar uma lista de números inteiros e manter apenas os números pares:

Segue um exemplo de utilização da **API Stream** para filtrar uma lista de números inteiros e manter apenas os números pares:

```java
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
        List<Integer> evenNumbers = numbers.stream()
                                            .filter(n -> n % 2 == 0)
                                            .collect(Collectors.toList());
        System.out.println(evenNumbers); // saída: [2, 4, 6]
    }
}
```

## Diferenças entre Callback Functions em PHP e Java

A principal diferença entre **callback functions** em PHP e Java é a forma como são definidas. Em PHP, **callback functions** podem ser definidas usando uma **string** ou um **array**, enquanto em **Java**, elas são definidas usando interfaces. Java também suporta interfaces funcionais, o que torna mais fácil definir **callback functions**. Outra diferença significativa é a forma como as  **callback functions** são usadas. Em PHP, elas são principalmente usadas em funções que aplicam uma função definida pelo usuário a cada elemento de um array, enquanto em Java, elas são principalmente usadas em ouvintes de eventos.

Mais exemplos 

```php
<?php
$strings = ["apple", "orange", "banana", "coconut"];
$lengths = array_map( function($item) { return strlen($item); } , $strings);
print_r($lengths);
?>
```

```java
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        List<String> strings = Arrays.asList("apple", "orange", "banana", "coconut");
        List<Integer> lengths = strings.stream()
                                        .map(String::length)
                                        .collect(Collectors.toList());
        System.out.println(lengths); 
    }
}
```

A função `map()` é utilizada para transformar cada elemento da stream no seu comprimento, utilizando a referência de método `String::length.` Essa referência de método é uma forma concisa de chamar o método `length()` de cada elemento da stream.

Por fim, é utilizada a função `collect()` para coletar os elementos transformados em uma nova lista.

O resultado é a mesma lista de comprimentos obtida com o código em **PHP** e com o código Java sem a **API Stream**. Note que a API Stream permite realizar a transformação de forma mais concisa e eficiente.

## Conclusão

**Callback functions**  são uma característica essencial das linguagens de programação que permitem passar funções como parâmetros para outras funções. **PHP** e **Java** ambos suportam **callback functions**, mas diferem na forma como são definidas e usadas. **PHP** fornece duas maneiras de definir **callback functions**, usando uma **string** ou um **array**, enquanto **Java** as define usando **interfaces**. **Java** também suporta interfaces funcionais, o que torna mais fácil definir **callback functions**. Em resumo, **callback functions**são uma parte essencial das linguagens de programação que tornam possível escrever código mais flexível e reutilizável.

Essas funções são utilizadas para permitir que a função principal chame outras funções de forma assíncrona, ou seja, sem precisar esperar que a função chamada termine sua execução antes de continuar com o restante do código. Quando a função principal chega a um ponto em que precisa de um resultado ou de uma ação específica, ela chama a função de retorno (**callback function**) e a execução do código continua normalmente após a chamada.