martes, noviembre 09, 2004

Qué y cuándo vs cómo

Ya es hora de que empecemos a tratar cosas un poco más concretas y, para empezar, quiero hablar sobre algo que no sólo agrega "estilo" a nuestro trabajo, también lo hace mucho más mantenible.

En una empresa, existen personas que saben lo que hay que hacer y cuándo hay que hacerlo, y otras que saben cómo hacerlo.

En nuestro código debería haber métodos que sepan qué y cuándo hacer las cosas y métodos que sepan cómo hacerlas. No me parece una buena práctica construir métodos que mezclan ambos roles.

Mantener esa separación nos permite ver rápidamente las reglas de negocio por un lado y, de ser necesario, revisar los algoritmos en forma individual. Además, estaremos creando métodos que podrán ser reutilizados en otras lugares de nuestro desarrollo.

Para graficar un poco más este concepto, veamos un ejemplo en ASPX. Necesitamos un método que envía un mail a la dirección especificada en un formulario. Tenemos un HTML en disco con la etiqueta "$$nombre$$" que debemos reemplazar por el nombre del usuario para personalizar el mail. Finalmente, grabamos el mail en nuestra base de datos.

El que sigue es un ejemplo de código muy poco profesional:
private void Button1_Click(object sender, System.EventArgs e)
  // Configuraciones
  NameValueCollection config = ConfigurationSettings.AppSettings;

  // Leer el archivo desde disco
  string mailFile = config["MailFileName"];
  FileStream fs = new FileStream(mailFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
  StreamReader sr = new StreamReader(fs, Encoding.Default);
  string message = sr.ReadToEnd();

  // Reemplazar etiqueta
  message = message.Replace("$$nombre$$", campoNombre.Text);

  // Enviar mail
  MailMessage mail= new MailMessage();
  mail.Subject = config["MailSubject"];
  mail.From = config["MailFrom"];
  mail.Body = message;
  mail.BodyFormat = MailFormat.Html;
  mail.To = campoEmail.Text;
  SmtpMail.SmtpServer = config["SmtpServer"];
  SmtpMail.Send( mail );

  //Grabar a SQL
  string connString = config["ConnectionString"];
  SqlConnection oConn = new SqlConnection(connString);
  SqlCommand dbCommand = new SqlCommand();
  dbCommand.CommandText = "Exec Insert_Email @email=@@email";
  dbCommand.Connection = oConn;
  int rowsAffected = 0;
  oConn.Open();
  try
  {
    rowsAffected = dbCommand.ExecuteNonQuery();
  }
  catch (Exception ex)
  {
    throw new Exception(ex.Message);
  }
  finally
  {
    oConn.Close();
  }
}

Algo con mucho más estilo sería:
private void Button1_Click(object sender, System.EventArgs e)
{
  // Nunca debemos escribir más código del necesario
  // en los métodos que capturan eventos !!!
  EnviarMailAUsuario(campoNombre.Text, campoEmail.Text);
}
private void EnviarMailAUsuario(string nombre, string email)
{
  //Este metodo sabe ques y cuandos

  NameValueCollection config = ConfigurationSettings.AppSettings;

  // 1.- Leer archivo de disco
  string emailSource = LeerArchivoDeDisco(config["MailFileName"]);

  // 2.- Reemplazar etiqueta
  emailSource = message.Replace("$$nombre$$", campoNombre.Text);

  // 3.- Enviar mail
  EnviarMailDelSitio(campoEmail.Text, emailSource);

  // 4.- Guardar el mail
  GuardarMail(campoEmail.Text);
}

Los métodos invocados seguramente tendrán un código parecido a las líneas correspondientes del primer ejemplo. Noten que no estoy especificando en que capa de mi aplicación se encuentran estos métodos, pero deberían estar en una capa diferente de la de presentación.

1 comentario:

sixdemons dijo...

Muy bueno!

Una explicación sencilla a uno de los principios fundamentales que hay que seguir en la programación orientada a objetos!

Felicitaciones, muy bueno!