Ler isso fez com que uma verdadeira lâmpada se acendesse acima da minha cabeça. Ou seja, estava sem fazer porra nenhuma e pensei, “Caralho, dá pra fazer um monte de cantadas toscas desse tipo relacionadas a programação!“.
Quem me conhece sabe que sou um solteiro convicto, mas a oportunidade me pareceu boa demais pra deixar passar. Sabe aqueles momentos em que a inspiração bate e você não liga muito pras consequências? Então. Foi aí que acabei despejando uma torrente de frases parecidas na minha conta no Twitter, mas todas relacionadas a Object-Oriented Programming, ou OOP (Programação Orientada a Objetos, em português). Quem teve a honra prazer sorte infelicidade de acompanhar os tweets não deve ter entendido muita coisa, porque elas são realmente muito voltadas pro mundo OOP; no máximo, pode ter achado uma ou outra engraçadinha.
No entanto, pro bem da humanidade, e pra ter algum propósito minimamente útil neste artigo, decidi colocar explicações de cada frase junto de cada uma delas. Pra quem não entendeu nada quando as escrevi, pode ser uma oportunidade de entender o quão genial razoável cada uma das frases era; pra quem está aprendendo OOP, pode ser uma oportunidade de sacar alguns conceitos através de exemplos, digamos, pouco ortodoxos; e pra quem já sabe, pode ler sem precisar de muitas explicações, no máximo utilizar as descrições pra ver se acertou, e talvez, quem sabe, achar um pouco de graça.
Nota: os links que coloquei na explicação, bem como as expressões que usei, são dos conceitos originais em inglês (porque foi assim que aprendi), mas é só clicar no link pra versão em português na página da Wikipedia que se abre pra achar o equivalente em português. Além disso, alguns dos conceitos explicados nas frases do começo não são repetidos mais além, então vale a pena ler na sequência porque as explicações podem parecer meio vagas mais pro final da lista.
Gata, você é uma constante na minha classe estática. Show ▼
Em OOP, geralmente criamos
classes com uma série de métodos ou propriedades
estáticas quando precisamos de alguma funcionalidade genérica, que será acessada de diversos lugares do código, sem que uma nova
instância da classe seja usada. Feito isso, é comum utilizarmos
constantes (valores que nunca serão alterados) para guardar algum dado especial que poderá ser utilizado diversas vezes como referência.
Assim, é comum termos classes que servem para pouco mais do que guardar dados para fácil acesso de forma estática, daí o termo um tanto quanto incorreto de classe estática. Em ActionScript 3, um bom exemplo é a classe StageScaleMode que só serve para guardar dados constantes como EXACT_FIT, NO_BORDER e outros.
Gata, no Singleton do meu coração, você é a instância default. Show ▼
Em OOP, existe uma série de
design patterns que podem ser utilizados. Design patterns são combinações comuns de classes, como que receitinhas de soluções que acabam sendo bastante frequentes em projetos OOP, mesmo por quem nem sabe o que é um design pattern. O
Singleton é um dos patterns mais comuns, talvez especialmente no ActionScript; ele consiste na criação de uma classe que cria uma única instância de si mesma (a tal instância default) que pode ser acessada a qualquer momento, de qualquer lugar, através de métodos estáticos da classe. E, como alguém já disse certa vez, singleton se tornou “
o _global do ActionScript 3“, já que é bastante comum de cair na armadilha de sair criando singletons pra tudo quanto é lado em trabalhos Flash pra resolver problemas de forma rápida mas sem muito planejamento.
Gata, se meu coração é o Model, você é o Controller e eu sou o View.Show ▼
Originalmente postado errado (escrevi “Master” ao invés de “Model”), esta é outra referência a um design pattern; desta vez, ao famigerado
Model-View-Controller, ou MVC. É um pattern mais complexo, que costuma utilizar uma série de classes através de
composição, mas também bastante prático em trabalhos Flash. Resumidamente,
model é a instância que gerencia dados relacionados à classe, como o processador interno de um relógio;
view é uma instância que contém a visão desses dados, como o painel que mostra as horas do relógio;
controller é algo que permite controlar os dados, como os botões de ajuste de hora de um relógio.
Gata, não tem Garbage Collection que consiga fazer eu te esquecer. Show ▼
Garbage Collection é um termo relacionado à programação em ambientes de execução
gerenciados, onde o
gerenciamento de memória é feito pela
máquina virtual que executa um programa. É como é chamado o processo de
limpeza de memória para a remoção de dados que não são mais necessários.
Quando um dado é apagado (como quando uma variável é removida ou um objeto deixa de existir), ele não necessariamente é removido da memória; ele continua existindo, meio órfão, até que a máquina virtual que está executando o código dispare a coleta de lixo que faz com que o dado seja efetivamente esquecido. Normalmente, isso é feito de maneira cíclica, não imediata, para melhor performance.
Gata, eu ter esquecido o dia do seu aniversário é culpa de um memory leak. Show ▼
Diretamente relacionado a Garbage Collection,
memory leaks ou
vazamentos de memória acontecem quando dados são criados e nunca removidos, preenchendo a memória com dados inúteis lentamente (ou até rapidamente). Normalmente, dados que não são mais necessários só são efetivamente removidos da memória através do garbage collection quando não existem mais referências a eles. Esquecer de remover alguma referência leva aos tais vazamentos de memória, que podem até mesmo interromper a execução de um programa quando ocorrem em excesso.
Gata, sua classe é final. Show ▼
Em OOP, é comum extender uma classe através de um conceito chamado
herança. No entanto, na maioria das linguagens OOP é possível criar uma classe que não pode ser extendida, nem usada como base para outra classe; neste caso, ela é considerada uma classe
final. Esta é uma necessidade rara, no entanto.
Gata, não tem longint grande o suficiente pra dizer o quanto eu gosto de você. Show ▼
Em linguagens de programação, geralmente existem vários tipos de dados que podem ser armazenados em variáveis. Cada tipo possui um número máximo de bytes de memória que pode ocupar, em especial números, já que existe um limite nos números com que um computador pode lidar. Longint ou
long integer são tipos de dados que armazenam números inteiros
longos. Como todos os tipos numéricos, variáveis desse tipo têm um valor máximo e mínimo – e bastante altos, neste caso.
Gata, vou extender meu coração só pra fazer um override no toString() pra escrever seu nome nele. Show ▼
Classes geralmente são extendidas quando se deseja adicionar novos recursos a ela. Este tipo de controle de herança e hierarquia é uma das bases da programação orientada a objetos. Override é o processo de se substituir um método que já existe na classe base, criando um novo método substituto na classe que a extende, efetivamente mudando o comportamento da classe. Já toString() é uma função bastante usada em ActionScript pra representar um objeto como texto.
Gata, sua classe não tem clone(). Show ▼
Algumas linguagens, talvez ActionScript em especial, implementam uma função chamada
clone() que simplesmente duplica uma instância, criando um clone completo do objeto original. Certas classes especiais, no entanto, como a
Sprite, devido à sua complexidade interna, não possuem esta função.
Gata, você implementa ILoveYou. Show ▼
Além da possibilidade de se extender uma classe, em OOP também é bem comum a implementação de
interfaces ou protocolos que declaram métodos ou propriedades que uma classe pode ter (sem relação com
interfaces gráficas). Essas interfaces geralmente servem para
dar forma a instâncias e permitir que elas sejam usadas como parâmetros em funções que exigem um tipo específico de objeto. Como convenção, classes que declaram interfaces começam com a letra
I; por exemplo, em ActionScript, temos a
IBitmapDrawable.
Gata, todos os meus overloads têm você como parâmetro. Show ▼
Um conceito não utilizado no ActionScript,
overloads são funções diferentes que possuem o mesmo nome e que são executadas de acordo com os parâmetros de entrada da função. Assim, é possível ter uma função que executa dois conjuntos de comandos diferentes (embora com propósitos parecidos) dependendo dos tipos de parâmetros passados. É provável que ActionScript adote este recurso em breve, embora seja possível simulá-lo através de algumas gambiarras.
Gata, meu dispose() é disparado automaticamente se sua referência for removida da instância. Show ▼
É comum a inclusão de uma função
dispose(),
destroy(),
kill() ou semelhante em certas classes que se utilizam de muitos dados internamente. O propósito da função geralmente é preparar uma instância para deleção, já se desfazendo de todos os seus dados e abrindo caminho para o garbage collector. Um exemplo em ActionScript é o
BitmapData.dispose().
Gata, me diz qual o método da sua API que retorna seu coração. Show ▼
API, ou
Application Programming Interface, é o conjunto de métodos, funções e propriedades usados para acessar uma biblioteca de classes pública. Como o nome
interface diz, é todo o conjunto de membros para permitir o diálogo de um programa qualquer com um grupo de classes. É comum que programadores utilizem APIs de terceiros para a realização de diversas tarefas diferentes, ou para a utilização de funções que retornam os mais variados tipos de dados.
Gata, sua instância é única. Show ▼
Classes são como receitas de objetos. Inúmeros objetos, ou instâncias, podem ser criados a partir de uma única classe.
Gata, quero te extender pra classe MyGirl. Show ▼
Criar uma extensão de uma classe – processo chamado de
inheritance ou herança – é um dos principais conceitos utilizados em programação orientada a objetos. Ele permite a criação de uma nova classe que herdam todos os métodos, funções e propriedades de uma classe base, mas com nova funcionalidade ou diferentes recursos.
Gata, vamos fazer um composition que instancia nós dois. Show ▼
Em contraponto à herança,
composition ou composição é quando um ou mais objetos são utilizados dentro de um novo objeto de outra classe, ao invés de extender a classe original. Assim, objetos mais simples – mais
baixo nível – são utilizados na criação de objetos mais complexos, de nível mais alto. Por exemplo, um objeto da classe
Casal poderia ser uma composição que conteria instâncias da classe
Homem e da classe
Mulher (ou equivalentes).
Gata, depois que eu terminar com você, vão escrever um capítulo novo sobre você no Gang Of Four. Show ▼
Gang of Four é o nome comunemente dado ao livro, ou aos autores, do livro “Design Patterns: Elements of Reusable Object-Oriented Software”, um dos livros seminais na difusão dos conceitos de
design patterns entre programadores. O livro contém inúmeros exemplos dos padrões mais comuns em OOP.
Gata, depois que eu terminar com você, não vai ter refactoring que faça você me esquecer. Show ▼
Refactoring é o processo de mudança do design interno de uma classe sem mudança de sua
interface, isto é, mudança do código sem mudança de funcionalidade ou recursos. Este processo geralmente é necessário para melhorar a performance de uma classe ou para resolver problemas inesperados.
Gata, o unit testing de minha classe só retorna válido se ele te encontrar. Show ▼
Unit testing é um processo de validação de código geralmente utilizado para se testar a confiabilidade de uma classe. Ele é realizado através da checagem da saída de funções e métodos baseado nos dados de entrada, ao invés da leitura do código em si; quando uma lista de resultados necessários é gerada, uma classe pode ser testada pra ver se passa nos testes com sucesso.
Gata, depois de ser instanciada, deus removeu sua classe do repositório. Show ▼
Instanciar é o processo de criar uma nova cópia de um objeto, ou
instância, a partir de uma classe. Repositório é onde arquivos relacionados a um projeto são armazenados, geralmente através de um serviço como
CVS ou
Subversion. Serviços desse tipo são bastante utilizados por times de programadores. Essa frase é meio que um equivalente de “depois que deus te fez, jogou a planta fora”.
Gata, não tem encapsulamento que esconda o que eu sinto por você. Show ▼
Encapsulation ou encapsulamento é outro recurso chave de OOP, em referência à possibilidade de se
esconder o funcionamento de uma parte do código dentro de uma classe. Esse tipo de separação faz com que projetos OOP possam ser montados de forma mais modular, sem que haja um diálogo muito grande entre diferentes classes – cada classe deve possuir uma funcionalidade própria e não interferir com o resto do projeto.
Gata, não dá setar o que sinto por você pra null. Show ▼
Setar algo para um valor
null ou
nulo geralmente significa remover uma referência a um objeto, efetivamente apagando-o, uma vez que objetos sem referência são removidos da memória pelo garbage collector.
Gata, meu o command pattern tá preso em loveYou(). Show ▼
Gata, minha paixão está em loop infinito. Show ▼
Um dos tipos mais comuns de controle de fluxo dentro de um programa, um
loop é um conjunto de comandos que deve ser repetido diversas vezes de forma sequencial. Um tipo especialmente indesejado de loop é o
loop infinito, caracterizado por um bloco de código inescapável – geralmente causado por algum erro de programação – que acaba interrompendo a execução de um programa, uma vez que mantém o fluxo
preso num mesmo ponto.
Gata, todas as entradas do meu iterator apontam pra você. Show ▼
Gata, você não tem factory, é base class. Show ▼
Factory é um
design pattern para um tipo de classe que, como o nome diz, cria objetos de um tipo definido, como uma
fábrica. Já uma
base class ou superclass é uma classe que está no topo de sua hierarquia, e não herda funcionalidade de nenhuma outra classe, servindo ao invés como base para outras.
Note que nesta cantada os conceitos estão um pouco misturados em prol da liberdade poética.
Gata, você provocou uma exceção no init() do meu coração. Show ▼
Em OOP, exceções ou
exceptions são acontecimentos fora do comum e inesperados, geralmente disparados por algum erro interno, pelo uso de propriedades ou parâmetros inválidos, ou por valores fora do limite permitido. Essas exceções devem ser tratadas através do
tratamento de exceções ou
exception handling.
Já init(), neste caso, é um nome de função arbitrário, geralmente utilizada para funções de inicialização de um objeto.
Gata, não tem especificação que explique sua classe. Show ▼
Especificações de classes são como receitas, criadas para definir tudo que uma classe deve fazer ou deixar de fazer, em especial dentro de um ambiente corporativo ou quando trabalhando em times. Um conceito mais genérico, a idéia aqui – também fruto da liberdade poética – foi dizer que a garota alvo da cantada tinha muita classe.
Gata, você conseguiu acessar uma propriedade do meu coração que era protected até eu te conhecer. Show ▼
Propriedades de classes podem ser de diversos tipos (também chamados de access modifiers) – públicas (public), privadas (private), protegidas (protected), etc. Essa definição diz respeito aos tipos de acesso que as propriedades permitem – propriedades privadas ou protegidas, por exemplo, não podem ser acessadas por nenhuma classe além da classe que as define (embora existam diferenças entre a interpretação destas definições de linguagem para linguagem).
Gata, depois de te conhecer, deu um lock na instância do meu coração. Show ▼
Lock (trancar) e unlock (destrancar) é algo que geralmente é feito em propriedades para impedir sua modificação, protegendo os dados lá contidos.
Gata, não tem pattern que explique o que sinto por você. Show ▼
Como dito acima,
design patterns são combinações comuns de classes – como
modelos estruturais – que visam solucionar problemas rotineiros e frequentes em projetos OOP.
Gata, meu try é pra dizer o que sinto por você, pra catch seu coração, e finally te conquistar. Show ▼
Try…catch…finally é o conjunto de blocos comunemente utilizado para
tratamento de exceções em OOP para evitar erros num código; o código dentro do bloco
try é algo a ser tentado; o(s) bloco(s)
catch são utilizados para a execução de comandos específicos quando algum erro acontece durante o bloco try; e o bloco
finally é para a definição de comandos que são executados após o teste.
Esta frase na verdade é a que mais abusa de liberdade poética, uma vez que, caso os comandos executados pelo bloco try tenham sucesso, o bloco catch é ignorado.
Gata, quero adicionar um listener em todos os seus eventos. Show ▼
Em OOP, é também bastante comum a utilização do pattern
Observer, que define a criação de objetos que contém
eventos que são disparados quando uma condição é atingida, como o pressionar de uma tecla, o carregamento de um arquivo, ou um erro. Neste pattern, muito utilizado em programas que precisam de interação com o usuário, outros objetos podem assinar os eventos, virando assim
listeners. Listeners são
notificados quando um evento ocorre no objeto que o disparou, permitindo assim funcionamentos específicos baseados em eventos.
Gata, você é tão única que seu prototype é private. Show ▼
Em certas variantes de OOP, todos os objetos possuem um prototype, que é um objeto único que define os métodos e propriedades básicos de uma classe, comuns a todas as suas instâncias. Esse prototype geralmente pode ser publicamente acessado e modificado, tornando possível a uma classe a mudança de funcionalidades internas em tempo real, embora este seja um recurso pouco ortodoxo.
Gata, todos os seus erros são fatais para meu coração. Show ▼
Durante o tratamento de erros de execução de projetos OOP, em especial durante o
tratamento de exceções, existem diversas categorias genéricas de erros que podem ocorrer, desde
warnings (avisos meramente informativos) até
fatal errors (
erros fatais, que fazem com que o programa seja encerrado de forma prematura).
Gata, espero a documentação que me ajude a conquistar seu coração. Show ▼
Em OOP, talvez em especial após a criação de bibliotecas de uso público, a
documentação é peça de extrema importância para a utilização eficaz de código criado por terceiros. É na documentação que estão listadas as classes e suas propriedades, métodos e funções. Documentação de projetos OOP geralmente é gerada de forma automática, através de ferramentas como
javadoc ou
asdoc, mas ainda dependendo de intervenção humana para a descrição do propósito e ação de cada método, classe, função ou propriedade.
Gata, universo = universo.replace(/([\.-,;\s]+s|^s)o(l$|l[\.-,;\s])/im, “você”); Show ▼
Talvez não OOP, esta é uma última cantada baseada em
regular expressions ou expressões regulares (RegExp para os íntimos). Regular expressions é uma sintaxe utilizada para a procura e substituição de texto de forma mais avançada, indo além de simplesmente “substituir x por y”. A expressão descrita na frase visa substituir a palavra “sol” por “você” em qualquer texto, desde que seja uma palavra separada (para evitar a substituição de “sol” no meio de outras palavras, como “solidão”). Já
replace() é a função utilizada em ActionScript para efetuar a substituição de texto através de regular expressions.
A idéia aqui era basicamente querer dizer “meu mundo gira em torno de você”, já que substitui a palavra “sol” por “você” numa variável chamada “universo”. Não cheguei a testar e é capaz de que tenha algum erro na expressão.
Nota final: não garanto a eficácia de nenhuma das cantadas listadas acima. Use por sua própria conta e risco.
E, por favor, não leve a sério.