O princípio Tell, Don’t Ask

Este princípio da orientação a objetos diz respeito sobre um objeto dizer o que faz ao invés de perguntar.

Para entender melhor, vou dar um exemplo com duas classes.

A classe Square que representa um quadrado.

namespace TellDontAsk
{
	public class Square
	{
		public int Height { get; private set; }
		public int Width { get; private set; }

		public Square(int height, int width)
		{
			Height = height;
			Width = width;
		}
	}
}

E a classe Paint que tem a função de desenhar um quadrado.

namespace TellDontAsk
{
	public class Paint
	{
		public Paint()
		{
		}

		public Square DrawASquare(int height, int width)
		{
			var square = new Square(height, width);

			if (square.Height != square.Width)
				throw new Exception("A square needs height equals width");

			return square;
		}
	}
}

Se tentarmos desenhar um quadrado com altura diferente da largura a classe vai dar erro e informar que um quadrado precisa ter a altura igual a largura.

Mas, qual o problema dessa classe de acordo com o princípio “Tell, Don’t Ask”?

Devemos dizer ao objeto o que queremos que ela faça, e não perguntar sobre ele mesmo, fazer uma decisão, e então dizer para ele o que fazer.

Para corrigir isso, podemos encapsular esse código dentro da própria classe Square, deixando essa regra no seu devido lugar.

A classe Square vai ficar da seguinte maneira:

namespace TellDontAsk
{
	public class Square
	{
		public int Height { get; private set; }
		public int Width { get; private set; }

		public Square(int height, int width)
		{
			Height = height;
			Width = width;

			Validate();
		}

		public void Validate()
		{
			if (Height != Width)
				throw new Exception("A square needs height equals width");
		}
	}
}

Já a classe Paint vai se abstrair de tomar a decisão de se o objeto Square é válido ou não.

namespace TellDontAsk
{
	public class Paint
	{
		public Paint()
		{
		}

		public Square DrawASquare(int height, int width)
		{
			return new Square(height, width);
		}
	}
}

Não aplicar esse princípio no código pode acarretar na existência de determinadas regras em lugares incorretos.

Se esse fosse um sistema mais complexo, a alteração de uma simples regra poderia ocasionar o aparecimento de vários defeitos pelo código. Uma vez que a regra não estaria no lugar correto e seria necessário buscá-la em todo o código.

O encapsulamento no lugar correto é a solução para garantir o comportamento esperado do objeto.

O código completo do projeto está no GitHub, basta clicar aqui para vê-lo.

Se quiserem conhecer mais sobre mim, basta ir aqui no blog no menu quem sou e conferir também o meu LinkedIn.

Se ficou alguma dúvida, comenta aqui no blog que eu tento ajudar. 🙂