martes, 20 de febrero de 2007

Capa Lógica de Negocios

Aquí les comparto este articulo que les comparti a los amigos de MSCoder.
Introducción

Hoy en día todos los desarrolladores comprendimos que es necesaria una capa intermedia entre nuestra aplicación y el proveedor de los datos, conocida como "Capa de Acceso a los Datos", pero muy pocos han comprendido las implicaciones de continuar desarrollando aplicaciones que contengan "súper botones" que en la capa de presentación tiene toda la lógica del negocio. El problema de este enfoque es que estaremos desarrollando aplicaciones para el día, día sin una planificación que nos permita construir una infraestructura de software que nos permita disponer de servicios que puedan ser reutilizados y extendidos por las aplicaciones existentes o nuevas. Otro problema de no desarrollar aplicaciones con arquitectura de n-capas es que se abre una brecha o GAP de seguridad cada vez que necesitamos reescribir el código para otra plataforma sin garantizar que la "misma" aplicación se comporte igual sin importar la plataforma o dispositivo en que se desarrolla la nueva capa de presentación de nuestra aplicación.

Este articulo ha sido escrito asumiendo que ya se ha tenido alguna experiencia desarrollando aplicaciones con C# , ya que no explica el uso del lenguaje sino la aplicación de la arquitectura n-capas en aplicaciones desarrollados en la plataforma .NET Framework 2.0.

Definición

El tener una arquitectura n-capas bien definida reducirá los hoyos de vulnerabilidad que evidentemente se dan cuando no desarrollamos con esta arquitectura. Dentro de esta arquitectura la capa intermedia o la capa lógica de negocios ocupa un lugar angular en la construcción de una infraestructura de software que nos permitirá el crecimiento y la extensibilidad de servicios para todas las aplicaciones existentes y futuras.

La definición de los linderos de cada capa nos permitirá definir correctamente la colaboración que proveerá cada una de ellas y descubriremos que la capa intermedia es inevitablemente la lógica de negocios, esto hará una infraestructura robusta y lista para la extensibilidad y el crecimiento como proveedora de servicios. Veámoslo más a detalle:

La capa de acceso a los datos su propósito primario es separar al proveedor de datos del resto de la aplicación. Hoy en día gracias a la tecnología que nos provee el .NET Framework esta capa puede ser reutilizada para diversos proveedores sin hacer cambios significativos o prácticamente sin ningún cambio. Pero esta capa no debe de guardar ningún grado de complejidad mas que el ejecutar las operaciones fundamentales del proveedor de datos operaciones conocidas por sus siglas en inglés CRUD (Creación, Lectura, Actualización y Eliminación). Las Métodos de esta capa debe de realizar operaciones mono transaccionales, o atómicas. Ya que la capa superior, la intermedia se encargará de manejar las transacciones gracias a la disponibilidad del System.Transactions del .NET Framework 2.0 de la clase TransactionScope. He aquí la colaboración entre las capas, la capa de acceso a datos se convierte en una capa un sencilla gracias a que la capa intermedia se encargará de las transacciones y esto gracias a la tecnología disponible que tenemos en el .NET Framework 2.0.

A continuación mostraré un segmento de código que muestre lo expuesto.

public static class ConceptoTransaccionBLL

{

private const decimal FactorCalculoImpuesto = 0.10141728;

public const string CrearExplicacion = "Proceso bla, bla bla";

public static int? Crear(ConceptoTransaccion parametro)

{

int? Resultado = null;

if (ValidarCrear(parametro)

{

using (TransactionScope ts = new TransactionScope())

{

Resultado = ConceptoTransaccionDAL.Crear(parametro);

parametro.Nombre = "Prueba de Transaccion";

parametro.ValorImpuesto = parametro.Valor * FactorCalculoImpuesto;

OtraTransaccionDAL.Actualizar(parametro);

ts.Complete();

}

}

return Resultado;

}

}

Este segmento de código típico de la capa intermedia o de negocios nos muestra lo siguiente:

El flujo del proceso del negocio:

Como el ejemplo anterior que define que luego de crear El Concepto de la Transacción, Actualizará Otra Transacción.

Resultado = ConceptoTransaccionDAL.Crear(parametro);

…

OtraTransaccionDAL.Actualizar(parametro);

Las reglas del negocio:

En nuestro segmento de código en medio del proceso realizamos el calculo de un impuesto X.

private const decimal FactorCalculoImpuesto = 0.10141728;

….

parametro.ValorImpuesto = parametro.Valor * FactorCalculoImpuesto;

Para facilitar el ejemplo se declaró como una constante este factor pero bien pudo estar almacenada esta información en el proveedor de datos u en otro medio.

Validaciones de los datos:

Esta capa debe de garantizar que los datos requeridos para procesarla fueron debidamente validados en el ejemplo anterior encapsulamos estas validaciones en el método validar, y solo si es exitosa la validación puede iniciar el flujo del proceso del negocio.

if (ValidarCrear(parametro){{…}}

Textos de explicación de los procesos del negocio:

Estos textos aunque pertenecen a esta capa pueden ser útiles en la capa de presentación para informar al usuario de que se trata el proceso que ha seleccionado ejecutar.

public const string CrearExplicacion = "Proceso bla, bla bla";

Manejo de transacciones:

En esta capa utilizamos la librería de .NET Framework 2.0, System.Transactions para manejar las transacciones que se adaptan muy bien si en la capa de acceso a los datos estoy utilizando Las librerías de Práticas y Patrones " Microsoft Enterprise Library 2.0 de enero del 2006" que utiliza las mejores prácticas de acceso a los datos de la tecnología ADO.NET 2.0. La clase TransactionScope hace todo el trabajo por nosotros. Además podemos definir Opciones para variar el comportamiento del alcance de las transacciones, lo cual por simplificación no expondremos aquí pero lo invito a que investigue en la Red.

using (TransactionScope ts = new TransactionScope())

{

…

ts.Complete();

}

Ts.Complete() si llega ejecutarse realiza el commit o persistencia "física" en el proveedor de los datos, si se interrumpe el código antes de ejecutar esta sentencia, entonces hará un rollback(revertira lo actualizado en el proveedor de datos) de las transacciones que hasta ese momento se ejecutaron. Esta fuera del alcance de este documento enseñar a los lectores el manejo de transacciones, pero si es mi objetivo dejar una inquietud de conocer a detalle el manejo sencillo y eficiente de las transacciones en el .NET Framework 2.0.

Facilita su lectura y manejo en la Capa de Presentación

Por lo tanto ya que hemos encapsulado la lógica en la capa intermedia, en la capa de presentación solo tendremos que llenar la clase que representa la entidad de negocio e invocar el método de la capa de negocios para procesar la información como se muestra en el siguiente segmento de código:

private void Grabar()

{

try

{

Factura parametro = this.Factura;

parametro.UsuarioSistema = this.User.Identity.Name;

TransaccionBLL.Crear(parametro);

MessageBox.Show("Operacion realiza con Exito!");

}

catch (Exception ex)

{

MessageBox.ShowError(ex.Message);

}

}

En este segmento invocamos un Método en la capa de presentación Grabar que a su vez, invoca de la capa de negocio TransaccionBLL y su método Crear que recibirá como único parámetro la entidad Factura. Y eso es todo.

La entidad del negocio

Es muy importante definir la estratégica de comunicación entre las capas. En el ejemplo expuesto hemos utilizado Entidades de Negocio, representadas por Clientes, Facturas, Empleados, Nomina Quincenal, Movimientos Bancarios, etc.

Estas entidades carecen de métodos solo tiene propiedades, campos y posiblemente atributos, que nos pueden servir para almacenar la información como el mapeo de las propiedades a las columnas de la base de datos. Luciría de la siguiente manera:

[ ConnectionStringName("NORTHWIND"), ReadMethodName("OrderRead")]

public class Orden

{

private int? numeroOrden;

[ColumnName("OrderID"), ParameterName( "@OrderID",IsPrimaryKey=true,IsForCreate=false)]

public int? NumeroOrden

{

get { return numeroOrden; }

set { numeroOrden = value; }

}

private DateTime fecha;

[ColumnName("OrderDate"), ParameterName( "@OrderDate")]

public DateTime Fecha

{

get { return fecha; }

set { fecha = value; }

}

}

Donde ConnectionStringName, ReadMethodName, ColumnName, ParameterNamel, son atributos personalizados que el programador puede definir y que el .NET Framework utiliza ampliamente desde su versión 1.0. Se recuerda del [Seriealizable] este es un atributo que indica al CLR que la clase puede persistir en algún medio utilizado como lo es una variable de sessión, o una variable ViewState en ASP.NET.

Ahora veamos un ejemplo paso a paso de transformación de un súper botón a una implementación de arquitectura de n-capas.

A continuación les mostrare un ejemplo de un segmento de código que representa el evento de un botón que tiene como propósito insertar una orden de un cliente en la base de datos "Northwind" (incluida en SQL Server 2000). El código lo iremos transformando hasta alcanzar la infraestructura de negocios aplicando los conceptos de arquitectura de n-capas en .NET Framework 2.0.

private void btnInsertar_Click(object sender, EventArgs e)

{ // Validaciones de los datos capturados

if (parametroFechaOrden == null parametroFechaOrden == DateTime.MinValue)

{

MessageBox.Show("Debe de ingresar el numero de la Orden" );

return;

}

if (paremetroCodigoCliente == null paremetroCodigoCliente.Length == 0)

{

MessageBox.Show("Seleccione el cliente");

return;

}

// Segmento de Codigo usual en el manejo de la Capa de Presentacion

this.dataGridView1.Enabled = false; this.btnConsultar.Enabled = false;

// Manejo del acceso a los datos

Database db = DatabaseFactory .CreateDatabase("NORTHWIND");

string sqlCommand = "OrderCreate";

DbCommand orderCommand = db.GetStoredProcCommand(sqlCommand);

db.AddInParameter(orderCommand, "@CustomerID", DbType.String, paremetroCodigoCliente);

db.AddInParameter(orderCommand, "@EmployeeID", DbType.Int32, parametroCodigoEmpleado);

db.AddInParameter(orderCommand, "@OrderDate", DbType.Date, parametroFechaOrden);

sqlCommand = "OrderDetailCreate";

DbCommand orderDetailCommand = db.GetStoredProcCommand(sqlCommand);

using (DbConnection connection = db.CreateConnection())

{

connection.Open();

//manejo de transacciones

DbTransaction transaction = connection.BeginTransaction();

try

{

object valor = db.ExecuteScalar(orderCommand, transaction);

int numeroOrden = 0;

if (!int.TryParse(valor.ToString(), out numeroOrden)) throw new Exception("No pudo obtener el numero de Orden");

foreach (OrdenLinea linea in ordenDetalle)

{

if (orderDetailCommand.Parameters.Count > 0)

orderDetailCommand.Parameters.Clear();

db.AddInParameter(orderDetailCommand, "@OrderID", DbType.Int32, numeroOrden);

db.AddInParameter(orderDetailCommand, "@ProductID", DbType.String, linea.CodigoProducto );

db.AddInParameter(orderDetailCommand, "@UnitPrice", DbType.Decimal, linea.PrecioUnitario );

db.AddInParameter(orderDetailCommand, "@Quantity", DbType.Int32, linea.Cantidad );

db.AddInParameter(orderDetailCommand, "@Discount", DbType.Decimal, linea.Descuento);

db.ExecuteNonQuery(orderDetailCommand, transaction);

}

transaction.Commit();

}

catch (Exception ex)

{

transaction.Rollback();

MessageBox.Show(ex.Message);

this.dataGridView1.Enabled = true; this.btnConsultar.Enabled = true;

return;

}

finally

{

connection.Close();

}

this.dataGridView1.Enabled = true; this.btnConsultar.Enabled = true;

MessageBox.Show( "Ordern Guardada!");

}

}

El código anterior muestra un código típico cuando "no" se utiliza la arquitectura de n-capas, en el desarrollo de aplicaciones empresariales. Es muy difícil interpretar este código porque incluye el manejo de la capa de presentación las validaciones de los datos, el manejo de errores. Adicional a ello si necesitamos realizar esto en otra opción en nuestra aplicación estaremos obligados a repetir el código, y entonces la brecha (GAP) se expande en ves de reducirse en el objetivo de minimizar las entradas maliciosas a nuestra aplicación. Este es otro aspecto el de Seguridad es el que nos obliga a tener una infraestructura de software bien definida para reducir los puntos de vulnerabilidad de nuestra aplicación.

Ahora veamos como quedaría nuestra aplicación si refactorizamos (la disciplina que promueve la mejora del código interno sin afectar el comportamiento externo de una aplicación. Uno de sus expositores mas famosos es Martin Fowler y su libro "Refactoring") este código e implementamos la arquitectura de n-capas:

private void btnInsertar_Click(object sender, EventArgs e)

{

// Segmento de Codigo usual en el manejo de la Capa de Presentacion

this.dataGridView1.Enabled = false; this.btnConsultar.Enabled = false;

Orden orden = new Orden();

orden.CodigoCliente = paremetroCodigoCliente;

orden.Fecha = parametroFechaOrden;

try

{

bool OperacionExitosa = OrdenBLL.Crear(orden, ordenDetalle);

if (OperacionExitosa)

MessageBox.Show("Ordern Guardada!");

}

catch (Exception ex)

{

MessageBox.Show(ex.Message);

}

this.dataGridView1.Enabled = true; this .btnConsultar.Enabled = true;

}

Podemos notar que ahora es mucho mas fácil entender el código para hemos encapsulado en la capa intermedia la de negocios todo el código referente a la lógica del negocio. Deducimos por simple observación que hay una clase "OrdenBLL" que tiene un Método Crear; que Crea la orden (el encabezado y detalle de la orden), alrededor esta el código propio de la capa de presentación y el manejo del error, que para ejemplo solo lo capturamos para evitar una ruptura en el funcionamiento de la aplicación y mostramos el error.

Ahora vayamos mas adentro del código y veamos que encierra el método Crear de la clase "OrdenBLL":

public class OrdenBLL

{

public static bool Crear(Orden orden, OrdenLinea[] ordenDetalle){..}

public static bool Validar(Orden orden){…}

}

Esta clase de la capa intermedia tiene dos métodos uno que crea la orden y otro que valida los valores de la entidad de negocio Orden. Veamos ahora el método crear:

public static bool Crear(Orden orden, OrdenLinea[] ordenDetalle)

{

bool OperacionExistosa = false;

bool CreoDetalle = false;

if (Validar(orden))

{

using (TransactionScope ts = new TransactionScope ())

{

int? numeroOrden = OrdenDAL.Crear(orden);

if (numeroOrden == null numeroOrden == 0)

throw new Exception("No pudo obtener el numero de Orden" );

foreach (OrdenLinea linea in ordenDetalle)

{

linea.NumeroOrden = numeroOrden;

CreoDetalle = OrdenDAL.CrearDetalle(linea);

if (CreoDetalle) break ;

}

if (CreoDetalle)

ts.Complete();

}

}

return OperacionExistosa;

}

Este método se encarga de invocar el método validar que es publico por si se desea validar los datos sin efectuar ninguna operación. Luego de validar los datos esta capa se encarga de manejar las transacciones ya que invocamos dos diferentes métodos de la capa de acceso a datos Y cada uno de ellos maneja su propia conexión. Pero el código es fácilmente entendible indicándonos que hay una clase "OrdenDAL" que tiene un método para crear la orden (el encabezado) y otro el detalle si sucede algo sabemos que esta manejando transacciones y revertirá todo el proceso.

Ahora veamos los métodos de la capa de acceso a datos. Iniciemos con el método que Crea el encabezado de la orden:

public class OrdenDAL

{

public static int? Crear(Orden orden)

{

int? NuevoNumeroOrden = null;

Database db = DatabaseFactory .CreateDatabase("NORTHWIND");

string sqlCommand = "OrderCreate";

DbCommand orderCommand = db.GetStoredProcCommand(sqlCommand);

db.AddInParameter(orderCommand, "@CustomerID", DbType.String, orden.CodigoCliente);

db.AddInParameter(orderCommand, "@EmployeeID", DbType.Int32, orden.CodigoEmpleado);

db.AddInParameter(orderCommand, "@OrderDate", DbType.Date, orden.Fecha);

DbCommand orderDetailCommand = db.GetStoredProcCommand(sqlCommand);

using (DbConnection connection = db.CreateConnection())

{

connection.Open();

//manejo de transacciones

try

{

object valor = db.ExecuteScalar(orderCommand);

int numeroOrden = 0;

int.TryParse(valor.ToString(), out numeroOrden);

}

finally

{

connection.Close();

}

}

return NuevoNumeroOrden;

}

Esto método solo se encarga de pasar los valores de la entidad y ejecutar el procedimiento almacenado. A continuación el método que crea el detalle de la orden:

public static bool CrearDetalle(OrdenLinea detalle)

{

bool operacionExitosa = false;

Database db = DatabaseFactory.CreateDatabase("NORTHWIND" );

string sqlCommand = "OrderDetailCreate";

DbCommand orderDetailCommand = db.GetStoredProcCommand(sqlCommand);

db.AddInParameter(orderDetailCommand, "@OrderID", DbType.Int32, detalle.NumeroOrden);

db.AddInParameter(orderDetailCommand, "@ProductID", DbType.String, detalle.CodigoProducto );

db.AddInParameter(orderDetailCommand, "@UnitPrice", DbType.Decimal, detalle.PrecioUnitario );

db.AddInParameter(orderDetailCommand, "@Quantity", DbType.Int32, detalle.Cantidad);

db.AddInParameter(orderDetailCommand, "@Discount", DbType.Decimal, detalle.Descuento);

int afectados = db.ExecuteNonQuery(orderDetailCommand);

operacionExitosa = afectados > 0;

return operacionExitosa;

}

}

Este método la única diferencia del anterior es que crea el detalle de la orden pero hace lo mismo pasa los valores de la entidad y ejecuta el procedimiento almacenado. Esta capa gracias a la abstracción de la capa intermedia se convierte en una capa que realiza operaciones atómicas, mono-transaccionales, esto facilita su comprensión y reduce el riesgo de un error en el código porque solo hace una casa pasar los datos de la entidad al proveedor de datos. Si hay una falla del lado del proveedor de datos sabemos que es en esta capa o en el mismo proveedor de datos y no disperso por toda la aplicación o la capa de presentación.

El Futuro

Por ultimo quisiera mencionar que hay una fuerte tendencia y mala concepción que la lógica de negocio es más fácil y práctica dejarla en el proveedor de los datos, pero no es así. Si analizamos un poco mas encontraremos que si tenemos un lenguaje orientado a objetos como lo es C#, con disposición a definir Tipos Genéricos, la capacidad de utilizar la reflexión en las entidades, la definición de atributos, podremos reutilizar el código, cambiar su comportamiento, heredar los objetos y abstraer y encapsular el código de una forma mucho mas fácil y eficiente que desde un proveedor de datos relacional. En especial si vemos que en el futuro podremos invocar y manejar las colecciones como lo haríamos desde un proveedor de datos de una forma mas natural o través de funciones extensibles como lo serán el FROM, WHERE y SELECT dentro del mismo lenguaje de programación porque el .NET Framework 3.0 se encargará de generar el código al proveedor de datos o no ha oído o leído sobre LINQ. Aquí le dejo un segmento de código para que se emocione e investigue más al respecto:

from c in customers
join o in orders on c.CustomerID equals o.CustomerID into co
let n = co.Count()
where n >= 10
select new { c.Name, OrderCount = n }

Código extraído de las especificaciones del Nuevo C# 3.0 Mayo 2006.

Resumen

En resumen si tenemos definida la capa intermedia y su colaboración con la capa de acceso a los datos hacia abajo y hacia arriba la capa de presentación. Si fuera necesario que lo es hoy en día proveer a los usuarios de nuestra aplicación de acceso a otra plataforma o dispositivo de Hardware, solo nos preocuparíamos por crear una nueva capa de presentación y a lo sumo actualizar o modificar la capa de acceso a datos para acceder un proveedor mas liviano para implementar nuestra aplicación en un dispositivo móvil. Pero ya no nos preocuparíamos del negocio en sí, sino de la parte tecnológica que es la parte donde somos más competentes. Esto al largo plazo nos dará mayor seguridad y preparación para enfrentar los retos presentes y futuros, porque hemos desarrollado una infraestructura de software con servicios bien definidos gracias a la implementación de la arquitectura de n-capas.

Hasta una próxima vez!

Manolo Herrera

Líder de la Comunidad de Desarrolladores .NET en Guatemala

lunes, 19 de febrero de 2007

Y como estuvo la Reunión del Miércoles 7 de Febrero del 2007?

El miércoles 7 de febrero de 2007 nuestro buen amigo y colaborador Cristian Prieto, desarrollo el tema sobre Windows Workflow Foundation, el cual a todos nos impacto los niveles de abstracción de esta tecnología de la versión 3.0 del .NET Framework. Definitivamente esta nueva versión del .NET Framework viene para quedarse y deslumbrar a todos los desarrolladores con capacidades que solo soñábamos pero que ahora se esta convirtiendo en una realidad, poder representar el código gráficamente y manipularlo de esa manera es un gran avance que definitivamente dará sus réditos al aplicarlos a los problemas que los desarrolladores se enfrentan hoy en día. Todo apunta que haremos en el futuro un trabajo más arquitectónico que de picar piedra escribiendo cada singular línea de código.

Para los interesados Microsoft esta ha lanzado una suscripción gratuita de una revista para arquitectos o interesados en la arquitectura de software, que como les comentaba es un futuro promisorio. Aquí les va el link: http:// www.ArchitectureJournal.net .

Para un registro dentro de la comunidad a continuación les listo los que estuvieron con nosotros acompañándonos ese 7 de febrero:

amilcarcerna@gmail.com

Amilcar Cerna

andy_martinez00@hotmail.com

Andres Adan Martinez

Christian_Rodas@hotmail.com

Christian Rene Rodas Ortiz

dhidalgo@intersystemonline.com

Dorian Alberto Hidalgo Vallejo

fausto.lopez@gmail.com

Fausto Antonio Lopez Mansilla

francisco.gonzales@bayarcropscience.com

Juan Francisco Gonzalez

franzlopez@hotmail.com

Franz Lopez

marlon.ramos@gmail.com

Marlon Antonio Ramos Moscoso

oscar.robles@zaculeuvalley.com

Oscar Cuán Robles

ricardoarias@icasa.com.gt

Ricardo Arias

rodrigez2000@hotmail.com

Musin

sergiodonis@icasa.com.gt

Sergio Donis

Zuleta.7@hotmail.com

Juan Jose Zuleta

Antzu@bitinmail.com

Jose Antonio Zuleta

David Zuleta

Emy@riosho.com

Emy

Luispirir@gmail.com

Luis Pirir

jeemsk8@hotmail.com

Jose España

stefonic_solorsano@hotmail.com

Stefany Solorzano

christian_rodas@hotmail.com

Crhistian Rodas

cristian@rioshv.com

Cristian Rios

leonelbueso@yahoo.com

Leonel Bueso

ingejorge@gmail.com

Jorge Lopez

mherrera_deps@yahoo.com

Marce Herrera

jmuel@gmail.com

Jorge Veliz



--
Saludos,

Manolo Herrera

viernes, 2 de febrero de 2007

Otra Reunión por Celebrar este Miercoles 7 de febrero 2007

From: Manolo Herrera
Sent: Viernes, 02 de Febrero de 2007 11:13 a.m.
To: 'LaComunidadNET@googlegroups.com'; 'Luis Alfaro'; 'lilia beltran'
Subject: [DotNETGTGroup] Los esperamos este Miercoles 7 de febrero 2007
Importance: High


Tema: Windows Workflow Foundation (WWF)

Expositor: Cristian Prieto (Miembro del Buró de Expositores de la comunidad .NET Community). Experto en la tecnología a participado en diferentes Eventos en el extranjero de la nueva tecnología que esta desarrollando Microsoft.

Fecha: miércoles 7 de Febrero del 2007

Horario: 6:30 P.M. – 8:30 P.M.

Lugar: Oficinas Microsoft. Edificio Intercontinental Zona 10, 11 Nivel.

Costo: Gratis

Otros: Habrá Coffee Break, Parqueo y Premios

Invita: Comunidad de Desarrolladores .NET en Guatemala, con Apoyo de Microsoft de Guatemala

Un Extracto de la definición en el sitio de MSDN sobre el tema que se desarrollará: “is the programming model, engine, and tools for quickly building workflow-enabled applications on Windows. It consists of a namespace, an in-process workflow engine, and designers for Visual Studio 2005. Windows Workflow Foundation can be developed and run on Windows Vista, Windows XP, and the Windows Server 2003 family.”

Los esperamos!

Manolo Herrera

Coordinador de La Comunidad de Desarrolladores .NET en Guatemala (Blog: http://jmhogua.blogspot.com/)

Una Visión Esperanzadora

A veces nos preguntaremos ¿cuándo vamos a madurar como nación democrática?, y nos podemos sentir abrumados al ver que la nación que tiene la democracia mas antigua también tiene serios problemas aunque a resuelto otros, que nosotros aún estamos inmersos y como quisiéramos no tenerlos. Hace unos días aprendí sobre la percepción de la tenencia (Lo que existe, lo que se tiene es lo que importa, la riqueza depende del gobierno en transito que asigna lo que hay) versus el del valor de las ideas (lo que aún no se ha inventado, el respeto a la propiedad (intelectual) privada, la riqueza se distribuye de acorde a los que logran capitalizar las ideas que mejoran lo que actualmente existe, esto empuja a una nación a la productividad y por ende a la prosperidad).

La primera propia de los países subdesarrollados como el nuestro y la segunda a países desarrollados, industrializados y productivos.

Esto me hizo pensar que Latinoamérica hoy es como la mujer hace una década; que era la minoría, en todo lo referente a liderazgo y productividad, esto ahora esta cambiando y se estamos percibiendo una mujer que demuestra con creces su capacidad y competencia.

Hoy en día es de conocimiento popular que Europa es un continente muy viejo y esto implica que la capacidad de aprender y mejorar es cada vez mas largo y que lo que tienen hoy ira mermando si no se renueva este continente. Al contrario Latinoamérica, es joven, y esta aprendiendo a pasos agigantados, la capacidad de adquirir el conocimiento gracias a la tecnología y a nuestra gente ya no es una limitación. Entonces en ese orden de ideas no pensemos en lo que tenemos hoy sino en lo que seres capaces dentro de unos 10 años, y lo que han estado vaticinando las ultimas películas de Hollywood, puede convertirse en una realidad, Latinoamérica será un modelo y un generador de riquezas a través de las ideas, por el conocimiento aprendido, Latinoamérica esta despertando y redescubrir su potencial. No pienses en lo que tienes hoy sino en lo que mañana alcanzaras, porque tu eres Latinoamérica!.
Por Manolo Herrera