julho 31, 2010

UML é sua amiga...

Durante muito tempo, principalmente na época de faculdade, olhava para aquele monte de diagramas sem sentido e me perguntava:

- Como isso pode ajudar alguém ou alguma equipe a desenvolver software?

Sim, eu estava falando de UML.

Acredito que muitos profissionais de TI sintam esta mesma antipatia. Isso talvez se deva ao fato de enxergarem a UML, da mesma forma que eu costumava enxergar, como um PROCESSO.

Antes de mais nada é importante esclarecer o seguinte:

"UML não é um processo, UML é uma ferramenta!"


Isso pode parecer básico, mas faz toda a diferença. Vejamos as figuras a seguir:

Visão geral da UML
Visão geral do SCRUM

A primeira figura, nos dá uma visão geral da UML e seus diagramas, a segunda, fornece uma visão geral do SCRUM.

Se retirarmos qualquer elemento do SCRUM, ele deixa de ser SCRUM, se não utilizarmos certos diagramas da UML em nossos projetos de software, a UML continua sendo UML, continua sendo uma ferramenta de apoio, pois, ao contrário do SCRUM, UML não é um processo.

Utilizar a UML como metodologia de desenvolvimento de software é errado, é contraproducente, torna o processo penoso e se associado à um modelo em cascata, torna as coisas muito piores. No final, você se vê afogado em diagramas que não possuem utilidade prática para o seu domínio e o pior, sem código escrito.

Depois que passei a enxergar UML como uma ferramenta de apoio, passei a usufruir dos seus reais benefícios e ela passou a realmente auxiliar em meus projetos. Basicamente, utilizo 3 diagramas:

  • Diagrama de Classes: Este dispensa comentários, é o mainstream dos diagramas da UML, o popstar. Este diagrama é uma foto do seu modelo. Ele contém os objetos e a forma como eles se relacionam.
  • Diagrama de Sequência: Serve como apoio para descrever funcionalidades do seu sistema. Ele descreve a maneira como objetos colaboram entre si, para atingirem um objetivo.
  • Diagrama de Atividades: Este é um diagrama de uso geral, pode ser utilizado para descrever literalmente, qualquer coisa. É um ótimo diagrama para comunicação entre a equipe, descrição de processos complexos, casos de uso e estórias do cliente.

Com exceção do diagrama de classes, não é sempre que faço uso dos outros diagramas, tudo depende da necessidade da situação.

Esta é apenas uma pequena parte da UML, mas que em geral, atende bem às minhas necessidades. Não se obrigue a utilizar tudo o que é oferecido, utilize a UML como uma ferramenta e com certeza você será beneficiado em seus projetos.

Grandes poderes trazem grandes responsabilidades...

Herança é um recurso poderoso oferecido pela orientação a objetos, mas para aproveitar suas vantagens, é preciso ter cuidado e fazer uso consciente dela.

Herança é um relacionamento fortíssimo entre duas classes. Quando você diz que um coisa herda outra em orientação a objetos, você está realmente dizendo que: "uma coisa além de ser uma coisa, também é outra coisa". Ahn?! O Que?! Como assim?! Parece até diálogo do Oráculo com o Neo em Matrix. Calma, um exemplo simples pode desfazer toda a confusão. Se eu digo que:

class Cachorro extends Animal{}

De fato, eu estou dizendo que "Cachorro além de ser um Cachorro, também é um Animal". Na prática, qualquer variável de referência do tipo Animal, pode apontar para um objeto de Cachorro na Heap.

Dizer que Cachorro é um Animal, faz todo sentido, nossa classe Cachorro além de possuir uma interface própria, carrega toda a interface referente à Animal. Herança tem um preço, ela gera acoplamento entre classes, elas se tornam intimamente ligadas, mas neste contexto, é perfeitamente aceitável, pois é natural que Cachorro seja um Animal. Agora pense, se eu disser:

"Cachorro é uma Cafeteira!"

...

Esquisto não?!...mas eu insisto que Cachorro é uma Cafeteira e codifico:

class Cachorro extends Cafeteira{}

Este código vai compilar e rodar perfeitamente. Nós acabamos de criar uma aberração, um cachorro que faz café. Criamos um acoplamento completamente desnecessário e reduzimos significativamente a coesão da classe cachorro. Uma classe coesa é altamente especializada e possui responsabilidades bem definidas, não é o caso do nosso "Cachorro-Cafeteira".

Vamos dizer que eu não esteja satisfeito com o fato de que meu Cachorro só saiba fazer café, e diga o seguinte:

"Cachorro é uma Cafeteira, um Microondas, um Celular e um Grill George Foreman."

Se o cachorro que faz café já é esquisto, isso aí então...

Java só aceita Herança Simples, isto é, uma classe só pode herdar de outra classe e ponto final. Mas se mesmo com Herança simples, podemos criar um cachorro que faz café, imagine o que pode ser feito utilizando Herança múltipla. C++ é um exemplo de linguagem que utiliza este recurso, onde uma classe pode herdar de várias classes. Herança simples, mal utilizada, pode resultar em classes com responsabilidades mal definidas, isso gera um ônus alto para um projeto orientado a objetos, logo, permitir que classes herdem de diversas classes, pode ser fatal em termos de qualidade de software, pois nada impede que se crie um "Frankenstein", apenas o bom senso.

Java oferece o recurso de interfaces. Uma interface é "uma classe 100% abstrata". Uma classe pode implementar diversas interfaces. Por mais que nada impeça que sua classe implemente interfaces totalmente sem sentido, existe uma vantagem nesta abordagem, pois Interfaces, são livres de implementação, isto é, seus métodos são "ocos", é de responsabilidade da classe implementadora prover funcionalidades aos métodos.

Herança é uma ferramenta muito útil, oferecida pelo paradigma orientado a objetos, porém, utilizá-la com coerência, é responsabilidade do desenvolvedor que preza pela boa qualidade do projeto de software. Lembre-se: Grandes poderes trazem grandes responsabilidades!