Diga, não pergunte!

Às vezes ao programar OO nos deparamos com situações das quais nos sentimos tentados sempre em colocar um valor em um atributo de modo mais rápido. Talvez o prazo para entrega do projeto esteja curto, ou então a alteração em questão é grande e não nos preocupanos com pequenos detalhes… Com isso é mais fácil deixar ser levado pelas circunstâncias do que analisar o que estamos fazendo.

Suponhamos que nós temos uma classe Porta e queremos saber se a ela está aberta ou não, e queremos mais, queremos mudar o estado dela de aberta para fechado e vice-versa. Um modo bem simples seria criar a classe e nela colocarmos um atributo booleano:

 public class Door {
     private boolean doorIsOpen = false;
}

Até aí tudo tranquilo, mas agora começa o perigo. Como iremos fazer com que essa variável tenha seu valor alterado? Devemos optar que essa alteração fosse realizada pela classe Porta? Ou pelo objeto que está chamando o objeto Porta? A solução mais comum que vemos por aí é fazer um get/set muito encontrado em códigos legados:

public void setDoorIsOpen(boolean doorIsOpen) {  
	this.doorIsOpen = doorIsOpen;  
}

public boolean getDoorIsOpen() {  
	return doorIsOpen;  
}  
// To close the Door  
if (door.getDoorIsOpen() == true)  
	door.setDoorIsOpen(false);  

// To open the Door
if (door.getDoorIsOpen() == false)  
	porta.setDoorIsOpen(true);

Pense comigo, e se, essa condição de pergunta (if + get) e o método set estivesse em 30 pontos do sistema e o cliente pedir uma nova regra de negócio. Imaginemos que, para ser fechada, a Porta tem que estar com o alarme ligado:

  public class Door {  
       private boolean doorIsOpen = false;  
       private boolean alarmIsActive = true;  
       public boolean getAlarmIsActive() {  
            return alarmIsActive;  
       }  
  }
  // To close the Door  
  if (door.doorIsOpen() && door.getAlarmIsActive ())  
       door.setDoorIsOpen(false);

Utilizando esse tipo de código, seria necessário ter que alterar todo os método do projeto que utilizassem esse código. Imagine todo o trabalho que teríamos para realizar essa alteração por todo o código…

Para não ter todo esse trabalho, basta dizer ao objeto Porta o que fazer, e não perguntar o estado do seu atributo para depois alterá-lo.

Utilizando esse conceito, alteração do código aconteceria apenas em um ponto e os outros 30 pontos do sistema continuariam intactos. O código inicial, antes da alteração solicitada pelo cliente (alarme ligado), ficaria assim:

  public class Door {  
      private boolean doorIsOpen = false;  
      private boolean alarmIsActive = true;  
      public boolean getAlarmIsActive() {  
           return alarmIsActive;  
      }  
      public boolean isOpen() {  
           return doorIsOpen;  
      }  
       public void closeDoor(){  
          doorIsOpen = false;  
       }  
       public void openDoor(){  
            doorIsOpen = true;  
       }  
  }

E o código para fechar/abrir a Porta seria bem mais simples:

  // Closes the Door
  if (door.isOpen())  
       door.closeDoor();  
  // Opens the Door
  if (!door.isOpen())  
       door.openDoor();

Após essa alteração, para aplicarmos o código novo (verificando o alarme), basta apenas colocar a condição do alarme dentro do método de fechar a Porta, e pronto, alteramos uma linha em uma classe todo o resto do sistema fica intocável:

  public void closeDoor(){  
       if (alarmIsActive)  
            doorIsClose = false;
  }

Agora, toda vez que a regra de negócio mudar (ex.: fechar a Porta), basta apenas alterar um método dentro da classe específica que o restante do projeto continuará intacto.

Utilizando esse princípio, diminuímos o acoplamento entre as classes e seu código está apto a ser utilizado em todas as partes do sistema.

Fica a dica.

Inspirado por: “The pragmatic Bookshelf – Alec Sharp”

Edit: Código final, dica do H.Fernandes. [=

8 thoughts on “Diga, não pergunte!

    • Olá Gustavo, boa tarde.

      Eu pretendo continuar uma série de posts, por enquanto estou focando mais na área técnica.

      Muito obrigado pelo apoio e pela dica. [=

  1. Muito bacana seu post cara…

    Parabéns, este principio é bastente interessante tambem para se respeitar a intimidade das classes e efetuar um baixo acomplamento e um bom encapsulmento…

  2. Viciei no seu blog!! Muito bom!
    Sou estudante de Sistemas de Informação na Unirio e vejo aqui abordagens que não tenho em aulas.

Leave a Comment