Quando a extensibilidade se torna vilã do paradigma O.O.

O título é bastante provocador, afinal, ao contrário do que ele sugere, o paradigma orientado a objetos propõe justamente oferecer alternativas mais elegantes para a extensão de uma classe.

Li o artigo intitulado Uniform Function Call Syntax (Bright, Walter) e foi uma interessante reflexão sobre as formas que utilizamos para estender as funcionalidades de uma classe já existente. As opções que tipicamente se apresentam:

1. Adicionar a nova funcionalidade diretamente na classe

Essa alternativa só é possível quando o código fonte da classe está disponível para nossa aplicação, o que nem sempre é o caso. Mesmo quando está acessível, nem sempre é conveniente fazê-lo: será que aquela funcionalidade justifica a sobrecarga que impomos à classe, e a provável violação do princípio da responsabilidade única?

2. Herança

Seria a maneira mais adequada, mas esbarra com uma limitação imposta por Java ou outras linguagens de herança simples: como combinar várias extensões? O exemplo do artigo é muito bom. Imagine a classe Integer do Java, e que eu quisesse adicionar a funcionalidade aoQuadrado numa subclasse de Integer. Outro colega necessita do método aoCubo e cria outra subclasse. Sem herança múltipla, como posso utilizar os dois métodos de maneira simples?

Além disso, nem sempre essa é uma opção: há classes que, justamente para evitar a confusão oriunda do descontrole sobre subclasses, colocam-as como ‘final’. Ou seja, estão seladas para herança.

3. Composição e Classe utilitária

As duas são maneiras mais elegantes, no meu ponto de vista, de adicionar a funcionalidade a uma classe existente. Digo isso do ponto de vista do encapsulamento. Sou capaz de adicionar a nova funcionalidade sem afetar a classe alvo. Mas não é chato ter que saber que existe uma classe IntegerUtil, ou, pior ainda, regredir do formato sintático tradicional que se aplica na orientação a objetos para o uso procedural? Não é muito melhor escrever objeto.metodo do que ClasseUtilitaria.fazAlgo(objeto) ?

Foi aí que esbarrei com essa nova modalidade de extensão: os métodos de extensão (Extension Method). Ele não difere do ponto de vista conceitual de uma classe utilitária. O diferencial dele é a forma de uso.

Não seria legal, ao invés de usar:

Integer resultado = IntegerUtil.aoQuadrado( meuInteger );

usar:

Integer resultado = meuInteger.aoQuadrado();

Pois é isso que os métodos de extensão habilitam. O código abaixo seria uma aproximação em C# da classe utilitária:

public static class IntegerUtil {
   public static Integer aoQuadrado(this Integer valor) {
      return valor * valor;
   }
}

O this, no código anterior, faz a mágica. Ainda não consegui relacionar o impacto desse novo recurso com as linguagens dinâmicas, como o Ruby. Alguma opinião?

Referências:

Bright, Walter. Uniform Function Call Syntax. Dr.Dobb’s. 2012.

Extension Method. Wikipedia. 12 October 2012.

Ubuntu com interface convencional

Resolvi escrever esse pequeno artigo apostando que muitos colegas amantes do Linux Ubuntu – como eu – se depararão com o mesmo sentimento de aversão que tive à nova interface Unity, introduzida na versão 12.4 “Precise Pangolin”.

Eu queria atualizar, afinal da Precise Pangolin é uma versão LTS (com suporte estendido da Canonical), mas não gostei da Unity. Não quero aqui tecer críticas a esse esforço, que me pareceu colossal e bastante sofisticado, mas esbarrei com dois problemas ao usá-la: 1. no meu computador, com um processador Celeron, ficou muito lento; 2. não achei a interface prática para uso profissional.

Por consequência, queria voltar ao gnome.

Aqui descrevo o que fiz, registrando o devido crédito ao blog onde originalmente pesquisei e busquei essas informações, com uma pequena modificação de minha parte:

Instalei os seguintes pacotes:

sudo apt-get install gnome-shell gnome-tweak-tool gconf-editor

Baixei o tema Clearlooks-Phenix 2 for GTK 3.4 and newer em http://gnome-look.org

Repare que baixei a versão para gnome GTK 3.4, pois foi a que foi baixada no processo anterior. Ao extrair o pacote, um arquivo README na pasta docs instrui a extrair o pacote, renomear a pasta para Clearlooks-Phenix e colocá-la na pasta /usr/share/themes/ (você precisará fazer isso como root)

Achar o System Tools >> Preferences >> Advanced Settings. Nela, na opção Theme >> Windows e em Theme >> GTK+ Theme mudar para o tema  recém-instalado.

Executei por linha de comando o gconf-editor

Naveguei até a opção /apps/metacity/general. Na propriedade button-layout, alterei para menu:minimize,maximize,close

Pronto! Tudo eu antes gostava.