Arquivo da categoria: Engenharia de Software

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.

Recomendação de “Eclipse and Java for Total Beginners”

Pesquisando material de aula sobre Programação Orientada a Objetos em Java, tive a grata surpresa em encontrar essa série de vídeo-aulas, hospedadas no site SourceForge, portanto disponível para qualquer um que queira assistir.

Digo que tive a grata surpresa pois, ao contrário de muito material de má qualidade que tipicamente encontro, esse material possui uma qualidade fantástica; tanto em qualidade da produção, quanto na do conteúdo exibido propriamente. Gostei tanto que assisti a todas as vídeoaulas e, mesmo trabalhando há mais de 6 anos com Eclipse como IDE, descobri funcionalides surpreendentes desta excelente ferramenta. O conteúdo abordado em Java é moderno e muito bem apresentado.

Por fim, o material é tão bom que recomendo mesmo para quem tem apenas uma compreensão básica de Inglês.

Segue o link: http://eclipsetutorial.sourceforge.net/totalbeginner.html

DART: por que mais uma plataforma?

Li um interessante artigo sobre a linguagem DART e vou compartilhar minhas impressões com vocês. A primeira coisa curiosa sobre o artigo é ele ser classificado como Green Paper. Eu nunca tinha ouvido falar nesse termo; já eram de meu conhecimento os white papers. Aparentemente um “green paper” vem a ser um artigo em forma de proposta; algo para discussão; nada definitivo.

Voltando para o assunto principal, que é essa nova plataforma DART, achei interessante os argumentos que fizeram a Google se dispor a desenvolver essa nova plataforma. Abaixo enumero alguns dos pontos que achei importante.

Por que se chama plataforma?

Porque ela é composta de uma máquina virtual, de uma linguagem de programação e ferramentas para o desenvolvimento.

Para que mais uma linguagem?

Sem dúvida essa é a pergunta fundamental. A motivação da Google baseia-se na percepção da tendência de “engorda” do lado cliente em aplicações WEB. As chamadas aplicações de uma única página (Single Page Application) estão crescendo em importância, principalmente para tirar proveito da grande capacidade de processamento ocioso que a camada cliente (os navegadores) dispõe. Até os navegadores dos celulares atuais dispõe de grande processamento.

Nesse tipo de aplicação de página única, o código de execução de uma aplicação – ou pelo menos toda a parte de um caso de uso específico – é carregado para o lado cliente. As necessidades de dados armazenados no servidor são supridas com invocações assíncronas pela já consagrada tecnologia AJAX. Recursos como banco de dados já estão disponíveis nas versões novas dos navegadores que suportam HTML5 e facilitam uma série de tarefas que antes exigiam a conexão ativa com o servidor. Até mesmo aplicações offline são possíveis nesse ambiente.

Mas por que não JavaScript?

Minha primeira reação ao ler os propósitos de DART foi: “mas já temos JavaScript”. Muitos, imagino, vão pensar inicialmente da mesma maneira. Entretanto, recursos do JavaScript que o torna extremamente flexível e poderoso, quando levados para desenvolvimento em larga escala, acabam expondo fraquezas. A não tipagem e a execução dinâmica de código tornam o código JavaScript difícil para ambientes de trabalho em equipe. Esses recursos tornam inviáveis certos feedbacks que as IDEs contemporâneas e ferramentas de integração contínua oferecem para desenvolvimentos descentralizados. Uma pequena falha de um desenvolvedor pode compromenter a aplicação e tal falha só ser percebida no momento da utilização.

Bem, é isso. Quem quiser, recomendo a leitura desse artigo, escrito por Chris Buckett.

Green Paper do DART

Uma revisita sobre a linguagem XML

Há uma década a linguagem XML apontava como uma revolução na forma de representar dados. Após mais de 10 anos, o que podemos observar?

Bem, de fato o XML tornou-se pervasivo nos sistemas de computação. Alguns usos mais comuns são em: (1) arquivos de configuração – p.ex. em frameworks como struts, spring e hibernate -, (2) definição de sistemas – JasperReports – ; e (3) transporte de dados – principalmente pela popularização dos WebServices. Mas também, relembrando aquele tempo, houve muito exagero: alguns afirmavam com alto grau de certeza que, a esta altura, as linguagens de programação estariam abolidas e programaríamos exclusivamente em XML; Java, .NET, VB, etc. seriam meras plataformas para as quais códigos definidos em metaprogramação XML seriam transformados.

Um dos melhores artigos do assunto, que tive a oportunidade de reler, é o “XML: We Ain’t Seen Nothin’ Yet”, de A. Russell Jones. Acesse o link aqui.

Projetos de tudo-fixo são mais arriscados

Essa é a reflexão que nos traz o excelente artigo do Scott Ambler, na Dr´.Dobbs. Ele levanta a intrigante e controversa afirmação de que projetos de tudo-fixo (em uma tradução forçada por minha parte) são mais arriscados do que projetos que usam práticas que permitem ajustar, de forma dinâmica, uma ou mais das três clássicas variáveis de projetos: escopo, custo e prazo.  É uma fundamentação para defesa de práticas ágeis. Recomendo a leitura:

http://drdobbs.com/architecture-and-design/231600756#

Tamanho importa?

Muito diferente do que a pergunta do título possa sugerir, o tema que abordo trata de Engenharia de Software. Muito se lê em livros que tratam de refatoração (como o do Fowler et al) e de boas práticas de código (como o do Robert Martin) sobre como identificar códigos OO mal redigidos. Fala-se sobre vários princípios, como o Aberto/Fechado, o de substituição de Liskov, o de Responsabilidade Única, etc; o livro do Fowler dá até dicas sobre como identificar tais problemas no código OO: os maus cheiros de código.

Não obstante, tais percepções não são tão óbvias para o desenvolvedor neófito. Descobrir que uma classe viola o princípio de substituição de Liskov, por exemplo, não é uma tarefa fácil; exige muito conhecimento e reflexão sobre o código.

Andrew Binstock, editor da Dr.Dobbs, cita uma excelente dica em seu artigo publicado na edição desse mês (In Praise of Small Classes). Ele fala de uma parâmetro bastante tangível para identificarmos um código mal projetado: o tamanho de uma classe. Segundo Binstock, tal parâmetro é colocado por Jeff Bay no livro “The ThoughtWorks anthology”, e estabelece o valor de até 60 linhas de código. Acima disso teríamos um indício de que a classe precisa perder responsabilidades através de refatoração.

O pequeno artigo transcorre sobre os conhecidos efeitos colaterais de código OO mal projetado sobre os testes. Vale a pena a leitura!

Clique aqui.

Propriedade versus Atributo

Frequentemente escuto alunos e colegas de profissão usar como sinôminos esses dois termos relacionados à UML. Mas existe diferença entre propriedade e atributo?

Segundo [Fowler, 2005], propriedade é uma “característica estrutural de uma classe”. Mas o que exatamente é uma característica estrutural, visto que uma classe é uma representação estática de parte de um sistema? Não seria tudo que é representado nela uma característica estrutural? Bem, o que Fowler tenta diferenciar são dois tipos de características que uma classe possui: propriedades e operações. As propriedades de uma classe são elementos que determinam o que uma classe é – por isso são ditas características estruturais – enquanto as operações deteminam o que uma classe pode fazer – portanto são características comportamentais.

Colocando de maneira mais objetiva, a propriedade refere-se a qualquer atributo ou associação que uma classe possui. Embora os conceitos de atributo e associação sejam semelhantes, elem implicam níveis de abstração diferentes de uma característica estrutural. Mas, de uma forma geral, podemos usar tanto atributo quanto uma associação para representar o mesmo conceito. A decisão sobre qual usar cabe ao engenheiro de software, dependendo no nível de destaque que ele deseja dar ao tipo que a propriedade possui.

Atributo

De forma grosseira, podemos entender o atributo como um campo de uma classe: um elemento de informação básico que identifica uma característica fortemente relacionada com aquela classe que o contém. Por exemplo, numa classe Cliente, seria comum representar a propriedade nome como um atributo, não como uma associação (embora nada impeça essa última forma), como na figura 1.

Figura 1 – Classe Cliente com propriedade representada como atributo

Associação

Da mesma forma que o atributo, uma associação representa uma propriedade de uma classe, só que representada por meio gráfico – uma linha ligando as classes – combinada com notações textuais (multiplicidades e nome do atributo de associação). A diferença fundamental da representação por meio de associação reside no destaque que é dado ao tipo de dado (classe) ao qual o elemento de informação está relacionado. Esse destaque procura dar ao leitor do modelo melhor compreensão sobre um elemento de informação que, provavelmente, é compreendido dentro do contexto de domínio da aplicação, mas não necessariamente fora dele. Por exemplo, se na classe Cliente eu desejo representar a propriedade que ele pode ter um Cartão, provavelmente representarei esse conceito por meio de associação, uma vez que o conceito Cartão depende muito do contexto onde ele se aplica (cartão de crédito, num sistema bancário; um cartão de visitas, num sistema de contatos, etc.). Ou seja, é importante destacar o tipo da classe à qual a propriedade pertence, até mesmo porque a classe Cartão, por sua vez, pode necessitar representar outras propriedades não óbvias para o leitor: número do cartão, tipo de bandeira (visa, mastercard, etc.), tipo de pagamento (à crédito ou à vista), etc. Veja a figura 2.

Figura 2 – Propriedade cartão representada como associação

Por outro lado, no caso do atributo nome da classe Cliente, qual seria a relevância de explicitar que tal propriedade é do tipo String? Ou ainda, não seria simplificar demais nosso modelo, incorrendo em imprecisão, representar a propriedade cartão como um atributo? Veja o mesmo modelo da figura 2, invertendo as representações, na figura 3. Qual deles é mais elucidativo?

Figura 3 – Propriedades representadas de forma invertidada

Conclusão

Uma propriedade pode ser representada tanto como atributo quanto como associação. A escolha por representar de uma ou outra forma depende do destaque que o engenheiro deseja dar ao tipo da propriedade. Se ele for dependente do domínio de aplicação sendo desenvolvido, é sempre conveniente representá-lo como associação. As demais propriedades, cujo tipo são de uso geral (String, int, Date,etc.), são melhor representadas como atributos.

Referências

[Fowler, 2005] Fowler, F. UML Essencial. 3ª edição. 2005. Editora Bookman.

Artigo de Projeto de Software O.O. para neófitos

Recebi a indicação de um colega de trabalho sobre esse artigo que trata de projeto de software orientado a objeto. Mas o quê torna este especial comparado aos milhares que existem na WEB: a forma didática como o tema é tratado. Com o título (em tradução livre) ‘Como ensinei Projeto de Soft. OO para minha esposa’, que em princípio pareceu-me jocoso tal qual na série ‘XXX for dummies’, surpreendeu-me com a forma aprazível de introdução para um tema complexo, que permite despertar o interesse dos neófitos para uma leitura mais aprofundada dos princípios elementares de projeto de software O.O., conhecidos popularmente como SOLID (cunhado por Uncle Bob).

Uma citação feita do artigo chamou-me a atenção (novamente em tradução livre):

“Desenvolver software a partir dos requisitos e andar sobre água é fácil desde que ambos estejam congelados.”, do autor (Edward V. Berard )

Segue o link abaixo. Vale a leitura!

How I explained OOD to my wife

O importante é o foco

Meu pai me mandou essa piadinha por e-mail. Impressionante é o quanto ela se aplica à engenharia de software.

O IMPORTANTE É O FOCO…

Um paciente vai num consultório e diz ao psiquiatra:
– Toda vez que estou na cama, acho que tem alguém embaixo. Aí eu vou embaixo da cama e acho que tem alguém em cima. Pra baixo, pra cima, pra baixo, pra cima. Estou ficando maluco!
– Deixe-me tratar de você durante dois anos. – diz o psiquiatra.
– Venha três vezes por semana, e eu curo este problema.
– E quanto o senhor cobra? – pergunta o paciente.
– R$ 120,00 por sessão – responde o psiquiatra.
– Bem, eu vou pensar – conclui o sujeito.
Passados seis meses, eles se encontram na rua.
– Por que você não me procurou mais? – pergunta o psiquiatra.
– A 120 paus a consulta, três vezes por semana, dois anos =R$ 37.440,00, ia ficar caro demais, ai um sujeito num bar me curou por 10 reais.
– Ah é? Como? – pergunta o psiquiatra.
O sujeito responde:
– Por R$ 10,00 ele cortou os pés da cama…
Muitas vezes o problema é sério, mas a solução pode ser muito simples…
HÁ GRANDE DIFERENÇA ENTRE FOCO NO PROBLEMA E FOCO NA SOLUÇÃO…
Foque uma solução ao invés de ficar pensando no problema.