Bases para la programación de una webapp en .NET con MVC, Entity Framework, LINQ y el patrón de diseño DAO.
Introducción.
Bases para programar una webapp con .NET: curso corto para implementar una aplicación que use un navegador como interfaz de usuario y que esté estructurada en capas para facilitar su mantenimiento.
Temario: Paradigmas en el desarrollo de aplicaciones. Patrón de Arquitectura MVC. Patrones de Diseño. Patrón DAO. Uso de Entity Framework para bases de datos SQL. Uso de bases de datos NoSQL. Uso de LINQ como lenguaje para la consulta de datos.
Descarga el proyecto para Visual Studio en:
Proyecto 1: Sin usar el patrón de diseño DAO: https://www.dropbox.com/s/l01qb9ev1lek7u4/CombosCascada.zip?dl=1
Proyecto 2: Usando el patrón de diseño DAO: https://www.dropbox.com/s/24r4or3kbsgouqa/CombosCascadaDAO.zip?dl=1
Puedes ir al índice de contenidos para ver todos los Minicursos.
Qué vamos a hacer
Vamos a crear una webapp en la que un usuario, desde un navegador, elige un país de una lista desplegable. Como resultado se muestran las ciudades de ese país en otra lista desplegable. Después, el usuario elige una ciudad y ésta es mostrada en una casilla de texto.
Denominaremos a esta aplicación Combos en Cascada. Estará estructurada en la parte del servidor y la parte del cliente:
- En la parte del servidor o back-end estará la webapp propiamente dicha que usará .NET Framework 4.x. Usará una base de datos, recibirá comandos desde la parte del cliente y enviará datos en formato HTML hacia la parte del cliente.
- En la parte del cliente o front-end estará el HTML enviado desde la parte del servidor que será usado mediante un navegador o browser cualquiera como IE, Edge, Chrome, Firefox... El cliente enviará comandos al servidor.
Nuestra webapp tendrá este aspecto:
A su vez, la aplicación en la parte del servidor estará estructurada en 3 capas:
- Una capa que tendrá el cometido de manejar una base de datos.
- Una capa que tendrá el cometido de crear el HTML que será enviado al navegador del usuario.
- Una capa que tendrá el cometido de ejecutar las órdenes del usuario usando las dos anteriores capas.
Qué técnicas usaremos
Nota: Si ya conoces el uso de patrones en programación OOP y qué son los frameworks ORM como Entity Framework, puedes saltarte esta introducción e ir directamente a la Entrega 2 en la que mostraremos cómo configurar Windows para poder usar Visual Studio. Si ya tienes Windows con Visual Studio configurado para crear webapps con MVC, puedes saltarte también la Entrega 2 e ir directamente a la Entrega 3, en la que ya entramos en la implementación de la webapp.
Para conseguir que la webapp tenga esas funcionalidades usaremos el Framework .NET 4.x y las siguientes técnicas:
- Patrón Modelo-Vista-Controlador, abreviado MVC: patrón de arquitectura de software que separa una aplicación web en 3 capas de responsabilidad, evitando crear una webapp monolítica y difícil de mantener.
- Object Relational Mapping, abreviado ORM: técnica que facilita el diseño y creación de bases de datos relacionales permitiendo programar un código que es independiente de la tecnología de base de datos usada.
- Language-Integrated Query, abreviado LINQ: es un lenguaje de consulta o manipulación de datos que es independiente de la tecnología de base de datos usada.
- Unobstrusive AJAX, abreviado UAJAX: es una librería .js que facilita el uso de AJAX en el navegador de una aplicación web. No es una tecnología diferente de AJAX, simplemente facilita el uso de AJAX, igual que hacen muchas otras librerías .js.
- Patrón Data Access Object, abreviado DAO: haremos una primera versión de la aplicación que tendrá una serie de limitaciones que deberemos corregir. Dicha corrección la haremos usando el patrón de diseño DAO. Esta segunda versión de la aplicación podrá usar tecnologías de bases de datos SQL y NoSQL. El patrón DAO es un patrón de diseño universal y no debe confundirse con la librería DAO propietaria de Microsoft.
Los lenguajes de programación usados serán VB (Visual Basic) y C# (C Sharp). Puedes escoger el que más te guste. Además, nuestra webapp será muy sencilla. De hecho, solamente la usaremos como apoyo para explicar las técnicas que hemos descrito: MVC + ORM + LINQ + UAJAX + DAO.
Entregas de este Minicurso
La manera de exponer nuestra webapp Combos en Cascada que seguiremos en este Minicurso será la siguiente:
- Explicar las técnicas y patrones que hemos mencionado.
- Configurar Windows y Visual Studio.
- Comenzar a programar la webapp creando el back-end (la parte de la webapp que está en el servidor) con "MVC". Crear el esquema de la Base de Datos SQL con el ORM "Entity Framework" y añadirle los datos.
- Enviar los datos de dicha base de datos en formato HTML al front-end (la parte del cliente) usando el lenguaje para creación de páginas web denominado "Web Pages" o "Razor". Este lenguaje combina HTML con código de programación Visual Basic ó C#.
- Crear la página web con los Combos en Cascada propiamente dicha, usando "UAJAX" con "JQuery" para intercambiar los datos entre el servidor y el cliente.
- Modificar el Proyecto para que funcione con otros motores de Bases de Datos Relacionales.
- Necesidad de refactorizar el proyecto con el patrón "DAO" para usar Bases de Datos no Relacionales. Esto nos ocupará varias entregas porque tendremos que explicar los diversos patrones de diseño que están incluidos dentro del patrón DAO.
Empezamos ahora la Entrega 1, donde explicaremos todas estas técnicas que vamos a usar. En la Entrega 2 veremos cómo configurar Windows 7 o Windows 10 y Visual Studio para usar estas técnicas. La webapp propiamente dicha la comenzaremos a crear en la Entrega 3.
Descripción de las técnicas que usaremos
- Lightweight GUI y Look and Feel (= GUI ligera con Identidad Visual): Un componente de una aplicación es ligero o lightweight si solamente es útil para otros componentes. Se dice que una GUI mantiene el look and feel o Identidad Visual si su aspecto y manera de ser usado es el mismo en cualquier dispositivo y plataforma.
Una webapp usa un browser o navegador que actúa como GUI ligera y que permite mantener el look-and-feel en cualquier dispositivo. La única limitación es que un navegador no puede interactuar con la computadora de la parte del cliente, solamente con la parte del servidor.
- Loose Coupling o Decoupling (= Acoplamiento Débil o Desacoplamiento): Si cada vez que se modifica un componente de una aplicación informática hay que re-testear la aplicación completa, se dice que la aplicación es "monolítica" o bien que las partes que "componen la aplicación están muy acopladas". Existe el acoplamiento lógico que obliga a re-testear la aplicación completa cuando se modifica alguna parte del código, y el acoplamiento físico que impide que la aplicación pueda distribuirse en varias computadoras. Para evitarlos y conseguir "loose coupling" los expertos recomiendan respectivamente seguir unos Patrones Arquitecturales del Software y del Hardware.
- MVC (= Modelo-Vista-Controlador): Es un Patrón Arquitectural del Software recomendado para crear una webapp, si bien no se usa en aplicaciones de escritorio (desktop app). El programador estructura la webapp en tres capas desacopladas: Capa Modelo, donde codifica la Base de Datos; Capa Vista, donde codifica el Output desde la aplicación hacia el usuario, y Capa Controlador, donde codifica las acciones a seguir según el Input del usuario hacia la aplicación (estas acciones a seguir se denominan "plumbing"). Por "Capa" entendemos "Uno o varios archivos de código que realizan exclusivamente la tarea encomendada a dicha capa según el patrón MVC".
Nosotros usaremos el framework gratuito "ASP.NET MVC" de Microsoft que proporciona al programador de .NET clases especiales para crear de manera fácil esas Capas y para que esas Capas estén desacopladas.
- "ASP.NET MVC", abreviado MVC, es un framework gratuito de Microsoft que permite al programador diseñar una webapp estructurada en las tres capas desacopladas que recomienda el patrón MVC, usando exclusivamente OOP. Las Clases ASP.NET, de las que ya dispone por defecto .NET Framework, sirven para trabajar con HTML creando una aplicación monolítica. Pero usando MVC, el programador puede usar el paradigma OOP para crear una aplicación no monolítica. En realidad, MVC traduce ese código OOP hacia código de ASP.NET y se dice entonces que MVC "envuelve" a ASP.NET para facilitar su uso (MVC es un "wrapper" de ASP.NET). Hay que decir que se tiene previsto que IIS sea sustituido por el propio ASP.NET como servicio web.
Existen varios paradigmas de Desarrollo de Aplicaciones. Uno de ellos es el denominado Desarrollo Ágil, que recomienda entregar por trozos una aplicación al consumidor de la misma. A cada trozo se lo llama "Iteración" y se usa la palabra "extensible" para indicar que un software se puede ir entregando por "iteraciones" sin necesidad de re-testear la aplicación completa en cada iteración. Si se siguen las recomendaciones de los expertos, se puede entregar en cada iteración un código que esté desacoplado del código de las anteriores y siguientes iteraciones. Una de estas recomendaciones es precisamente usar el patrón MVC. Para aplicaciones de escritorio (desktop apps) se sigue otro patrón denominado "multicapa", que puede tener una, dos, tres, cuatro... capas. Nada impide también usar este patrón también para webapps.
Existen más paradigmas de desarrollo de aplicaciones, como TDD (Test-Driven Development) en el cual, el criterio para decidir cuáles serán las partes en que el programador estructurará la aplicación, viene dado porque cada parte sea testeable unitariamente en base a todos y cada uno de los casos de uso posibles que ha indicado el consumidor de la aplicación. También existe DDD (Domain-Driven Design) que recomienda centrar la aplicación en las Entidades o Clases del Dominio (=clases que representan elementos de la vida real) en vez de centrar la aplicación en el uso de ciertas tecnologías o frameworks. En la práctica se usa una mezcla de todos estos paradigmas o bien, sencillamente, se usa el paradigma de desarrollo que mejor se adapte a cada situación, incluyendo el "Waterfall Design Process" de toda la vida, es decir, entregar la aplicación cuando esté terminada del todo.
En lo que sí que están de acuerdo y tienen en común todos estos paradigmas de desarrollo de aplicaciones, es que las aplicaciones deben estar estructuradas en diversas capas, teniendo cada capa un cometido específico, y estando cada capa desacoplada de las demás capas, de forma que cualquier cambio en una capa no implique hacer cambios en las demás capas. Asimismo, sería ideal poder testear unitariamente cada componente de la aplicación, si bien esto último ya es más difícil porque "desacoplamiento" no implica "independencia total": las diversas capas han de poder intercambiar datos entre ellas.
Respecto a los Patrones Arquitecturales del Hardware, comentaremos el Patrón 3-Tier. Los patrones del hardware tienen como finalidad poder estructurar una aplicación entre varias computadoras:
Nota: todas las imágenes de este Minicurso se pueden ampliar con un clic si no se ven bien:
Clic en la imagen para ampliarla
Básicamente lo que se usa es empaquetar los datos en TCP/IP con lo que es lo mismo enviar los datos al localhost o a un host remoto. Si, en algún momento, el hardware de una sola computadora se queda pequeño y necesitamos más potencia, podemos "escalar horizontalmente" el hardware, que significa distribuirlo en varias computadoras. Si el software está bien diseñado habrá poco trabajo para escalar. Tocaremos este tema muy superficialmente.
- Patrones de Diseño: Para conseguir desacoplamiento lógico y físico, los expertos dan unos consejos que se han recopilado en lo que se llama "Patrones de Diseño" y que permiten al programador obtener una aplicación OOP desacoplada que tendrá estas ventajas: será testeable unitariamente, extensible y escalable. Se dice entonces que un software es "elástico". En general la palabra "extensible" se usa para el software, la palabra "escalable" para el hardware y la palabra "elástico" sería la unión de extensible y escalable. Se los suele llamar Patrones de Diseño "GoF" (Gang of Four) porque fueron recopilados por cuatro Diseñadores en 1994. Un Patrón de Diseño no está basado en la reutilización de clases OOP, sino en la reutilización de "estrategias" exitosamente usadas en situaciones concretas al implementar una aplicación informática. Nosotros usaremos un patrón muy sencillo denominado "Fachada" y otro más complejo denominado "DAO".
- ORM (= Object-Relational Mapping): Es una técnica para trabajar con Bases de Datos Relacionales que permite al programador trabajar siempre con Clases y Objetos siguiendo el paradigma OOP y así no tener que usar el paradigma de las Bases de Datos Relacionales. Las siglas ORM significan "Mapeo entre el paradigma OOP y el paradigma Relacional".
También permite al programador usar el mismo código OOP con varios motores de Bases de Datos, es decir, permite al programador crear un código desacoplado de la tecnología de base de datos que utilice la webapp.
Nosotros usaremos ORM en .NET con dos frameworks distintos: "ADO.NET Entity Framework 6" y "LINQ to Entities" ambos de Microsoft. El primero proporciona al programador de .NET clases especiales para crear bases de datos con un código OOP independiente de la tecnología usada. El segundo proporciona al programador de .NET clases especiales para consultar y modificar bases de datos con un código OOP independiente de la tecnología usada.
"ADO.NET Entity Framework 6 (EF6)" es un framework gratuito de Microsoft que permite al programador diseñar el esquema de una Base de Datos usando exclusivamente OOP. Las Clases ADO.NET, de las que ya dispone por defecto .NET Framework, sirven para trabajar con Bases de Datos Relacionales usando el paradigma Relacional. Pero usando EF, el programador puede usar el paradigma OOP para crear la Base de Datos Relacional. En realidad, EF traduce ese código OOP hacia código relacional de ADO.NET y se dice entonces que EF "envuelve" a ADO.NET para facilitar su uso (EF es un "wrapper" de ADO.NET). EF permite tanto diseñar el esquema de una BDR (Base de Datos Relacional) nueva como obtener el esquema de una BDR existente. Además, hay la posibilidad de que ese esquema sea en forma gráfica o en código OOP. Esto da lugar a cuatro sintaxis de EF:
Nosotros usaremos "Code First to New Database", es decir, el programador diseña el esquema de la BD tecleando código Visual Basic ó C# a partir del cual EF crea la BD externa real.
Nota: para acostumbrarnos a usar EF, es interesante conocer un poco la "jerga" que se usa cuando se habla de este framework: el diseñador de una aplicación OOP cualquiera, tiene que "elicitar" (=descubrir) las "Clases del Dominio" que es como se denomina a las clases OOP que representan algo de la vida real, como un "Estudiante". En una aplicación que use el paradigma Relacional, "Estudiante" sería un registro de una tabla que se denominaría "Estudiantes". Pero en una aplicación OOP que use el paradigma ORM, "Estudiante" será una clase OOP. Esta clase la denominaremos "POCO" en EF. POCO significa "clase OOP de .NET que no hereda de otra clase y que sus propiedades son tipos primitivos". Por tanto, la clase del dominio "Estudiante" en EF se diría "el POCO de Estudiante". Por otro lado, en EF, la Base de Datos en formato OOP es denominada EDM ("Entity Data Model") o también Contexto ("Context"). EF proporciona una clase denominada "DbContext" que es la que permite crear estos objetos EDM. EF también tiene otra clase denominada "DbSet" que permite crear las tablas del EDM.
Resumiendo: EDM o Contexto o DbContext se refiere a la Base de Datos completa. DbSet se refiere a una tabla. POCO se refiere un registro de una tabla. Y, por último, cada propiedad miembro de esa clase POCO se refiere a un campo de la tabla.
Hay que aclarar que la versión siguiente a EF6 se denomina "EF Core". EF Core está diseñado para ser usado con .NET Core y con ASP.NET Core, que son frameworks que se pueden usar en cualquier dispositivo, como tablets o smartphones, e incluso en Linux y Mac OSX. Pero en el momento de crear este Minicurso, EF Core está todavía en desarrollo, por lo que conviene seguir usando EF6. Además, EF6 seguirá teniendo mantenimiento y mejoras.
- "LINQ (Language-Integrated Query) to Entities", "LINQ to Entities" ya viene incorporado en .NET y por tanto no tendremos que instalar nada. Es una técnica ORM que permite consultar y modificar una Base de Datos Relacional sin usar SQL y, por tanto, una misma consulta creada con LINQ puede ser usada con cualquier motor de base de datos. Lo que hace es consultar a los objetos de Entity Framework que hemos descrito antes. No consulta a la base de datos.
Es importante aclarar que LINQ es, en realidad, un lenguaje de consulta de datos "agnóstico", es decir, que su sintaxis es la misma sea cual sea la manera en que estén almacenados los datos. Con LINQ se puede consultar o modificar archivos XML, bases de datos SQL, bases de datos NoSQL o datos almacenados en objetos en la RAM como listas o arrays. Por tanto, si hablamos solamente de LINQ, estamos hablando de un lenguaje de consulta de datos "agnóstico" que ya viene incorporado en .NET. LINQ propiamente dicho no es un ORM.
Pero si hablamos de "LINQ to Entities" entonces es cuando estamos hablando de una implementación especial de LINQ denominada "LINQ to Entities" que sí que es un ORM porque traduce las consultas LINQ (objetos) hacia SQL (relacional) de manera transparente al programador.
El programador puede escribir consultas a bases de datos con LINQ usando dos sintaxis diferentes: "LINQ method syntax" o "sintaxis encadenada" o "inline" que usa métodos OOP encadenados con puntos, y "LINQ query syntax", que es una sintaxis denominada "sintaxis declarativa", que es muy similar al lenguaje SQL. Nosotros usaremos "LINQ query syntax" porque, al ser tan parecida a SQL, resultará más familiar y cómoda, pero añadiremos a cada consulta su versión en "method syntax" como curiosidad.
En .NET, el lenguaje LINQ es proporcionado por la dll "System.Core.dll" que ya viene incluida en el framework .NET. LINQ no es el único lenguaje de consulta orientado a objetos. Existen otros como ".NET Persistence API" que es igual que el lenguaje de consulta JPA, usado en Java. Nosotros usaremos LINQ porque es el estándar para .NET. En este Minicurso veremos solamente una introducción a LINQ y no entraremos a fondo.
- Scaffolding (plantillas dinámicas de código): Con MVC se puede generar automáticamente Vistas (=el código HTML enviado al usuario) que muestren en un grid los datos de la Base de Datos y que, opcionalmente, dispongan de los cuatro métodos CRUD (alta, consulta, modificación y baja de registros). Esto se denomina "Scaffolding". En MVC está limitada a una sola tabla por Vista para versiones MVC-5 y anteriores.
- ORM Lazy Loading: Todos los ORM integran la técnica "lazy loading". Esta técnica es un Patrón de Diseño GoF. Un programador puede crear una consulta contra el EDM que sea una join que obtenga los datos de una tabla de la BD y que obtenga también todos los datos relacionados de las tablas relacionadas. Pero la técnica "lazy loading" hace que los datos de las tablas relacionadas se carguen solamente cuando el usuario los necesite. Además, la consulta contra la BD no se ejecutará cuando aparezca escrita en el código VB ó C# sino cuando se necesiten los datos. Con esta técnica, ORM consigue disminuir los accesos a la Base de Datos.
- ORM Proxy: La técnica Lazy Loading requiere que los datos de las tablas relacionadas estén disponibles solamente cuando se necesiten. Para ello Entity Framework usar el patrón "Proxy" (=representante) para instanciar una representación de una Entidad POCO, en vez de instanciar la Entidad real. "Proxy" es también un patrón GoF.
En resumen, EF usará los patrones "lazy loading" y "proxy" de una manera transparente al programador, lo que le simplificará mucho la creación de aplicaciones, pero el programador debe conocer la existencia de estos dos patrones en un ORM ya que en determinadas circunstancias conviene no usarlos (por ejemplo, cuando se serializan datos). Por ello, EF permite activar o desactivar el uso de "lazy loading" y el uso de "proxies". Esto lo veremos más adelante.
- DAO (=Data Access Object): cuando hayamos acabado nuestra webapp, veremos que ésta tendrá ciertas limitaciones e imperfecciones, especialmente si queremos añadir a la webapp el uso de bases de datos NoSQL o de Archivos Planos (JSON, XML, CSV...). Ello nos llevará a refactorizar (=reescribir) la aplicación entera usando el patrón de diseño DAO. El patrón DAO es en realidad el resultado de la integración de varios patrones de diseño, como el patrón Fachada, el patrón Factoría, el patrón Singleton o el patrón Inversión de Control. Explicaremos todos ellos.
Explicar el patrón DAO es un poco largo pero el resultado será una nueva versión de la webapp muy limpia, mantenible y "agradable" desde el punto de vista de un desarrollador informático.
Resumiendo: existen varios Paradigmas de Desarrollo de aplicaciones empresariales como Ágil, TDD, DDD, Waterfall (=Cascada) y más. Todos estos paradigmas tienen en común que es mejor no crear aplicaciones monolíticas, sino que estén estructuradas en capas desacopladas. Para desacoplar esas capas se usan diversos Patrones Arquitecturales como MVC, N-Tier y más. Estos Patrones Arquitecturales están pensados tanto para desacoplar el software en capas (=layers) como para desacoplar el hardware en gradas o niveles (=tiers). Esos Paradigmas de Desarrollo y esos Patrones Arquitecturales están basados en Patrones de Diseño OOP GoF: Proxy, Lazy Loading, Fachada, DAO y otros que veremos como Singleton, Inversión de Control y más, y son presentados en forma de Tecnologías o Frameworks.
Nota: Hay que aclarar que no en todos los entornos se usan estos patrones. En ciertos casos, como la implementación de un driver, lo que interesa es que el driver funcione dentro del Sistema Operativo con la máxima rapidez posible. Dado que el uso de todos estos patrones y frameworks resta rapidez a las aplicaciones, en esos casos es mejor una aplicación monolítica muy optimizada para la velocidad, aunque después su mantenimiento sea más duro y trabajoso. En cambio, en aplicaciones de escritorio o web de ámbito empresarial, lo que nos interesa es usar estos patrones y frameworks para que sean aplicaciones muy fácilmente mantenibles y ampliables, aunque sea a costa de disminuir la rapidez de la aplicación. Esto último es lo que haremos nosotros en nuestra aplicación Combos en Cascada.
Con esto acabamos la introducción teórica a las técnicas que usaremos para nuestra webapp. En la siguiente Entrega seguiremos con una parte más práctica pero aún no empezaremos a implementar la webapp, sino que veremos cómo configurar nuestra computadora para poder usar Visual Studio para implementar una webapp con todas las tecnologías explicadas.
Todo esto explicado parece difícil, pero se aclarará cuando veamos la implementación de la webapp a partir de la Entrega 3.
Basta de teoría y comencemos con los temas prácticos.
0 comentarios:
Publicar un comentario