Ponteiros para funções: exemplos
Em uma cidade quente como Cuiabá, ter aparelhos de ar-condicionado é uma necessidade.
Agora, imagine que você trabalha uma empresa que dispõe de diversos aparelhos instalados em todo o prédio, como acontece na UFMT.
Para otimizar o uso dos aparelhos, a empresa deseja desenvolver um dispositivo capaz de ligar, desligar e alterar a temperatura desses equipamentos.
Embora os fabricantes disponibilizem uma biblioteca para a manipulação de seus aparelhos de ar-condicionado, a empresa em que você trabalha possui aparelhos de diversos fabricantes em uma mesma sala. Por isso, o dispositivo que você está desenvolvendo precisa ter a capacidade de se comunicar com todos eles.
🤔 Imaginando o cenário técnico
Vamos considerar, por enquanto, dois fabricantes ar-condicionado: PantanAr e ArARA. Por uma normatização técnica, as empresas devem fornecer bibliotecas que possibilitam controlar o funcionamento de seus produtos, com a mudança de temperatura.
A PantanAr disponibiliza uma biblioteca com as seguintes implementações:
void ligar(int aparelho){
printf("PantanAr %d tá on! :D \n", aparelho);
}
void desligar(int aparelho){
printf("PantanAr %d tá off! :( \n", aparelho);
}
void alterarTemperatura(int aparelho, int temp){
printf("Temperatura do PantanAr %d alterada para %d :)\n", aparelho, temp);
}
Já a ArARA oferece uma biblioteca com as seguintes implementações:
void turnOn(int dsp){
printf("\nArARA - Device %d on", dsp);
}
void turnOff(int dsp){
printf("\nArARA - Device %d off", dsp);
}
void alterarTemperatura(int dsp, int t){
printf("\nArARA - Device %d - Current temperature %d", dsp, t);
}
👨🏻💻 Discutindo a implementação da solução
Já vimos que cada empresa oferece uma biblioteca própria para manipular seus aparelhos de ar-condicionado. Na implementação da solução para a nossa empresa, temos que pensar numa estratégia que possibilite lidar com as funções das duas bibliotecas, assim como possibilite uma fácil adequação a um terceiro fabricante, caso um aparelho de uma nova marca seja adquirido.
A melhor estratégia aqui não é chamar diretamente os procedimentos das bibliotecas de cada fabricante, mas sim criar uma biblioteca própria.
A nossa biblioteca
Assumindo que há uma padronização no protótipo dos procedimentos/funções entre os diversos fabricantes, graças a uma norma técnica, a nossa biblioteca pode ser implementada da seguinte forma:
void ligarAparelho(void (*funcaoLigar)(int), int codAparelho){
funcaoLigar(codAparelho);
}
void desligarAparelho(void (*funcaoDesligar)(int), int codAparelho){
funcaoDesligar(codAparelho);
}
void mudarTemperatura(void (*funcaoMudarTemperatura)(int), int codAparelho, int temperatura){
funcaoMudarTemperatura(codAparelho, temperatura);
}
A partir de agora, nosso programa pode lidar exclusivamente com os nomes que atribuímos aos nossos procedimentos. Embora ainda tenhamos que passar o ponteiro para a função da biblioteca de cada fabricante, todo o resto do nosso programa é independente.
Nas próximas aulas, estudaremos conceitos que nos possibilitarão extrair o máximo de benefícios dessa estratégia que começamos a ver aqui.