DESARROLLO EN 3 CAPAS

10/11/2005 - 02:58 por rafael | Informe spam
Bueno , perdonen la pregunta reiterada pero no encuentro el post anterior.
Explico mi problema, Trabajo con Visual Basic 6.0 SP 6, y SQL Server 2000
Profesional.
Estoy programado con capas, y ya tengo la capa de acceso a datos y la capa
de entidades
Por ejemplo :
Clase entidadPersona
Private Nombre as string
Private Apellido as string
.
.
Propiedades para cada una de las variables publicas
Let Nombre
Get Nombre.
...

Clase EntidadHabilidad
Private Habilidad as string
Propiedades para cada una de las variables publicas
Let Nombre
Get Nombre.
...

clase datosPersonas
Public function Grabar(nuevaPersona as entidadPersona) as boolean
Dim Coneccion As ADODB.Connection
Dim Comando As ADODB.Command
Codigo para grabar datos de persona en la tabla persona
Comando.Execute
Comando.ActiveConnection = Nothing
Coneccion.Close
Set Comando = Nothing
Set Coneccion = Nothing
Grabar = True
end function


Clase DatosHabilidad
Public function Grabar(nuevaHabilidad as entidadHabilidad) as boolean
Dim Coneccion As ADODB.Connection
Dim Comando As ADODB.Command
Codigo para grabar datos de habilidad
Comando.Execute
Comando.ActiveConnection = Nothing
Coneccion.Close
Set Comando = Nothing
Set Coneccion = Nothing
Grabar = True
end function

Bueno hasta ahi no hay problema
Ahora estaba pensando armar la capa de logica de negocios asi
clase LogicaPersona(nuevaPersona as entidadPersona, nuevaHabilidad as
entidadHabilidad)
Dim Coneccion As ADODB.Connection
Dim Comando As ADODB.Command
dim dPersona as datosPersona
dim dHabilidad as datosHabilidad
codigo para establecer la conexion
Coneccion.BeginTrans
if dPErsona.Grabar(nuevaPersona) then
if dHabilidad.Grabar(nuevaHabilidad) then
Coneccion.ComitTrans
else
Coneccion.RollbackTrans
else
Coneccion.RollbackTrans
end if

Bueno lo hice y funciona. Graba tanto los datos de persona y habilidad.
Pero el problema que no aplica la transaccion. es decir se puede grabar
persona y no necesariamente la habilidad
todo como un bloque
Lo he tenido que implementar ambas clases en un solo procedimiento.
No se porque no funcione el begintrans.
Lo unico que se me puede ocurrir es que en cada funcion de las clases de
acceso a datos
uso una conexion propia.
Agradezo de antemano cualquier ayuda

Preguntas similare

Leer las respuestas

#11 Alfredo Novoa
22/11/2005 - 12:09 | Informe spam
On Mon, 21 Nov 2005 12:48:22 -0500, "rafael"
wrote:

A su vez una aplicación puede tener varios componentes, que reciben cierta
clasificacion similar a la de los sistemas de informacion.



Si, pero originalmente el término "multitier" se aplicaba solamente a
los sistemas de información y no a las aplicaciones, hasta que alguien
confundió las dos cosas y un montón de personas le copiaron.

Porque estuve leyendo la guia Arquitectura de aplicaciones
de .net : Diseno de aplicaciones y servicio.
http://www.microsoft.com/spanish/ms...istapp.asp



Yo me olvidaría de esta guía, está realmente mal.

Como regla general NUNCA hay que intentar aprender arquitectura de
sistemas de información utilizando materiales que provengan de
fabricantes de software. Es mucho mejor acudir a textos universitarios
como los enlaces que te pasé en un mensaje anterior.

, y
menciona capa de accesso a datos dentro de una aplicacion, pero usa el
termino algo ambiguo , porque esa capa de acceso a datos se transforma en un
componente.



Ya te digo que casi todo lo que puedes leer allí está mal.

Ahora si entendi bien, (eso espero :) ) , si creo una sistema de
informacion, con un .exe que contenga los formularios y reglas de formato,
validacion simple, una dll para accesar a los datos,el sistema de
informacion seria cliente servidor de 2 capas



Si la aplicación utiliza los servicios de un SGBD y las reglas de
negocio están garantizadas por este, entonces si sería de dos capas.
Pero no por la dll, por supuesto sino por que estarías usando un SGBD.

Si estuvises usando un procesador de archivos como MS Jet (también
conocido incorrectamente como Access), entonces sería un sistema de
una capa por muchas dll que use.

, y si le agrego una dll para
reglas de negocio seria de 3 capas,



En este sería más bien un sistema de una capa, por que las reglas de
negocio volverían a estar garantizadas por la aplicación y estarías
infrautilizando el SGBD como un simple procesador de archivos.

Tres capas es cuando pones un servidor de aplicaciones entre las
aplicaciones y el SGBD

independientemente de donde esten las
dlls o es que para que cumplan con la definicion estas deben estar en una
maquina distinta a la que tiene el programa (.exe).



No, no es necesario que se encuentren en máquinas distintas. Puedes
tener un sistema de tres capas en una misma máquina.



Saludos
Respuesta Responder a este mensaje
#12 rafael
23/11/2005 - 17:41 | Informe spam
Tres capas es cuando pones un servidor de aplicaciones entre las
aplicaciones y el SGBD


Si entiendo pero en el servidor de aplicaciones, lo que se aloja no son las
dlls?
Respuesta Responder a este mensaje
#13 Alfredo Novoa
24/11/2005 - 01:40 | Informe spam
On Wed, 23 Nov 2005 11:41:44 -0500, "rafael"
wrote:

Tres capas es cuando pones un servidor de aplicaciones entre las
aplicaciones y el SGBD


Si entiendo pero en el servidor de aplicaciones, lo que se aloja no son las
dlls?



Podría ser así, pero pensaba que te referías a usar las dll
directamente desde las aplicaciones.

Eso sería un sistema de tres capas, pero uno muy malo por varias
razones.

El código procedimental es la peor forma de implementar las reglas de
negocio. Siempre que sea posible se debe de utilizar código
declarativo como SQL.

Es decir en lugar de crear escribir procedimientos en una dll para
asegurarte de que no hay dos artículos con el mismo código sería mucho
mejor declarar una clave primaria en SQL. Este es un ejemplo muy
sencillo pero en casos más complicados la idea es la misma.

En un sistema de dos capas las aplicaciones se comunican con el SGBD a
través de un lenguage relacional que es SQL (en realidad es
pseudorelacional, pero esto es otra historia). Es decir que lo que ven
las aplicaciones es un diseño lógico de base de datos relacional, que
es la mejor forma de organización lógica de una base de datos que se
conoce.

En el caso de un sistema de tres capas, esto no debería cambiar, y las
aplicaciones deberían ver lo mismo que veían antes y esto es algo
fundamental. Es decir que el servidor de aplicaciones debería de
mostrar a las aplicaciones un diseño de base de datos relacional y la
comunicación entre aplicaciones y servidor de aplicaciones debería de
hacerse con un lenguaje como SQL.

En realidad seguiríamos teniendo un sistema Cliente/Servidor, solo que
la parte Servidor se habría dividido en dos capas de forma
transparente para las aplicaciones.

Esto ocurriría por ejemplo con un servidor de mensajes que se dedicase
a repartir las consultas SQL entre una serie de servidores SQL,
mandandolas al que esté menos ocupado en ese momento.

Otra forma correcta sería utilizar un SGBD relacional virtual como
este: www.alphora.com

En este caso el servidor de aplicaciones sería un auténtico SGBD
relacional capaz de asegurar la lógica de negocio y que delega parte
del trabajo en otros SGBD SQL. Aquí la ventaja es que podemos usar un
lenguaje mucho mejor que SQL, tanto para implementar las reglas de
negocio de forma declarativa en el SGBD como para hacer consultas
desde las aplicaciones.

Si el servidor de aplicaciones no presenta una interfaz relacional a
las aplicaciones es que las cosas se están haciendo muy mal, y esto no
te lo dicen en la MSDN.


Saludos
Alfredo
Respuesta Responder a este mensaje
#14 rafael
24/11/2005 - 03:51 | Informe spam
El código procedimental es la peor forma de implementar las reglas de
negocio. Siempre que sea posible se debe de utilizar código
declarativo como SQL.


Entiendo que el codigo procedimental no es adecuado, por ello dentro de las
dlls
hay clases no modulos.

Es decir en lugar de crear escribir procedimientos en una dll para
asegurarte de que no hay dos artículos con el mismo código sería mucho
mejor declarar una clave primaria en SQL. Este es un ejemplo muy
sencillo pero en casos más complicados la idea es la misma.


TOTALMENTE CORRECTO, INDISCUTIBLE

Mi problema actual va por el hecho, en que no me queda claro , como
exactamente implementarla.
Como me imagene implementarla y la estaba haciendo, era crear una clase que
manejara las transacciones, para luego
colocarlo en el servidor de aplicaciones algo asi:
Clase ManejarVentas
Public function Grabar(Factura as cFactura, Items as colItems)
'Codigo bla bla bla
'cFactura es una bussines entity es decir una clase que representa a la
entidad Factura de la bd.
'colItems es una coleccion de objetos Items que son los productos que deben
insertarse en la factua.
dim datFactura as dFactura ' clase que utilizo para menajr las insertar,
eliminar o actualizar registros en la tabla factura.
dim datItem as dItem 'clase que utilizo para insertar, eliminar o actualizar
registros en la tabla detalle de factura.
'Codigo para iniciar la transaccion algo como Conexion.Begintrans
if datFactura.Grabar(Factura)
For i=1 to Items.cantidad
datItem.Grabar(Items.item(x))
next i
else
Conexion.Rollback
end if
end function
Pero el problema que no medi, era que como las clases de datos factura y
item utilizan su propio objeto
conexion , la transaccion realmente no se cumple.
Ademas de una duda derivada de esta implementacion, esta clase deberia
contener tambien una funcion listar (para listar las facturas) , lo cual
seria correcto con la teoria del aislamiento de capas, pero reduciria la
perfomance.
Clase datFactura
Public function Listar() as ADODB.Recordset
´Mucho Codigo
end function
Clase ManejarVentas
Public Function Listar() as ADODB.Recordset
´Devuelvo el mismo recordset generado por la clase datFactura?
´Eso no haria un poco mas lento el proceso?
end function
Respuesta Responder a este mensaje
#15 Alfredo Novoa
24/11/2005 - 11:15 | Informe spam
On Wed, 23 Nov 2005 21:51:43 -0500, "rafael"
wrote:

El código procedimental es la peor forma de implementar las reglas de
negocio. Siempre que sea posible se debe de utilizar código
declarativo como SQL.


Entiendo que el codigo procedimental no es adecuado, por ello dentro de las
dlls
hay clases no modulos.



C# es un lenguaje tan procedimental como el viejo C, y es igual de
inadecuado como este para implementar las reglas de negocio que se
puedan expresar de forma declarativa.

Es decir en lugar de crear escribir procedimientos en una dll para
asegurarte de que no hay dos artículos con el mismo código sería mucho
mejor declarar una clave primaria en SQL. Este es un ejemplo muy
sencillo pero en casos más complicados la idea es la misma.


TOTALMENTE CORRECTO, INDISCUTIBLE



Pues la mayoría de la gente lo discute o lo rechaza airadamente.

Mi problema actual va por el hecho, en que no me queda claro , como
exactamente implementarla.



Ya, eso es lo dificil. Sobre todo con el estado actual de las
herramientas de programación. Pocos SGBD SQL soportan las "Assertions"
de SQL, y son algo fundamental.

Como me imagene implementarla y la estaba haciendo, era crear una clase que
manejara las transacciones, para luego
colocarlo en el servidor de aplicaciones algo asi:



Pero las transacciones ya las gestiona el SGBD.

Clase ManejarVentas



Esto es justo lo que no hay que hacer. Los datos los debe de manejar
el SGBD y no el código de aplicación.

Public function Grabar(Factura as cFactura, Items as colItems)
'Codigo bla bla bla
'cFactura es una bussines entity es decir una clase que representa a la
entidad Factura de la bd.
'colItems es una coleccion de objetos Items que son los productos que deben
insertarse en la factua.



¿Por que insertas los productos en una colección pudiendo hacerlo
directamente en la base de datos?

dim datFactura as dFactura ' clase que utilizo para menajr las insertar,
eliminar o actualizar registros en la tabla factura.
dim datItem as dItem 'clase que utilizo para insertar, eliminar o actualizar
registros en la tabla detalle de factura.
'Codigo para iniciar la transaccion algo como Conexion.Begintrans
if datFactura.Grabar(Factura)
For i=1 to Items.cantidad
datItem.Grabar(Items.item(x))
next i
else
Conexion.Rollback
end if
end function



Aquí supongo que los datos que están en el objeto Factura ya han sido
validados usando código de aplicación, y esto es justo lo que no hay
que hacer. En lugar de ir creando el objeto factura deberías de ir
grabando los datos en la base de datos. Las clases Factura e Items
sobran. Es lo que llevo intentando decir todo el rato.


Saludos
Alfredo
Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida