Desarrollo en Capas con .Net

19,124 views
18,936 views

Published on

Que implica desarrollar software con un Modelo de Negocio OO? - Capas con .NET+NHibernate - Desarrollo de componentes

Published in: Technology
2 Comments
12 Likes
Statistics
Notes
No Downloads
Views
Total views
19,124
On SlideShare
0
From Embeds
0
Number of Embeds
10,343
Actions
Shares
0
Downloads
0
Comments
2
Likes
12
Embeds 0
No embeds

No notes for slide
  • Desarrollo en Capas con .Net

    1. 1. Desarrollo en Capas con “mejorando la productividad y reutilizaciòn” Disertante: Jorge Ercoli (Analista de Sistemas) Jornadas sobre Desarrollo de Software UTN Centro de Estudios Mar del Plata - Argentina
    2. 2. Temario <ul><li>Componentes de software </li></ul><ul><li>La Lògica del Negocio </li></ul><ul><li>Arquitectura sin capa de negocio </li></ul><ul><li>Arquitectura de 3 Capas lògicas. Responsabilidad de los componentes de cada capa. </li></ul><ul><li>Capa de Negocio. Ventajas. Patrones: Transaction Script y Domain Model </li></ul><ul><li>Capa de Acceso a Datos. Persistencia de objetos de negocio. ORMs, ventajas, patrones: ActiveRecord y DataMapper </li></ul><ul><li>NHibernate: arquitectura, proceso de desarrollo, uso. </li></ul><ul><li>BREAK (30 minutos) </li></ul><ul><li>Desarrollo de software aplicando 3 capas, “ConferenciaWeb” sitio de ejemplo usando AspNet 2, C# y Nhibernate </li></ul><ul><li>Comprendiendo el còdigo de cada componente: </li></ul><ul><ul><li>Presentaciòn (Asp Net pages) </li></ul></ul><ul><ul><li>Procesos de Negocio (Clases controladoras de CU) </li></ul></ul><ul><ul><li>Objetos de Negocio (Clases que representan las Entidades) </li></ul></ul><ul><ul><li>Acceso a Datos (DAOs de los objetos de Negocio) </li></ul></ul>
    3. 3. <ul><li>“ Toda la arquitectura es diseño, pero no todo el diseño es arquitectura. </li></ul><ul><li>La arquitectura representa las decisiones de diseño significativas que le dan forma a un sistema, donde lo significativo puede ser medido por el costo del cambio .” </li></ul><ul><li>Grady Booch </li></ul>
    4. 4. Componentes de Software <ul><li>Componentes ?? </li></ul><ul><li>“ E s una pieza de software que realiza una función bien definida, y posee una interfaz bien definida” </li></ul><ul><li>“ Bloques de construcciòn fìsicos del sistema” </li></ul>* En .NET son los “assemblies” (ensamblados), los cuales pueden ser exe ò dll.
    5. 5. Beneficios de trabajar con componentes <ul><li>La división en componentes reduce la complejidad , permite la reutilización y acelera el proceso de ensamblaje de software. (plug-in) </li></ul><ul><li>Los creadores de componentes pueden especializarse creando objetos cada vez mas complejos y de mayor calidad . </li></ul><ul><li>La interoperabilidad entre componentes de distintos fabricantes aumenta la competencia , reduce los costos y facilita la construcción de estandares </li></ul><ul><li>Los costos de mantenimiento del software se reducen. </li></ul>
    6. 6. Lògica de Negocio <ul><li>“ Procesos y reglas del dominio del negocio, obtenidos en la fase de Análisis del Sistema” </li></ul><ul><li>Ejemplo para sistema de Gestión de Conferencias </li></ul><ul><li>“ Inscripciòn de un Oyente a una Conferencia” </li></ul><ul><li>“ No inscribir nuevos oyentes si se excediò la capacidad del Salon” </li></ul><ul><li>“ Consultar las Conferencias que poseen vacantes” </li></ul><ul><li>“ Registrar altas de nuevos Oyentes” </li></ul><ul><li>“ Permitir el cambio de Salòn de una Conferencia sòlo cuando la cantidad de inscriptos no supere su capacidad” </li></ul>
    7. 7. Arquitectura sin Capa de Negocio Presentaciòn Acceso a Datos InscribirClick( ) { conf_Id=ComboConferencia.SelectedValue; oye_Id=LabelOyenteId; dtOyeInsc= sqlExec(“sele * from conf_oye where…”); if (dtOyeInsc.Count()=0) // Oyente inscripto?? Inscriptos=sqlExec(“sele count(*) from conf_oye…”); dtSalon= sqlExec(“sele * from Salon where Id=…”); if (dtSalon(0).Capacidad – Inscriptos > 0) sqlExec(“Insert into conf_oye … values …”); else Mostrar(“No Hay Vacantes !!”); else Mostrar(“Oyente ya inscripto !!”); }
    8. 8. Arquitectura con Capa de Negocio InscribirClick( ) { conf_Id=ComboConferencia.SelectedValue; oye_Id=LabelOyenteId; ProcesoInscrip i=new ProcesoInscrip(); try { i.Inscribir (conf_Id, oye_Id); } catch (Excepcion ex) } Negocio Presentaciòn Acceso a Datos
    9. 9. <ul><li>Veamos la aplicación sin capa de negocio: </li></ul>ConferenciaWeb 2 capas ( DataSets Tipados ) Jorge Ercoli (http://metodologiasdesistemas.blogspot.com)
    10. 10. 3 Capas Lògicas Presentaciòn Negocio Acceso a Datos BD <ul><li>Permitir el ingreso de datos del Usuario </li></ul><ul><li>Mostrar informaciòn en la IU </li></ul><ul><li>Capturar eventos de la IU </li></ul><ul><li>Validar el ingreso de datos </li></ul><ul><li>Llama mètodos de objs. de “Negocio” </li></ul><ul><li>Da forma al modelo de negocio </li></ul><ul><ul><li>Servicios basados en CU </li></ul></ul><ul><ul><li>Objetos de Negocio </li></ul></ul><ul><li>Posee las reglas de Negocio </li></ul><ul><li>Procesa los datos de “Presentaciòn” </li></ul><ul><li>Llama mètodos de objs. de “Acc. a Datos” </li></ul><ul><li>Acceder a alguna fuente de datos almacenados </li></ul><ul><li>Permitir realizar operaciones CRUD s/datos </li></ul><ul><li>Mapear datos a objetos de negocio </li></ul>
    11. 11. Capa de Negocio <ul><li>Ventajas: </li></ul><ul><li>Simplicidad </li></ul><ul><li>Claridad </li></ul><ul><li>Reusabilidad </li></ul><ul><li>Independencia de la infraestructura tecnològica </li></ul>
    12. 12. Arquitectura “No Intrusiva” (agnóstica) para la Capa de Negocio <ul><li>Mantener separada la lògica de negocio de las capas màs dependientes de las tecnologìas informàticas ( Presentaciòn : WindowsForms, Consolas, Mobile, WebPages – Acceso a datos : Bases de datos relacionales, BDOO, LINQ, Nhibernate, ActiveRecord, etc) </li></ul>Jorge Ercoli (http://metodologiasdesistemas.blogspot.com)
    13. 13. Patrones para la Capa de Negocio <ul><li>Transaction Script </li></ul><ul><ul><li>Basado en Procesos de Negocio (CU) </li></ul></ul><ul><ul><li>Implementan la lógica de una determinada acción solicitada por la IU </li></ul></ul><ul><ul><li>( VerificarDisponibilidad, CalcularInterés, ProcesarOrden, BuscarArtsEnPromoción,...) </li></ul></ul><ul><ul><li>Orientado a aplicaciones simples con Lógica de Negocio de baja complejidad </li></ul></ul><ul><ul><li>No existen los Objetos de Negocio, se interactúa con las Tablas de la BDR </li></ul></ul><ul><ul><li>No se oculta el hecho de que existe una BDR que persiste la aplicaciòn </li></ul></ul><ul><ul><li>Gran cantidad de la lògica de negocio se traslada al motor de BDR (store procedures) </li></ul></ul><ul><ul><li>Propenso a mezclar lògica de negocio con persistencia (rompe encapsulamiento) </li></ul></ul>
    14. 14. Patrones para la Capa de Negocio (II) <ul><li>Domain Model </li></ul><ul><ul><li>Basado en una red interconectada de los Objetos de Negocio ( Conferencia, Oyente, Salon, Disertante,...) </li></ul></ul><ul><ul><li>Asociaciones entre objetos, manejo de colecciones </li></ul></ul><ul><ul><li>Comportamiento encapsulado en el objeto, de acuerdo a sus Responsabilidades </li></ul></ul><ul><ul><ul><li>Int cant_Inscriptos=conferencia.CuantosInscriptos(); </li></ul></ul></ul><ul><ul><ul><li>List<Oyente> OyentesInsc=conferencia.DameInscriptos(); </li></ul></ul></ul><ul><ul><ul><li>If (Conferencia.HayVacantes()); </li></ul></ul></ul><ul><ul><li>Permite el aislamiento de sus Capas superiores e inferiores, buen encapsulamiento que permite la creaciòn de Componentes. </li></ul></ul><ul><ul><li>Se debe solucionar el salto (gap) entre el modelo de objetos y la BDR subyacente (“impedance mismatch”) </li></ul></ul>
    15. 15. Patrones para la Capa de Negocio (III) <ul><li>RESUMIENDO: </li></ul><ul><li>En TS no hacemos un diseño OO, simplemente escribimos métodos por c/solicitud de la IU y los encapsulamos en 1 ó + clases. </li></ul><ul><li>En DM diseñamos una aplicación OO donde podemos aplicar todo tipo de asociaciones entre objetos. </li></ul>
    16. 16. Acceso a datos - Persistencia <ul><li>Como solucionamos el “gap objeto-relacional”? </li></ul><ul><li>FrameWork ORM (object-relational mapping) </li></ul><ul><li>Para .NET: </li></ul><ul><li>NHibernate </li></ul><ul><li>ActiveRecord (Castle) </li></ul><ul><li>Linq (sòlo .NET 3) </li></ul><ul><li>Cooperator (Arg.) </li></ul>
    17. 17. Ventajas de usar un ORM <ul><li>Trabajar con las clases diseñadas en el modelo del dominio </li></ul><ul><li>No trabajar con filas de tablas (nada de DataRows ó RecordSets ó ResultSets) </li></ul><ul><li>Código OO limpio, que permite el uso de herencia, polimorfismo, composiciòn en nuestras clases de negocio </li></ul><ul><li>Permite crear, modificar, recuperar y borrar objetos persistentes. Al recuperarlos nos permite navegar por las asociaciones entre objs. y luego actualizarlos al finalizar una transacción. </li></ul><ul><li>Permite elegir la BD relacional subyacente con la que querramos interactuar (SqlServer-PostGre-MySql-DB2, Oracle,...) </li></ul><ul><li>Genera automáticamente el cód. SQL usando una definiciòn del mapeo objeto-relacional (XML mapping); ò el còd. de las clases a partir del ddl de la BDR. </li></ul>
    18. 18. Patrones para persistir objetos <ul><li>Active Record: </li></ul><ul><li>Propone tener los métodos que me brindan la persistencia en el mismo objeto de negocio, heredando de una clase Base que posee las operaciones CRUD. </li></ul><ul><li>Normalmente las instrucciones del mapeo atributo del objeto-campo de la tabla en la definición del objeto de negocio. </li></ul><ul><li>Data Mapper: </li></ul><ul><li>Propone que nuestros objetos de negocio sean POCO (ó POJO en Java), o sea que no tengan nada de código que los acople a una tecnología dada de persistencia, ya que no es su función manejarla. </li></ul><ul><li>Normalmente se maneja la persistencia a través de una clase administradora de la misma (Session ò DataContext). Esta clase es la que se encarga de hacer las operaciones CRUD a la BDR. </li></ul>
    19. 19. Active Record
    20. 20. Data Mapper
    21. 21. Data Mapper (II) <ul><li>Como logramos aislar en su propia capa a las funciones del DataMapper, y asi lograr mayor independencia tecnològica? </li></ul>Martin Fowler Patròn DAO (Data Access Object)
    22. 22. DAO - Ejemplo
    23. 23. Ejemplo de ORM: NHibernate Arquitectura
    24. 24. NHibernate (II) – Proceso de desarrollo <ul><li>1. Crear la clase que necesita ser persistida </li></ul><ul><li>2. Crear la tabla para persistir la clase </li></ul><ul><li>3. Crear un archivo de mapeo para que NHibernate sepa como persistir las propiedades de la clase </li></ul><ul><li>4. Crear un archivo de configuración para que NHibernate sepa como conectarse a su BD. </li></ul><ul><li>5. Usar la API del NHibernate </li></ul>
    25. 25. NH - Pasos 1 y 2 Clases del Dominio (objs. de negocio) Tablas para persistir objetos
    26. 26. NH – Paso 3 <?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?> <hibernate-mapping xmlns=&quot;urn:nhibernate-mapping-2.0&quot; default-access=&quot;property&quot;> <class name=&quot;TPVBO.Venta, TPVBO&quot; table=&quot;Venta&quot; > <id name=&quot;VentaID&quot; column=&quot;idVenta&quot; unsaved-value=&quot;0&quot;> <generator class=&quot;identity&quot; /> </id> <property name=&quot;Fecha&quot; type = &quot;DateTime&quot; /> <property name=&quot;Numero&quot; type = &quot;Int32&quot; /> <bag name=&quot;LineaVenta&quot; cascade=&quot;all&quot;> <key column=&quot;venta&quot;/> <one-to-many class=&quot;TPVBO.LineaVenta, TPVBO&quot;/> </bag> </class> </hibernate-mapping> ............... <class name=&quot;TPVBO.LineaVenta, TPVBO&quot; table=&quot;lineaventa&quot; > <id name=&quot;LineaVentaID&quot; column=“idLineaVta&quot; unsaved-value=&quot;0&quot;> <generator class=&quot;identity&quot; /> </id> <property name=&quot;Cantidad&quot; type = &quot;Int32&quot; /> <many-to-one name=“Producto&quot; class=&quot;TPVBO.Producto, TPVBO&quot; column=&quot;producto&quot; /> </class> </hibernate-mapping>
    27. 27. NH – Paso 4 <?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?> <configuration> <configSections> <section name=&quot;nhibernate&quot; type=&quot;System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&quot; /> </configSections> <nhibernate> <add key=&quot;hibernate.connection.provider&quot; value=&quot;NHibernate.Connection.DriverConnectionProvider&quot; /> <add key=&quot;hibernate.dialect&quot; value=&quot;NHibernate.Dialect.MySQLDialect&quot; /> <add key=&quot;hibernate.connection.driver_class&quot; value=&quot;NHibernate.Driver.MySqlDataDriver&quot; /> <add key=&quot;hibernate.connection.connection_string&quot; value=&quot;Server=localhost;Database=TpvHibernate;User ID=jorge;Password=jorge&quot; /> </nhibernate> </configuration> Generalmente en el app.config de la aplicación
    28. 28. NH - Paso 5, usemos el ORM!! 1.      Agregamos una referencia a NHibernate.dll (para usarlo en nuestra aplicación) 2.       Creamos un objeto de Configuración Configuration cfg = new Configuration(); 3.       Le decimos al Configuration sobre los tipos de objetos que vamos a persistir cfg.AddAssembly(“TPVBO&quot;); // En TPVBO.dll están mis class con mis class.hbm.xml .... 4.       Creamos una Fabrica de sesiones (1 X BD) y luego le pedimos una Session y comenzamos una transacción. ISessionFactory factory = cfg.BuildSessionFactory(); ISession session = factory.OpenSession(); ITransaction transaction = session.BeginTransaction(); 5.       Trabajamos con nuestros objetos Producto p=new Producto(); p.Codigo=“CA123”; p.Descripcion=“Camisa CA”; p.Precio=59.90; session.Save(p); 6.       Grabamos la transacción en la BD y cerramos la sesión. transaction.Commit(); session.Close();
    29. 29. NH – El objeto Session <ul><li>La Session en NHibernate: </li></ul><ul><li>Es el punto de contacto principal para trabajar con Nhibernate </li></ul><ul><li>Nuestros objetos se asocian a ella para poder realizar operaciones de persistencia (Save, Update, Delete, Load ó Get) </li></ul>
    30. 30. NH – Session (II) Con una session abierta  ISession session = factory.OpenSession(); <ul><li>Grabar ó actualizar </li></ul><ul><ul><li>p.precio = 62.45; </li></ul></ul><ul><ul><li>session.SaveOrUpdate(p); // hará un Insert si el ID=0, sino un Update con el ID corresp. al obj. </li></ul></ul><ul><ul><li>session.Flush(); // permite bajar todos los cambios a la BD (sin nec. de tener una transacción) </li></ul></ul><ul><li>Leer uno o mas objetos </li></ul><ul><ul><li>Producto p = session.Load( typeof(Producto),m_ID); // Busca el objeto Producto con ese m_ID </li></ul></ul><ul><ul><li>// Usamos el HQL, similar a SQL pero nombrando los atributos de la clase, NO campos de Tabla ! </li></ul></ul><ul><ul><li>ArrayList misProd = session.Find( “from Producto p where p.Precio > 50”); </li></ul></ul><ul><li>Borrar </li></ul><ul><ul><li>session.Delete(p); // borramos nuestro objeto p de tipo Producto </li></ul></ul><ul><ul><li>session.Flush(); </li></ul></ul>
    31. 31. NH – Manejo de colecciones // Creo una Venta Venta v=new Venta(); v.Fecha=hoy; v.Numero=22; // Creo 2 lineas de venta LineaVenta l1=new LineaVenta(); l1.Cantidad=10; l1.Producto=session.Load(typeof(Producto),155); LineaVenta l2=new LineaVenta(); l2.Cantidad=5; l2.Producto=session.Load(typeof(Producto),189); // agrego a la colección de lineas de venta de v, las 2 lineas creadas v.lineas.Add(l1); v.lineas.Add(l2); // grabo la venta a la session con sus 2 lineas (por tener el cascade=all ): En la BD se inserta una fila en // Venta y 2 en LineaVenta session.Save(v); session.Flush();
    32. 32. NH – manejo de transacciones try { session = factory.OpenSession(); transaction = session.BeginTransaction(); session.SaveOrUpdate(miObjetoNegocio); transaction.Commit(); } catch (Exception ex) { transaction.Rollback(); } finally { session.Close(); }
    33. 33. BREAK 30 minutos
    34. 34. Desarrollemos software en capas ConferenciaWeb Requisitos funcionales: <ul><li>Crear nuevas conferencias </li></ul><ul><li>Seleccionar el Salón para la Conferencia de una lista. </li></ul><ul><li>Seleccionar el Disertante que dictará la Conf. de una lista </li></ul><ul><li>Inscribir Oyentes a las Conferencias disponibles, controlando si </li></ul><ul><li>existen vacantes </li></ul><ul><li>Permitir buscar un Oyente por orden alfabético para inscribirlo </li></ul><ul><li>Permitir el alta de nuevos Oyentes </li></ul><ul><li>Mostrar las conferencias que se dictarán próximamente, en el Home </li></ul><ul><li>del sitio </li></ul>
    35. 35. ConferenciaWeb – Casos de Uso
    36. 36. ConferenciaWeb – Objetos de Negocio
    37. 37. ConferenciaWeb – Componentes
    38. 38. ConferenciaWeb – Componentes II
    39. 39. ConferenciaWeb Presentación llama Negocio
    40. 40. Negocio llama Acceso a Datos
    41. 41. <ul><li>Veamos la aplicación ejecutarse: </li></ul>ConferenciaWeb Jorge Ercoli (http://metodologiasdesistemas.blogspot.com)
    42. 42. Nuevo requerimiento <ul><li>Un mismo oyente no puede inscribirse en más de 2 conferencias </li></ul><ul><li>Donde lo implemento? : </li></ul><ul><li>En los Objs. de negocio (Conferencia y Oyente) </li></ul>
    43. 43. Que más deberíamos ver ? <ul><li>Implementación de “Servicios” en la capa de negocio, que permitan interactuar desde otros subsistemas (SOA, “web services”) </li></ul><ul><li>FrameWorks que me brinden posibilidad de AOP (facilita el desarrollo de servicios horizontales: logging, autorizaciones, transacciones, error check,..), SPRING.NET </li></ul><ul><li>Patrones de diseño : fábricas de objs., decoradores, estrategias, fachadas, proxys,... </li></ul>
    44. 44. Recursos <ul><li>Libros </li></ul><ul><ul><li>UML y PATRONES (Prentice Hall - Larman) </li></ul></ul><ul><ul><li>Programming dot NET components 2nd. Ed. (O´Reilly – Juval Lowy) </li></ul></ul><ul><ul><li>Head First Design Patterns (O´Reilly – Freeman & Freeman) </li></ul></ul><ul><ul><li>Applying Domain Driven Design and Patterns, con ejs. en C# y .NET (Jimmy Nilson) </li></ul></ul><ul><ul><li>Nhibernate in action (Manning – Kuate) </li></ul></ul>
    45. 45. Recursos II (sites) <ul><li>Nhibernate best practices with AspNet ( www.codeproject.com/KB/architecture/ NHibernateBestPractices .aspx ) </li></ul><ul><li>ITArchitect ( www. itarchitect .co.uk ) </li></ul><ul><li>Blog de Scott Guthrie , Project Leader .NET (http://weblogs.asp.net/scottgu/) </li></ul><ul><li>Mi Blog sobre Arquitecturas y Diseño OO (orientado a .NET...) (metodologiasdesistemas.blogspot.com ) </li></ul><ul><li>Spring.NET (www.springframework.net ) </li></ul>Jorge Ercoli (http://metodologiasdesistemas.blogspot.com)

    ×