Saltar al contenido

Patrones de Diseño – Ejemplo DAO+DTO+Singleton,Búsqueda y filtro de datos -C#,SQL (Cap 2)

Los patrones de diseño son aquellos que expresan esquemas para definir estructuras o micro-arquitecturas de diseño o sus relaciones en los componentes, es decir, definen los detalles de cómo está construido un sistema de software mediante la colaboración de clases y objetos para resolver un problema general de diseño en un contexto particular. Los patrones de diseño resuelven problemas más localizados, tienen menos impacto en la base del código, afectan una sección específica de la base del código, por ejemplo:

  • Cómo instanciar un objeto cuando solo sabemos qué tipo necesita instanciarse en tiempo de ejecución.
  • Cómo hacer que un objeto se comporte de manera diferente según su estado.

Los patrones de diseño describen una estructura interna y la relación entre algunas clases o módulos internos para obtener una solución en la estructura o componente de un sistema de software, es decir, un patrón de diseño solo afecta en uno o varios componentes internos de un sistema de software o aplicación (Patrones de diseño orientado a subsistemas de componentes).

Inclusive solo puede afectar la estructura interna de una clase o definir una estructura para la creación y comportamiento de un objeto (Patrones de diseño orientado a clases y objetos).

En cambio, un patrón de arquitectura representa la relación entre los componentes de todo el sistema y cada uno de ellos está compuesto por pequeños módulos. Afecta a la estructura global del sistema, ya que expresan un esquema organizativo estructural para sistemas de software, por lo tanto, los patrones de diseño ayudan a comprender esa arquitectura, estructura o componente.

Observa el siguiente gráfico para obtener un mejor concepto general acerca de patrones de diseño.

Clasificación / Tipos de Patrones de Diseño

Patrones de diseño orientado a clases y objetos

Este tipo de patrones de diseño solamente definen la estructura y comportamiento de clases u objetos.

Hay una gran variedad de patrones de diseño orientado a clases y objetos. Los más populares y aceptados por la comunidad son del libro Design patterns, Elements of Reusable Object- Oriented Software, escrita por los Gang of Four (GOF), en este libro se presentan 23 patrones de diseño, divididos en 3 categorías.

Patrones de Diseño Creacionales: Se encarga de la Inicialización y Configuración de objetos.

  • Abstract Factory
  • Builder
  • Factory Method
  • Prototype
  • Singleton

Patrones de Diseño Estructurales: Separan la interfaz de la implementación. Se ocupan de cómo las clases y objetos se agrupan para formar estructuras más grandes.

  • Adapter (de objetos)
  • Bridge
  • Composite
  • Decorator
  • Façade
  • Flyweight
  • Proxy

Patrones de Diseño de Comportamiento: Se encarga en describir objetos o clases y la comunicación entre ellos.

  • Interpreter
  • Template Method
  • Chain of Responsibility
  • Command
  • Iterator
  • Mediator
  • Memento
  • Observer
  • State
  • Strategy
  • Visitor

Patrones de diseño orientado a subsistemas de componentes

Este tipo de patrones de diseño definen estructuras de componentes o sus relaciones, por ejemplo: patrones de diseño orientado al acceso de datos, dominio o presentación, como también definen la estructura y comportamiento de clases y objetos.

Generalmente, este tipo de patrones está orientado para aplicaciones empresariales. Entre los patrones más conocidos de este tipo tenemos; los patrones de diseño presentados en el libro J2EE Patterns, Best Practices and Design Strategies – Second Edition-2002 escrita por desarrolladores de  Java. En este libro, indican que existen 5 capas de arquitectura, y 15 patrones de diseño, divididos en 3 de las capas, presentación, negocios e integración. 

Patrones de diseño orientado a la capa de presentación: Estos patrones se encargan de la interfaz gráfica y de la interacción con el usuario.

  • Intercepting Filter
  • Front Controller
  • View Helper
  • Composite view
  • Service To Worker
  • Dispatcher View

Patrones de diseño orientado a la capa de negocio: Estos patrones se encargan de las reglas de negocio, validaciones de negocio y transferencia de datos.

  • Business Delegate
  • Session Facade
  • Service Locator
  • Value Object Assembler
  • Value List Handler
  • Composity Entity
  • Data Transfer Object(DTO)

Patrones orientado de integración o acceso a datos, estos patrones se encarga de explotar los datos de cualquier fuente, ya sea archivos o base de datos.

  • Service Activator
  • Data Access Object(DAO)

Por otra parte, también hay algunos patrones de diseño presentados por Martin Fowler en su libro Patterns of Enterprise Application Architecture (PEAA- 2002).

Sin embargo, en la actualidad, en este tipo de patrones existe mucha controversia entre definir si es un patrón de diseño o arquitectura, debido a la evolución del desarrollo de software en estos últimos años. Ademas los patrones de este tipo puede ser utilizado tanto como un Patrón Arquitectónico o un Patrón de Diseño, dependiendo del alcance (Granularidad) en el que lo usemos. Explicaré todo a detalle en los siguientes artículos.

Recuerden que No es obligatorio utilizar los patrones. Solo es aconsejable en el caso de tener el mismo problema o similar que soluciona el patrón, siempre teniendo en cuenta que en un caso particular puede no ser aplicable. Abusar o forzar el uso de los patrones puede ser un grave error, provocando Antipatrones o Patterns happy.

Ejemplo: Aplicación de Mostrar y Filtrar Datos con Patrón DAO, DTO y Singleton-C#, SQL

Ahora pasemos a los ejemplos,realizaremos una pequeña aplicación para mostrar, búsqueda y filtro de datos, con Lenguaje C#, SQL Server y programación orientada a objetos.

Aplicaremos el patrón singleton, que restringe la instanciación de una clase o valor de un tipo a un solo objeto, básicamente solo permite crear una instancia única, este patrón lo usaremos para solucionar el problema de instancias múltiples de un formulario.

Patrón Data Transfer Object (DTO), se trata de un objeto serializable para la transferencia de datos.

Patrón Data Access object (DAO), consiste en utilizar un objeto de acceso a datos para abstraer y encapsular todos los accesos a la fuente de datos. El DAO maneja la conexión con la fuente de datos para obtener y almacenar datos.

Crear Base de Datos – SQL Server

  • Crea la siguiente base de datos y tabla clientes.
--CREAR BASE DE DATOS
create database Practica_Patrones
go
use Practica_Patrones
go
--CREAR TABLA 
CREATE TABLE Clientes (
  ID int IDENTITY(1,1) primary key,
  Nombre nvarchar(20) NOT NULL,
  Apellido nvarchar(23) NOT NULL,
  Direccion nvarchar(100) NOT NULL,
  Ciudad nvarchar(100) NOT NULL,
  Email nvarchar(100) NOT NULL,
  Telefono nvarchar(25) NOT NULL,
  Ocupacion nvarchar(70) NOT NULL
);
go
  • Inserta algunos datos a la tabla clientes, o puedes insertar los 10 000 registros descargando el proyecto.

Crear Procedimientos Almacenados – SQL Server

--Busqueda de datos exactos
select *from Clientes where Nombre='romeo'
--Busqueda de datos por Aproximacion 
select *from Clientes where Nombre like 'Zo%'
--PROCEDIMIENTO
CREATE PROC VerRegistros
@Condicion nvarchar(30)
as
select *from Clientes where ID like @Condicion+'%' or Nombre like @Condicion+'%' 
go

Crear Proyecto Aplicación C# – Visual Studio

  • En Visual Studio, crea un proyecto nuevo de aplicación de Windows Form en Visual C#  y asígnele el nombre que desee. Yo lo nombraré App_Registros.

Crear Objetos de Transferencia de Datos (DTO)

  • En nuestro proyecto, agregamos una nueva carpeta de nombre DTO.
  • Dentro de la carpeta agregamos todas clases necesarias para transportar datos de alguna entidad, en este caso la entidad Cliente, en este patrón solamente se debe declarar los atributos y/o propiedades (para no tener objetos pesados) de la entidad y algún método de serializacion (Opcional).

Clase Cliente DTO

    class ClientesDto
    {
        //ATRIBUTOS 
        int  _ID;
        string _Nombre;
        string _Apellido;
        string _Direccion;
        string _Ciudad;
        string _Email;
        string _Telefono;
        string _Ocupacion;
        //PROPIEDADES GETTERS AND SETTERS
        public int ID
        {
            get
            {
                return _ID;
            }

            set
            {
                _ID = value;
            }
        }

        public string Nombre
        {
            get
            {
                return _Nombre;
            }

            set
            {
                _Nombre = value;
            }
        }

        public string Apellido
        {
            get
            {
                return _Apellido;
            }

            set
            {
                _Apellido = value;
            }
        }

        public string Direccion
        {
            get
            {
                return _Direccion;
            }

            set
            {
                _Direccion = value;
            }
        }

        public string Ciudad
        {
            get
            {
                return _Ciudad;
            }

            set
            {
                _Ciudad = value;
            }
        }

        public string Email
        {
            get
            {
                return _Email;
            }

            set
            {
                _Email = value;
            }
        }

        public string Telefono
        {
            get
            {
                return _Telefono;
            }

            set
            {
                _Telefono = value;
            }
        }

        public string Ocupacion
        {
            get
            {
                return _Ocupacion;
            }

            set
            {
                _Ocupacion = value;
            }
        }
        
    }

Crear Objectos de Acceso a Datos (DAO)

  • Agregamos una nueva carpeta de nombre DAO a nuestro proyecto.
  • Dentro de la carpeta agregamos una clase para conexión a la base de datos SQL Server.
  • Importamos la librería System.Data.SqlClient.
  • Creamos el objeto sqlConnection como parámetro, enviamos la cadena de conexión.

Clase Conexión

    class ConexionBD
    {
        protected SqlConnection Conexion =
            new SqlConnection(
                "Server=DESKTOP-4FVONF2;DataBase=Practica_Patrones;Integrated Security=true"
                );
    }
  • Agregamos otra clase de nombre Clientes para el acceso a datos y crear los métodos CRUD.
  • Importamos las librerias using System.Data y using System.Data.SqlClient.
  • Indicamos que la clase hereda de la clase conexion.
  • Creamos los métodos Crud, en este caso, solo implementare para leer datos y filtrar datos (Busqueda).

Clase Cliente DAO

  class ClienteDao : ConexionBD
    {
        SqlDataReader LeerFilas;
        SqlCommand Comando = new SqlCommand();
        //METODOS CRUD
        public List<ClientesDto> VerRegistros(string Condicion)
        {
            Comando.Connection = Conexion;
            Comando.CommandText = "VerRegistros";
            Comando.CommandType = CommandType.StoredProcedure;
            Comando.Parameters.AddWithValue("@Condicion", Condicion);
            Conexion.Open();
            LeerFilas = Comando.ExecuteReader();
            List<ClientesDto> ListaGenerica = new List<ClientesDto>();
            while (LeerFilas.Read())
            {
                ListaGenerica.Add(new ClientesDto
                {
                    ID = LeerFilas.GetInt32 (0),
                    Nombre = LeerFilas.GetString(1),
                    Apellido = LeerFilas.GetString(2),
                    Direccion = LeerFilas.GetString(3),
                    Ciudad = LeerFilas.GetString(4),
                    Email = LeerFilas.GetString(5),
                    Telefono = LeerFilas.GetString(6),
                    Ocupacion = LeerFilas.GetString(7),
                });
            }
            LeerFilas.Close();
            Conexion.Close();
            return ListaGenerica;
        }

        public void Insert() { }
        public void Edit() { }
        public void Delete() { }
    }

Crear Formulario Clientes

  • Agregamos una nueva carpeta de nombre IU para todos los formularios o interfaces de usuario de nuestra aplicación.
  • En la carpeta, agregamos un nuevo formulario para la entidad Cliente.
  • Agregamos un DatagridView para mostrar los datos, un TextBox para filtrar los datos al momento de escribir en ella, agregamos un botón solo para realizar una búsqueda simple.

Codificar Formulario Clientes

Una vez diseñado el formulario, es hora de codificarlo.

  • Doble click en el formulario para crear el evento load.
  • Importamos la carpeta DAO.
  • Creamos un método para mostrar y buscar los registros de clientes, en ello, instanciamos a la clase ClienteDAO e invocamos el método de ver registros y asignamos el resultado al datagridview.
  • Finalmente invocamos el método desde el evento load para mostrar todos los datos, y desde el botón buscar o el evento textChanged del textbox para la búsqueda o filtro de datos, depende de tu preferencia.

Clase FormClientes

   private void FormClientes_Load(object sender, EventArgs e)
    {
        //MOSTRAR TODO
        VerRegistros("");
    }
    //METOOD VER REGISTROS
    private void VerRegistros(string condicion)
    {
        ClienteDao DAO = new ClienteDao();
        dataGridView1.DataSource = DAO.VerRegistros(condicion);
    }
    //BUSCAR 
    private void btnBuscar_Click(object sender, EventArgs e)
    {
        VerRegistros(txtBuscar.Text);
    }
    //FILTRAR
    private void txtBuscar_TextChanged(object sender, EventArgs e)
    {
        VerRegistros(txtBuscar.Text);
    }
}

Aplicar Patrón Singleton

Ahora realizaremos un ejemplo del patrón singleton, puedes aplicar en este patrón en caso que necesites crear una instancia única de algún objeto/clase. En este caso, deseo que los formulario de mi aplicación se abran una sola vez.

  • El constructor de la clase debe ser privado.
  • Declaramos una variable estática del mismo tipo de la clase.
  • Creamos un método para obtener la instancia.
  • En este caso, estoy aplicando en patrón singleton a un formulario, entonces será necesario reiniciar a su estado original (instancia =null).

Clase FormClientes

    //PATRON SINGLETON
    private FormClientes()
    {
        InitializeComponent();
    }
    private static FormClientes Instancia = null;

    public static FormClientes ObtenerInstancia()
    {
        if (Instancia == null)
        {
            Instancia = new FormClientes();
            Instancia.FormClosed += new FormClosedEventHandler(reset);//SOLO PARA FORMULARIOS
        }        

        return Instancia;
    }
    //FIN SINGLETON        
    private static void reset(object sender, FormClosedEventArgs e)//SOLO PARA FORMULARIOS
    {
        Instancia = null;      
    }
  • Para invocar las clases de este tipo, lo hacemos de la siguiente manera:
 FormClientes frm = FormClientes.ObtenerInstancia();

Descargas

Los comentarios están cerrados.