Saturday, May 19, 2007 8:24 PM

Em inglês: Tell, don’t Ask. Isto significa que você deve pedir para o objeto executar o que você precisa e não perguntar seu estado e decidir como ele deve se comportar. A lógica de como se comportar dado seu estado e deve estar encapsulada no próprio objeto.

Veja o exemplo abaixo:

    public decimal CalculateSalesTax(Order order)
    {
        decimal taxValue;
        switch (order.DeliveryAddress.StateId)
        {
            case State.ES:
                taxValue = 0.10M;
                break;

            case State.MG:
                taxValue = 0.12M;
                break;

            case State.RJ:
                taxValue = 0.15M;
                break;

            case State.SP:
                taxValue = 0.11M;
                break;
            default :
                return 0;
        }

        return order.Total * taxValue;
    }

Isto é justamente o que queremos evitar. O método pergunta uma certa condição para o objeto e a partir desta define o que será feito. Não há dúvidas de que todo este processo deveria estar encapsulado na classe Order, já que ela tem todas as informações necessárias para resolver o problema. A solução ficaria assim:

Um método na classe Order que encapsula toda lógica:

    public class Order
        {
        public decimal SalesTax()
            {
                decimal taxValue;

                switch (DeliveryAddress.StateId)
                {
                    case State.ES:
                        taxValue = 0.10M;
                        break;

                    case State.MG:
                        taxValue = 0.12M;
                        break;

                    case State.RJ:
                        taxValue = 0.15M;
                        break;

                    case State.SP:
                        taxValue = 0.11M;
                        break;

                    default:
                        return 0;
                }

                return Total * taxValue;
        }
    }

O método original simplesmente chama no novo método:

    public decimal CalculateSalesTax(Order order)
    {
        return order.SalesTax();
    }

Uma das formas de facilitar a aplicação deste conceito é separar os métodos entre comandos e perguntas, como sugerem Andy Hunt e Dave Thomas do The Pragmatic Programmers.

A idéia é separar métodos entre comandos e perguntas. Um comando altera o estado do objeto, enquanto que uma pergunta se limita a responder o estado do objeto, sem alterá-lo. Desta forma temos claramente a noção de quando estamos telling, chamando um comando, e quando estamos asking, chamando uma pergunta.

Comments

No comments posted yet.
Post Comment
Title *
Name *
Email (never displayed)
Website
Comment * (Allowed tags: blockquote, a, strong, em, p, u, strike, super, sub, code)  
Please add 1 and 7 and type the answer here: