none
Duda con programación N Capas... RRS feed

  • Pregunta

  • Hola!

    Estoy intentando crear un programa simple utilizando el modelo de N Capas (3 capas en mi caso)


    En la capa Datos, tengo todo lo relacionado a mi Base de Datos con SQLite

    En la capa Lógica, tengo todo lo relacionado a la programación y el funcionamiento interno de mi Window Form

    En la capa Presentación, está la parte visual (Window Forms mismo).

    El problema que tengo es con las referencias, puedo llamar a la capa de Datos y Lógica desde Presentación (ya que he creado referencias a ambas para Presentación), pero no puedo crear a la inversa, lo que yo deseo es leer desde la capa de Datos o Lógica lo que está en la capa de Presentación, cuando intento crear dependencia, me dice Visual Studio que hay problema porque se generaría una dependencia circular.

    Actualmente está asi:

    Presentación ----> Datos
    Presentación ----> Logica

    Datos ---x--> Presentación
    Lógica ---x--> Presentación

    Como verán, necesito acceder a los textboxes Window Forms que están en Presentación pero desde Lógica y Datos..

    Como lo hago?

    saludos!

    Gracias


    • Editado digimikeh miércoles, 3 de octubre de 2018 22:32 imagen
    miércoles, 3 de octubre de 2018 22:32

Respuestas

  • Las referencias serían así:

    En tu ejemplo, si tienes los resultados del examen en la base de datos entonces deben participar las 3 capas, supongamos que tienes una tabla Respuestas entonces 

    Presentación:

    //Este código debe estar en tu formulario de la capa presentación, recuerda agregar using Negocios; en las referencias donde aparece using System;

    private void button1_Click(object sender, EventArgs e) { Examen Exam = new Examen();//Esto está en tu capa de negocios, es parte de la lógica de tu "Negocio" int usuarioRespuesta = 0; int examenRespuesta = Exam.TraerRespuesta();//Presentación le solicita a negocios //Presentación le solicita al usuario y valida sus entradas y le muestra información if (radioButton1.Checked) usuarioRespuesta = 1; else if (radioButton2.Checked) usuarioRespuesta = 2; else if (radioButton3.Checked) usuarioRespuesta = 3; else { MessageBox.Show("Porfavor seleccione una respuesta"); return; } if (examenRespuesta == usuarioRespuesta) MessageBox.Show("La respuesta es correcta"); else MessageBox.Show("La respuesta es incorrecta, la opción correcta era la número " + examenRespuesta.ToString()); }


    Negocios (Creamos la clase Examen):

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Datos;
    
    namespace Negocios
    {
        public class Examen
        {
            public int TraerRespuesta()
            {
                //Capa de negocios solicita datos a la capa de datos
                BD basedatos = new BD();
                int Respuesta =  basedatos.ObtenerDatoTabla("ExamenRespuseta");
                return Respuesta; // le regresa la info a la capa presentación
            }
        }
    }
     

    Datos:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace Datos
    {
        public class BD
        {
            public int ObtenerDatoTabla(string Tabla)
            { 
                //aca la lógica de tu capa de datos para consultar la información en la base de datos
                
                return 2;// le respondemos a la capa de negocios
            }
        }
    }
    

    Revisa este enlace para mas ejemplos

    https://social.msdn.microsoft.com/Forums/es-ES/68e76e53-ab13-4378-901b-ade1de96fc3c/ejemplo-simple-en-c-con-3-capas-ejemplo-sencillo?forum=vcses

    
    • Marcado como respuesta digimikeh jueves, 4 de octubre de 2018 19:19
    jueves, 4 de octubre de 2018 15:19

Todas las respuestas

  • Estas aplicando mal la estructura "datos negocios presentación", la comunicación entre ellas es lineal: Datos-->Negocios-->Presentación, la capa de datos en ningún momento debe ni tiene porque comunicarse con la de presentación, la idea es la capa de presentación solicita cosas a la capa de negocios y la capa de negocios solicita cosas a la de datos y se acabó, mira lo que tienes va en buen camino, veamos:

    En la capa Datos, tengo todo lo relacionado a mi Base de Datos con SQLite (Esto esta bien)

    En la capa Lógica, tengo todo lo relacionado a la programación y el funcionamiento interno de mi Window Form (acá no debe ir el funcionamiento de tus formularios, eso va en la capa de presentación, acá va la lógica del negocio, por ejemplo si el negocio es una farmacia, entonces acá irán funciones como TraerProductosAVencer, EliminarProductosVencidos)

    En la capa Presentación, está la parte visual (Window Forms mismo, captura de datos por parte del usuario como nombre del producto y fecha de vencimiento, validaciones simples como no texto en números, cálculos simples como fecha de vencimiento = Hoy + 20 días).

    La capa de negocios es el comunicador y validador entre tu capa de datos y tu capa de presentación

    Capa de datos, contiene todas las funciones que tienen que ver con la base de datos

    Capa Negocios, recepciona solicitudes de la capa de presentación, solicita datos a capa de datos y le regresa los resultados a capa presentación.

    Capa Presentación, recepciona datos que digita el usuario y le presenta datos al usuario, hace validaciones sencillas

    La capa de negocios no le interesa cuantos textbox tengas en un formulario, mucho menos a la de datos, veamos el ejemplo completo, tengo el formulario crear medicamento, entonces en mi capa de presentación tengo mi formulario con mis controles, ahi recepciono todos los valores que digita el usuario, le digo si está escribiendo un texto donde debe poner un número, una vez que el usuario termina y manda a guardar a la base de datos entonces como la capa de presentación no tiene idea de la base de datos ni de la capa de datos entonces le pide a la capa de negocios que guarde la información y le manda lo que el usuario digitó, la capa de negocios recibe los datos los valida (por ejemplo si el medicamento está betado y no se recepcionaría mas) y le dice a la capa de datos lo que hará con ellos en este caso agregarlos a la tabla Medicamentos, la capa de datos a su vez ejecuta la instrucción contra la base de datos, es decir le dice "INSERT INTO Medicamentos VALUES()", le regresa la respuesta a la capa de negocios y esta a su vez a la capa de presentación la cual le manda un mensaje al usuario de "Registro Exitoso"

    Entonces tu capa de datos no debe tener ninguna referencia a los otros proyectos, la capa de negocios solo necesita la referencia de la capa de datos, y la capa de presentación solo necesita la referencia a la capa de negocios


    miércoles, 3 de octubre de 2018 23:14
  • Hola!!, gracias por tu respuesta.

    Por ejemplo en mi caso estoy programando un examen, tengo una pregunta y 3 alternativas (radiobuttons), revisar si esa alternativa es la correcta al presionar el botón "Finalizar examen" y mostrar el messagebox "La respuesta es correcta", sería tarea de la capa "Presentación" entonces y no de negocios verdad?...

    Y la llamada de referencias para lo que me explicas es lineal también?

    primero, le añado una referencia a la capa Datos que apunte a Negocios
    luego, le añado una referencia a la capa Negocios que apunte a Presentación ?

    Saludos y muy amable por responder.


    jueves, 4 de octubre de 2018 14:06
  • Las referencias serían así:

    En tu ejemplo, si tienes los resultados del examen en la base de datos entonces deben participar las 3 capas, supongamos que tienes una tabla Respuestas entonces 

    Presentación:

    //Este código debe estar en tu formulario de la capa presentación, recuerda agregar using Negocios; en las referencias donde aparece using System;

    private void button1_Click(object sender, EventArgs e) { Examen Exam = new Examen();//Esto está en tu capa de negocios, es parte de la lógica de tu "Negocio" int usuarioRespuesta = 0; int examenRespuesta = Exam.TraerRespuesta();//Presentación le solicita a negocios //Presentación le solicita al usuario y valida sus entradas y le muestra información if (radioButton1.Checked) usuarioRespuesta = 1; else if (radioButton2.Checked) usuarioRespuesta = 2; else if (radioButton3.Checked) usuarioRespuesta = 3; else { MessageBox.Show("Porfavor seleccione una respuesta"); return; } if (examenRespuesta == usuarioRespuesta) MessageBox.Show("La respuesta es correcta"); else MessageBox.Show("La respuesta es incorrecta, la opción correcta era la número " + examenRespuesta.ToString()); }


    Negocios (Creamos la clase Examen):

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Datos;
    
    namespace Negocios
    {
        public class Examen
        {
            public int TraerRespuesta()
            {
                //Capa de negocios solicita datos a la capa de datos
                BD basedatos = new BD();
                int Respuesta =  basedatos.ObtenerDatoTabla("ExamenRespuseta");
                return Respuesta; // le regresa la info a la capa presentación
            }
        }
    }
     

    Datos:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace Datos
    {
        public class BD
        {
            public int ObtenerDatoTabla(string Tabla)
            { 
                //aca la lógica de tu capa de datos para consultar la información en la base de datos
                
                return 2;// le respondemos a la capa de negocios
            }
        }
    }
    

    Revisa este enlace para mas ejemplos

    https://social.msdn.microsoft.com/Forums/es-ES/68e76e53-ab13-4378-901b-ade1de96fc3c/ejemplo-simple-en-c-con-3-capas-ejemplo-sencillo?forum=vcses

    
    • Marcado como respuesta digimikeh jueves, 4 de octubre de 2018 19:19
    jueves, 4 de octubre de 2018 15:19
  • Yerald Mora, muchas gracias por tu paciencia y tiempo, me queda mas claro ahora como trabajan las 3 capas..

    Ahora si le hallo sentido.

    Un abrazo.

    jueves, 4 de octubre de 2018 19:19
  • hola

    >>puedo llamar a la capa de Datos y Lógica desde Presentación

    Eso es incorrecto, se supone que desde la presentacion solo puede comunicarte con Logica, no deberias conectar Presentacion con datos

    >>pero no puedo crear a la inversa, lo que yo deseo es leer desde la capa de Datos o Lógica lo que está en la capa de Presentación

    no tienes que hacer eso, no es asi como funciona

    se supone que de presentacion envias los datos a la logica para que realice las acciones, pero solo envias datos simples no controles

    >>necesito acceder a los textboxes Window Forms que están en Presentación pero desde Lógica y Datos

    no, esto es incorrecto NUNCA se accede a los controles desde logica o datos

    [WinForms] Edición Empleados

    analiza el ejemplo del articulo

    recuerda que debes enviar los datos del textbox a la logica, pero son datos imples no controles

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    viernes, 5 de octubre de 2018 1:36
  • Gracias por contestar, si, me percaté de todo esto con las respuestas anteriores, prácticamente los métodos de las capas de Dato y Logica (o Negocios) devuelven siempre un tipo de valor primitivo no ?..

    De repente los nombres de los métodos de Datos y Lógica y me parecen algo redundantes, por ejemplo estoy intentando obtener una tabla y mostrarla en un DataGridView...

    Capa_Lógica

    public int obtenerTabla(){
         BD bd = new BD();
         bd.obtenerTabla();
    }

    Había leído que la palabra "Traer" se utiliza mucho, tal como lo hizo Yerald.  Pero traer y obtener son similares, es normal que exista esta redundancia en los nombres?


    • Editado digimikeh lunes, 8 de octubre de 2018 18:16 ..
    lunes, 8 de octubre de 2018 17:58
  • Hola digimikeh

    Los nombres no tienen que ser redundantes, la capa de datos no está ligada a un sistema en específico, es indiferente al giro del negocio por lo que el nombre de sus métodos serán siempre generales y tendrán que ver con base de datos, mientras que la capa de negocios si está ligada al sistema que estas desarrollando por lo que los nombres de sus métodos por lo general tendrán que ver con el "giro del negocio" para el que estés desarrollando tu aplicación, por ejemplo un "obtenerTabla" es general y sería un nombre mas para la capa de datos que para la de negocios, para la capa de negocios podría ser "ObtenerExamenesPorParcial" igual puede ser "TraerExamenesPorParcial", esto deja visto que la aplicación tiene que ver con exámenes de un colegio, ese es su giro de negocio. Si miras en el ejemplo que te dí en la capa de Negocios el método se llama "TraerRespuesta" una respuesta tiene que ver con tu aplicación de éxamenes, mientras que "TraerRespuesta" ejecuta un método de la capa de datos que si es mas general "ObtenerDatoTabla", y tabla puede contener cualquier tipo de información no necesariamente las respuestas a un examen.

    Respecto a usar "traer" u "obtener"; son convenciones que diría yo debe establecer el desarrollador o el grupo de desarrolladores, de tal forma que la lectura de su código sea comprensivo y ordenado, por ejemplo si yo como desarrollador establezco una norma de que todo método que me devuleva un datatable dentro de mi código debe comenzar con "Traer" y luego nombre descriptivo de lo que deseo, entonces cuando mi código sea grande se me hará fácil entender que quiero en un método "TraerTalCosa".




    • Editado Yerald Mora lunes, 8 de octubre de 2018 20:04
    lunes, 8 de octubre de 2018 19:59
  • Vale, esta mas que claro...

    saludos! y gracias.

    lunes, 8 de octubre de 2018 20:08