Idea clave: Cada función debe realizar únicamente una tarea.
Las funciones deben ser cortas para evitar bugs, facilitar la comprensión, el mantenimiento, etc.
Deben extraerse subtareas en funciones separadas, siempre dejando el código lo más legible posible. Para ello, cada función debe tener únicamente un nivel de abstracción.
Las funciones con bloques largos de declaraciones If, else, while, for, case o demasiado anidados, generalmente tienen varias subtareas que podrían dividirse en funciones diferentes Las declaraciones If/Else,
While, Case, etc deben tener pocas líneas, por lo general, solo las llamadas a las funciones que realizan cada tarea específica.
Ejemplo:
#INCLUDE "TOTVS.CH"
Function EnvEmail()
Local cSMTP := ''
Local cConta := ''
Local cPass := ''
Local cDestinatario := ''
Local cAssunto := "Asunto"
Local cHtml := ''
Local lRet := .F.
U_CfgMailIni(@cSMTP, @cConta, @cDestinatario) // Búsqueda de configuraciones del ini
cHtml := U_MontaHTML() // Elabora cuerpo del e-mail
lRet := U_EnviaEmail(cSMTP, cConta, cPass, cDestinatario, cAssunto, cHtml) // Envía e-mail
Return lRet
En este ejemplo, la función realiza únicamente las llamadas necesarias para que se ejecute el procedimiento del cual se hace cargo. La forma y los detalles necesarios para que el proceso macro se ejecute está subdividido en otras funciones. Cada una solamente con una tarea en su nivel de abstracción.
Una función se quedará encargada únicamente de buscar las configuraciones del archivo ini:
#INCLUDE "TOTVS.CH"
Function CfgMailIni(cSmtp, cConta, cDestinatario)
Local cSecao := 'EMAIL'
Local cPath := "C:\EmailCFG.ini"
// Leer configuraciones de archivo .ini
cSmtp := GetPvProfString(cSecao, "SMTP", '', cPath)
cConta := GetPvProfString(cSecao, "CUENTA", '', cPath)
cDestinatario := GetPvProfString(cSecao, "DESTINATARIO", '', cPath)
Return
Otra función simplemente elaborará el cuerpo del e-mail:
#INCLUDE "TOTVS.CH"
Function MontaHtml()
Local cHtml :=''
cHtml += '<html>'
cHtml += '<head>'
cHtml += '<META http-equiv="Content-Type" content="text/html;charset=ISO-8859-1">'
cHtml += '<style type="text/css">'
cHtml += '#Cab{font-family:Verdana;}'
cHtml += '</style>'
cHtml += '<title>Email de pruebas</title>'
cHtml += '</head>'
cHtml += '<body>'
cHtml += '<h3 id="Cab">Cuerpo del e-mail</h3>'
cHtml += '</body>'
cHtml += '</html>'
Return cHtml
Y una última simplemente recibirá todo y enviará el e-mail definitivamente:
#INCLUDE "TOTVS.CH"
Function EnviaEmail(cSMTP, cConta, cPass, cDestinatario, cAssunto, cMensagem)
Local lConSMTP := .F.
Local lEnvEmail := .F.
Local cError := ''
Connect SMTP Server cSMTP Account cConta Password cPass Result lConSMTP
// Si la conexión con el SMPT funcionó
If lConSMTP
Send Mail From cConta;
To cDestinatario;
Subject cAssunto;
Body cMensagem;
Result lEnvEmail
If !lEnvEmail // Error en el envío del e-mail
Get Mail Error cError
ConOut("Error en el envío del e-mail. " + cError)
EndIf
Disconnect SMTP Server
Else // Error en la conexión con el SMTP Server
Get Mail Error cError
ConOut("Error en la conexión SMTP. " + cError)
EndIf
Return lEnvEmail