Variáveis fracamente tipadas – uma análise baseado na experimentação com PHP

Publicado por José Luz
10/7/2012
Categoria:
Tags: , , ,

Nos últimos tempos tive a oportunidade de trabalhar com PHP. Sim, o terrível e abominável PHP!! O que vou relatar é minha opinião sobre um aspecto específico dessa famigerada linguagem – variáveis. O que se nota é que em PHP as variáveis são elementos tratados de forma estritamente técnica e sem muito uso de abstração, isso pode ser bem perigoso para o desenvolvimento.

Como eu nunca tive muito contato com PHP, além de poucos exemplos e alguns “hello word”s em tempos remotos, a experiência foi muito interessante e acredito que muito acrescentou. Como venho de uma escola vanguardista de Orientação a Objetos (OO) e engenharia de software, sou um “militante” dos bons costumes e das boas práticas de programação como um todo, acredite, rever tal linguagem foi, no inicio, quase torturante e doloroso.

A tarefa era simples: incluir a funcionalidade de pagamento a uma aplicação herdada que se dividia em um front-end em Html + Javascript e um back-end em PHP, ou seja, não tive acesso aos elementos visuais que o PHP dispõe, por isso vou falar da linguagem sem citar esta parte. Ao iniciar a programação, logo de cara constatei que esta linguagem é “fracamente tipada”, ou seja, ela não permite que variáveis sejam declaradas com um determinado tipo – a menos que sejam variáveis declaradas como parâmetros de funções e ainda sim não é obrigatório “tipá-las”, mas este é outro caso.

Bem, vamos pensar no aspecto fracamente tipado da linguagem, este fato não é de todo mal, se pensarmos em um caso de manutenção onde ocorra a troca de uma classe por outra. Vejamos um exemplo em C#, o qual existe a “tipagem” através do token var. Deixo claro que para este exemplo vou ignorar uma solução com interface.

Bloco 1

    var client = ClientFactory.BuildClient();
    Console.Write(client.ToString());

Bloco 2

public class ClientFactory
{
    public ClientA BuildClient()
    {
        return new ClientA('This is client A');
    }
}

Se eu quiser trocar a implementação do método BuildFactory para retornar um ClientB, ao invés, do ClientA, eu não vou precisar alterar nada no bloco 1. Porém em tempo de execução a variável client do bloco 1 vai ser, durante todo o seu tempo de vida, uma variável do tipo ClientA ou ClientB segundo a implementação do BuildFactory. O que torna impossível tentar atribuir outro tipo de valor. E isso não ocorre em PHP. É possível atribuir um objeto complexo à uma variável e em seguida atribuir um número inteiro à mesma variável dentro de um mesmo escopo. Veja o exemplo:

function doStuff(){
    $my_var = new complexObject();
    $my_var->executeObjectFunction('param1');
    $my_var = 2;
    return $my_var;
}

E a aplicação vai retornar o número 2, que é o valor atribuído à variável no momento em que a função efetua o retorno.

Quando atribuímos a uma variável um nome, estamos lhe dando muito mais do que um identificador para um local da memória. Definimos uma função e capacidade, o que ocorre com linguagens como PHP é que a parte técnica é elevada até a camada superior e a abstração é deixada de lado. Isso é perigoso: induz o programador ao erro.

Vou explicar: Vamos assumir a definição de variável como um elemento da computação que referencia um espaço da memória onde estão guardados um ou mais bits. Olhando por esse aspecto Von Neumanniano, um espaço de memória pode armazenar bits que podem significar qualquer coisa, afinal de contas… tudo, em computação, não passa de um amontoado de bits, seja um objeto, um valor inteiro ou qualquer coisa que esteja disponível.

Porém quando variáveis são tratadas como elementos capazes de armazenar tudo e qualquer coisa na memória, elas podem levar o programador a ignorar, esquecer ou ser displicente com a sua principal função: representar o estado de alguma coisa em um espaço de tempo determinado. E está aí o X da questão: uma variável deve representar o estado de alguma coisa, não o estado de algumas coisas, pense assim uma chave foi feita para abrir a fechadura de uma porta e a mesma chave não deve conseguir abrir outras portas – a menos que as outras fechaduras sejam do mesmo modelo.

Há algumas vantagens em seguir este raciocínio como por exemplo: organização, manutenção do código, legibilidade, etc. Estes elementos são características importantes que auxiliam no desenvolvimento do código e permitem a evolução da aplicação ao longo do tempo e deixam um nível razoável de manutenibilidade da aplicação .

Colocando lado a lado ambas as definições, é possível ver que cada uma está em um campo de atuação diferente: A primeira se encontra nos níveis mais baixos da computação, já o segundo fica no nível mais alto ou abstrato da programação. E sem dúvida que o segundo campo de atuação usa o nível mais baixo da computação para realizar sua implementação, porém ele é ignorado de forma explícita e proposital para evitar que estes conceitos “maquinários” influenciem a programação.

Conclusão

Bem, não é porque eu tenho um martelo que isso me torna um engenheiro, em outras palavras, não é porque eu uso C#, Java, ou qualquer linguagem fortemente tipada que eu saiba usar variáveis ou uma solução focando a manutenibilidade e capaz de suportar a mutabilidade da aplicação, apesar de tornar muito mais difícil já que exigiria alguns casts para isso.

public void Configure(object obj)
{
    try
    {
        int receivedValue = (int)obj;
        ShowLineNumber(receivedValue);
    }
    catch (Exception e)
    {
        try
        {
            string receivedText = (string)obj;
            messageLabel.Text = receivedText;
        }
        catch (Exception ex)
        {
            errorMessageLabel.Text = "Erro";
        }
    }
}

ou ainda

public void Configure(string text)
{
    int receivedValue;
    if(int.TryParse(text, out receivedValue))
    {
        ShowLineNumber(receivedValue);
    }
    else
    {
        messageLabel.Text = receivedText;
    }
}

Estes exemplos são bem absurdos, mas são equivalentes, compilam e são totalmente executáveis. Por isso não podemos culpar ou inocentar um programa pela linguagem que usa, pois até em linguagens baseadas no paradigma OO é possível encontrar absurdos, o problema não está na tecnologia e sim nos programadores que muitas vezes não sabem o que é ou como usar o OO.

Por outro lado o fato da tecnologia PHP, ou qualquer outra linguagem fracamente tipada, não suportar tipagem de variável pode tornar as manutenções mais difíceis. Não pela característica em si, mas pela forma em que isso foi estruturado e que sustenta tudo isso: uma mistura dos conceitos primários da computação, como alocação da memória, como a abstração de uma variável em uma computação. Isso fatidicamente levará um programador a escrever códigos de pior qualidade, pois ele nem sempre tentará resolver o problema abstraindo-o em alto nível, ou tomará os cuidados para que o código se mantenha bem estruturado.

De toda forma eu posso pensar em alguns motivos plausíveis para este tipo de abordagem de variáveis no caso do PHP, tais como, economia de alocamento de memória para variáveis, uma vez que PHP é uma linguagem voltada para Web que foi criada nos meados dos anos 90, onde os recursos físicos eram muito mais escassos. Porém o uso de PHP como linguagem server-side, provavelmente, foi uma má, para não dizer péssima, escolha do programador original. Como diria Alexandre Cunha: “O fato do Facebook e Yahoo! serem feitos em PHP não quer dizer que a linguagem é boa, só quer dizer que o programador era muito competente.” E isso as pessoas confundem com muita facilidade.





Desenvolvido por hacklab/ com WordPress