Por que eu abomino Métodos Estáticos?

Da série: Como não aprender Orientação a Objeto

Erick Carvalho
Published in
7 min readApr 5, 2017

--

E aweeeee meu povo!!!!!

Sempre que converso com desenvolvedores — sejam eles experientes ou novatos na linguagem ABAP — e entramos no assunto métodos estáticos, sinto que entramos em uma área de conhecimento nebulosa e escura sobre quando utilizar (ou não utilizar) este recurso.

Prepare a pipoca e a vitamina de abacate

O que são métodos estáticos

Segundo a definição da wikipedia para um método estático, temos:

Métodos estáticos não requerem uma instância da classe nem podem acessar implicitamente os dados (this, self, ME[este aqui é utilizado no nosso querido ABAP], etc.) de tal instância. Um método estático é distinguido em algumas linguagens de programação com a palavra-chave static, colocada em algum lugar na assinatura do método.Em linguagens de tipagem estática, como o Java, métodos estáticos são chamados “estáticos” pelo fato deles serem resolvidos estaticamente (isto é, em tempo de compilação) baseado na classe que eles são chamados, e não dinamicamente, como no caso dos métodos de instância que são resolvidos polimorficamente baseados no tipo de tempo de execução do objeto. Entretanto, métodos estáticos não podem ser sobrescritos.

Trocando em miúdos, métodos e atributos estáticos só podem acessar outros métodos e atributos estáticos da mesma classe, o que faz todo sentido já que dentro de um método estático não temos acesso à referência ME, uma vez que um método estático é chamado através da classe, e não através de um objeto.

Quem leu meu post sobre Singleton já pode imaginar a razão pela qual eu acho perigoso o uso de métodos estáticos, pois como vimos singleton está mais para um antipattern do que para um design pattern, como muitos ainda o consideram.

Coloquei meu ponto de vista sobre o Singleton, mas hoje quero conversar mais sobre métodos estáticos. Então se ainda não estiver claro:

Não! Eu não gosto de métodos estáticos.

Quando vejo que algum desenvolvedor utilizou esse recurso, normalmente eu faço o sinal da cruz como forma de proteção (e quem me conhece sabe que eu não sou o muito religioso).

Então você deve estar se perguntando: “Se métodos estáticos são ruins, por que as linguagens de programação continuam com a sua utilização?”. Essa é uma boa questão, já que obviamente métodos estáticos não foram criados para serem ruins. O problema é que para o paradigma da orientação eles são perigosos, isso porque na maioria das vezes sua utilização não se dá da melhor forma.

Objetos estáticos x Objetos de instância

Antes de continuarmos, eu, no meu TOC sobre ter certeza de que todos estarão no mesmo nível de conhecimento sobre o assunto, farei uma introdução sobre o tema. Pois bem:

Qual a diferença entre objetos estáticos x objetos de instância?

Resposta curta e objetiva: Em ABAP, temos membros de instância (variáveis e métodos) e membros estáticos:

  • Os membros de instância pertencem a uma instância de uma classe (popularmente conhecido como objeto);
  • Os membros estáticos podem ser acessados diretamente na classe (você não precisa de uma instância de uma classe para se referir a membros estáticos).

Membros de instância são variáveis e métodos que você só pode acessar quando você tem uma instância de uma classe, como no exemplo abaixo:

CLASS bar8 DEFINITION.PUBLIC SECTION
METHODS: get_data IMPORTING iv_date TYPE d.
ENDCLASS.CLASS bar8 IMPLEMENTATION.

METHOD get_data.
ENDMETHOD.
ENDCLASS.DATA(data) = NEW bar8( )->get_data( ‘20130313’ ).

Nesta situação data é uma instância da classe bar8. O objetodata possui um método chamado get_data( ) . Um ponto importante aqui a se observar é que este método só está disponível após a criação de um objeto, que neste caso é uma instância da classe bar8 .

Nós nunca deveríamos ter situações como no código abaixo:

static=>realiza_passo_01( ).
static=>realiza_passo_02( ).
static=>realiza_passo_03( ).
static=>realiza_passo_04( ).

Mas preciso confessar que já vi muito, mas muito código escrito dessa forma. Essa é uma tentativa de chamar uma rotina como um método estático. Isso não deveria fazer sentido, mas na cabeça de alguns pseudo-desenvolvedores, faz. Isso foi feito apenas pela praticidade de não precisar preocupar-se com a criação de um objeto ou questões relacionadas a possibilidade de livre acesso. O cheiro de procedural aqui é muito forte, já que:

Boa utilização de Métodos Estáticos.

Vou colocar aqui as únicas situações em que faço uso de métodos estáticos. Serão essas as únicas e as melhores situações em que você poderá utilizar métodos estáticos? Talvez não, mas se você tiver uma outra situação, por favor deixe nos comentários.

  1. Declaração de constante global. Exemplo: Utilização de ícones. Não importa qual seja o sistema SAP em que você esteja trabalhando, os ícones não mudaram. Nesses casos, eu utilizo métodos estáticos como uma forma de constante global, assim posso utilizá-los em diversas partes do programa que estou construindo.
  2. Além do Singleton, temos também um design pattern chamado Factory Method, que em resumo trata-se de um método estático que retorna um objeto, só que com a possibilidade de ir além das atribuições de um construtor, sendo capaz de retornar uma instância de uma subclasse por exemplo.

Métodos estáticos de forma abominável.

Caso você veja um código que não se enquadre nos exemplos acima, na minha opinião, trata-se de um código perigoso.

Na maior parte das vezes em que vi o emprego de um recurso estático, sabia que estava diante de um código procedural. Claramente é possível fazer a comparação de métodos estáticos com aqueles objetos criado pela SE37 (muito popularmente conhecidos como funções, porém com uma sintaxe maneira do ABAP Objects).

A única razão para utilizarmos esses recursos é a possibilidade de podermos chamá-los em qualquer lugar e de qualquer lugar.

Primeiramente, devo citar que métodos estáticos são a morte quando você utiliza TDD, isso pois a questão básica com os métodos estáticos é que eles são código procedural. Eu não tenho idéia de como testar de forma unitária um código procedural. O teste de unidade pressupõe que eu possa instanciar um pedaço do meu aplicativo isoladamente, e durante a instanciação eu conecto as dependências com mocks/stubs que substituem as dependências reais. Com a programação procedural não há o que fazer, uma vez que não há objetos, assim não existe domínio, o seu código não passa de procedimentos isolados.

Métodos estáticos são abomináveis, pois de fato indicam não se saber de onde eles pertencem, como também não possuem contexto, isso por não possuir um estado.

Pensando em SRP (Princípio de Responsabilidade Única), este princípio é, na maior parte das vezes, violado com o uso de um método estático, isso porque este tende a ter uma responsabilidade que não é a mesma da classe em que está associado.

O método estático aumenta a complexidade do seu código por não possuir estado e não precisar de contexto para existir, o que permite a liberdade (privada de bom senso) de se criar vários métodos distintos, forçando um outro desenvolvedor a ter que ir fundo no código durante a manutenção para ter certeza que o código alterado não lhe renderá surpresas.

métodos de instância são usados em uma classe que faz parte de um contexto. Assim, ter uma instância desse objeto permitirá ao desenvolvedor que dê manutenção neste código saber todas as ações que podem ser afetadas ao alterar aquele comportamento.

Por último, mas não menos importante, os métodos estáticos também não são polimórficos. Se você criar um método estático em uma classe, não há substituição para esse comportamento. Você está preso em uma referência rígida dessa implementação.

Performance — Estático x Instância

Já discuti isso algumas vezes com o Adriano Campanhola e Antelio I. Abe, porém em ABAP nunca encontrei uma documentação oficial feita pela SAP falando sobre o assunto. Mesmo em discussões em grupos da SCN, esse tema nunca ficou muito claro para mim, por isso sou incapaz de julgar, mas caso você tenha conhecimento sobre o assunto, ficarei grato em tomar conhecimento. Entretanto, em outras linguagens como C# e Java o assunto não é tão oculto e temos melhores definições.

A Microsoft, neste post, se posiciona informando que um método estático chega a ser de 4 a 5 vezes mais rápida do que um método de instância. Porém, é feito uma ressalva que esse tempo é dado em algumas dezenas de nanosegundos, assim sendo improvável que você perceba qualquer benefício. Detalhe: esse post é de 2003, então imaginem só hoje em dia.

Já o Java passou por algumas alterações, já que antes do Java 8 o que era entendido é que métodos estáticos eram alocados na memória Stack, enquanto que os de instância ficavam na memória Heap, simples assim. Porém, com a atualização as coisas mudaram, como é possível ler no post sobre From PermGen to Metaspace. Esse é outro caso onde a teoria mostra que métodos estáticos são mais rápidos, porém na prática essa velocidade não é sentida.

Para você obter a confirmação definitiva, basta baixar o código fonte OpenJDK para estudar. Como a maioria de nós tem conhecimento, existem matérias estudadas na faculdade onde apenas metendo a mão na massa é possível provar alguma coisa, e essa por envolver sistema operacional é definitivamente uma dessas matérias.

Conclusão

Lembre-se: quando você criar um método estático, pare para pensar sobre isso com cuidado. Eu não estou defendendo nunca usá-los. Estou defendendo verificar primeiro se há uma boa razão para isso, e também para ver se o método estático realmente pertence a outra classe onde ele possa usar o estado.

--

--

Editor for

Agilista, Desenvolvedor e quando não está discutindo TDD está sendo repreendido por algum comentário infeliz