Independência ou sorte!

Desenvolvimento Abr 27, 2018

Podemos chamar de Desenvolvimento Orientado a Sorte o ato de escrever o código sem se preocupar com a dependência entre suas classes e objetos, pois nessa situação o sucesso do seu projeto depende de:

  1. Não haver necessidade de alterações no seu código (o que é difícil de acontecer);

  2. As classes do seu código possuírem pouca dependência, sem que você tenha consciência disso.

Ou seja, pura sorte.

Por que a dependência entre as classes e objetos é tão prejudicial?

Quando você não se preocupa com a dependência no seu código e surge a necessidade de alterar uma ou mais classes, você pode:

  1. Inserir um bug ou um mal funcionamento ao código de produção, pois você não alterou todas as classes dependentes da classe modificada;

  2. Levar horas para realizar uma modificação que deveria ser feita em minutos, pois são muitas classes dependentes.

Como saber se há dependência no seu código?

Sempre que a alteração de uma classe te obrigar a alterar outras, há dependência no seu código.

Mas você pode (e deve) identificar as dependências enquanto desenha ou escreve o seu código.

E como fazer isso?

Existem quatro tipos de dependências que você deve evitar:

  1. Dependência em relação ao nome de outra classe;

  2. Dependência em relação ao nome da mensagem enviada a outra classe;

  3. Dependência em relação aos argumentos que a mensagem necessita;

  4. Dependência em relação a ordem dos argumentos que a mensagem necessita.

Vamos a um exemplo prático

Imagine o seguinte contexto: você está desenvolvendo um sistema de gestão para uma biblioteca. Por ora, o sistema possui apenas dois requisitos:

  1. Deve ser possível adicionar livros em uma determinada posição;

  2. Deve ser possível recuperar a posição de um determinado livro.

Então, você escreveu o código para atender aos dois requisitos e como resultado seu sistema possui duas classes Library e Book:

worst_solution-1

Você consegue identificar as dependências no código?

Apesar de não parecer, esse código inocente contém os tipos de dependências que listei acima. Vejamos onde estão:

1. Dependência em relação ao nome de outra classe

Em nosso código, o método add_book da classe Library é dependente do nome da classe Book.

add_book

Esse tipo de dependência apresenta os seguintes problemas:

  • Se o nome da classe Book for alterado o método add_book também deverá ser alterado;
  • A classe Library está limitada a trabalhar apenas com Book. Se em algum momento a classe Library quiser trabalhar com Article ou Magazine não será possível.

2. Dependência em relação ao nome da mensagem enviada a outra classe

Os métodos públicos add_book e book_position são dependentes da mensagem identification enviada aos objetos da classe Book.

add_book_book_position

Esse tipo de dependência apresenta o seguinte problema:

  • Se o nome da mensagem for modificada, ambos métodos públicos da classe Library também terão de ser modificados.

3. Dependência em relação aos argumentos que a mensagem necessita
4. Dependência em relação a ordem dos argumentos que a mensagem necessita

O método add_book da classe Library é dependente dos argumentos necessários para instanciar os objetos da classe Book. Então, se novos argumentos forem adicionados ou a ordem for alterada, o método add_book também deverá ser modificado.

add_book-1

Além disso, o próprio método add_book possui dependência em relação aos seus parâmetros. Se novos forem adicionados ou a ordem for alterada, todos os objetos e classes que enviam a mensagem add_book aos objetos da classe Library terão que ser alterados.

add_book-2

Como você pôde perceber, em apenas duas classes é possível ter muita dependência. Agora, imagine um contexto com mais de 200 classes.

É possível escrever esse mesmo código evitando essas dependências?

A resposta: sim, é possível!

Existem três técnicas que são excelentes para diminuir a dependência entre suas classes e objetos:

Após aplicar as três técnicas, o código para nosso sistema de gestão da biblioteca ficou assim:

better_solution-2

Após aplicar a técnica Dependency Injection, a classe Library não depende mais da classe concreta Book, nem dos argumentos necessários para sua criação. A dependência da classe Library, agora é com um conceito abstrato capaz de responder ao método identification.

add_item-4

Além disso, a nova classe Library é capaz de gerenciar outros itens, como por exemplo artigos (Article). O único detalhe é que os novos itens devem responder a mensagem identification.

article_class
using-3

Ao aplicar a técnica Isolate Vulnerable External Messages, a classe Library isolou a dependência em relação ao método externo identification em um método privado de seu controle, chamado item_identification(item).

item_position

Agora, se alterarmos o nome do método identification para id, por exemplo, o impacto será apenas nesse novo método, protegendo os métodos públicos.

item_identification-1

Ao aplicar a técnica Remove Argument-Order Dependencies, o método add_item (que substituiu o antigo add_book) da classe Library necessita apenas de um parâmetro, a hash args. Com isso, você pode adicionar um novo parâmetro em qualquer posição sem que haja a necessidade de alteração de todos os objetos e classes que enviam a mensagem add_item.

add_item-5

Além disso, a nova solução provê mais um benefício: as chaves da hash explicitam a intenção de cada parâmetro.

adding_book

Concluindo, um código com menos dependência entre as classes e objetos é mais fácil de ser mantido, principalmente se o código for um viajante do tempo, como descrito nesse artigo.

Paulo Urgal

Cientista da computação, curioso, dedicado e apaixonado pelo que faço.

LinkedIn icon Instagram icon Facebook icon Twitter icon
Great! You've successfully subscribed.
Great! Next, complete checkout for full access.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.
manage cookies