Tell Don't Ask

Tell Don't Ask

·

2 min read

En este momento pasamos a conversar sobre responsabilidades, así que anda por tu brebaje favorito 🍻 y a tu salud!. ¡Espera, ¿no tienes permitido beber?! ¡Haberlo dicho antes! (Tell don't ask)

El parrafo anterior es un ejemplo de cómo no deberían comportarse los objetos en nuestros sistemas. Lo ideal es que el objeto dueño de sus propiedades responda mis preguntas o ejecute acciones que solicito. En el caso introductorio, tú eres conocedor de tu edad y por lo tanto, debieras tener un método que responda mi pregunta: "¿Puedes beber alcohol?". Yo espero un sí o un no considerando tu edad, las leyes del país donde estamos y otras consideraciones adicionales que puedan afectar tu respuesta, y en base a todo eso, brindamos con o sin alcohol.

¿Cómo rompemos el principio? Te hago la misma pregunta: "¿Puedes beber alcohol?", y tu respondes: "No sé, dime tú... tengo 17 años, soy chileno y mi religión es...". Yo debo procesar esa información (la que en realidad no necesito y por la que no pregunté) y responderme. Lo cual, no es lo ideal.

Este principio es aplicable a la programación orientada a objetos, y es parte del conjunto de principios que consolidan Clean Code.

Un poco de código

Supongamos el siguiente objeto de Cuenta bancaria.

public class BankAccount {
    private Person owner;
    private Amount amount;
}

Supongamos que tienes una clase llamada BankAccount que tiene un método llamado transfer para transferir dinero de una cuenta a otra. En lugar de pedir al objeto BankAccount que te proporcione información sobre el saldo de la cuenta y luego decidir si la transferencia es posible o no, deberías decirle al objeto BankAccount que realice la transferencia y que se preocupe de los detalles internos.

Por ejemplo, podrías llamar al método "transferir" de la siguiente manera:

public Transaction transfer(BankAccount destinationBankAccount, Amount transferAmount){...}

...

origin.transfer(destination, amount);

Aquí la clase BankAccount es responsable de verificar si la transferencia es posible (considerando si la cuenta de origen tiene saldo suficiente) y de ejecutarla. El servicio que llama al método origin.transfer() no tiene que preocuparse por los detalles internos de la transferencia. Ahora, el código es más desacoplado y fácil de mantener.