<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.kartones.net/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>El framework de coco</title><link>http://kartones.net/blogs/coco/default.aspx</link><description>No te acostaras sin saber una o dos cosas mas ...</description><dc:language>en</dc:language><generator>CommunityServer 2007 SP2 (Build: 20611.960)</generator><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.kartones.net/ElFrameworkDeCoco" /><feedburner:info uri="elframeworkdecoco" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><title>La Capa de Presentación : El Patrón MVP</title><link>http://feeds.kartones.net/~r/ElFrameworkDeCoco/~3/gGJs8E8Q1OA/la-capa-de-presentaci-243-n-el-patr-243-n-mvp.aspx</link><pubDate>Sat, 19 Dec 2009 21:35:08 GMT</pubDate><guid isPermaLink="false">b86c0850-82e5-42ed-a9d8-bde9e8f94ec1:50614</guid><dc:creator>ccrego</dc:creator><slash:comments>0</slash:comments><comments>http://kartones.net/blogs/coco/archive/2009/12/19/la-capa-de-presentaci-243-n-el-patr-243-n-mvp.aspx#comments</comments><description>&lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;El patrón Modelo Vista Presentador (MVP) es un patrón derivado del patrón Modelo Vista Controlador (MVC) que nos ayuda a ofrecer una clara separación entre la vista, el modelo y el controlador.&lt;/font&gt;&lt;/p&gt;  &lt;p align="justify"&gt;La clave del patrón MVP es una estricta regulación de la interacción entre la vista y el controlador, aunque en el patrón MVP, al controlador se le conoce como presentador.&lt;/p&gt;  &lt;p align="justify"&gt;La vista y el modelo de datos son claramente separados a través de un contrato (interfaz) que expone la vista y al cual el presentador accede de modo polimórfico.&lt;/p&gt;  &lt;p align="justify"&gt;Resumiendo, podemos decir que el patrón MVP es una mejora del patrón MVC basado en tres características :&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;     &lt;div align="justify"&gt;La vista no conoce el modelo.&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;El presentador es independiente de la tecnología de interfaz de usuario.&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;La vista y el presentador es testeable puesto que esta basada en un contrato. &lt;/div&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p align="justify"&gt;Mediante el uso de un contrato en la vista, podemos testear la propia vista y el presentador de modo independiente :&lt;/p&gt;  &lt;p align="justify"&gt;&lt;a href="http://kartones.net/blogs/coco/patronMVP1_4A056FB9.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="patronMVP[1]" border="0" alt="patronMVP[1]" src="http://kartones.net/blogs/coco/patronMVP1_thumb_0D7CD542.png" width="535" height="192" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;font color="#ff8040"&gt;En aplicaciones web ASP.NET, las vistas se representan a través de formularios web, y en aplicaciones Windows a través de formularios Windows.&lt;/font&gt;&lt;/p&gt;  &lt;p align="justify"&gt;En la implementación de la vista, tenemos dos opciones :&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;     &lt;div align="justify"&gt;Una vista pasiva&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;Una vista activa&lt;/div&gt;   &lt;/li&gt; &lt;/ol&gt;  &lt;p align="justify"&gt;Si optamos por una vista pasiva, obtendremos un mayor grado de testeabilidad por que la lógica representada por el contrato se reducirá al mínimo, sin embargo aumentaremos la complejidad en el presentador.&lt;/p&gt;  &lt;p align="justify"&gt;Si optamos por una vista activa que contiene lógica como el enlace y el formateo de datos, necesitaremos implementar una funcionalidad extra que convertirá la vista en menos testeable.&lt;/p&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;El presentador es el componente encargado de “presentar” las acciones del usuario al sistema y obtener la respuesta del mismo.&lt;/font&gt;&lt;/p&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;El presentador se ubica entre la vista y el modelo, y actúa de la siguiente manera : &lt;/font&gt;&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;     &lt;div align="justify"&gt;&lt;font color="#ff8040"&gt;Recibe datos de la vista &lt;/font&gt;&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;&lt;font color="#ff8040"&gt;Convierte los datos de la vista en acciones que se ejecutan contra el sistema&lt;/font&gt;&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;&lt;font color="#ff8040"&gt;Con la respuesta del sistema, actualiza los datos de la vista.&lt;/font&gt;&lt;/div&gt;   &lt;/li&gt; &lt;/ol&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Las acciones del usuario que requieran navegación a otra vista, deberán ser delegadas en el presentador, el cual será responsable de aplicar la redirección a la vista correspondiente.&lt;/font&gt;&lt;/p&gt;  &lt;p align="justify"&gt;El patrón MVP, es un patrón que no puede ser implementado sin haber hecho un análisis&amp;#160; previo que determine que miembros deben formar parte del contrato de cada vista.&lt;/p&gt;  &lt;p align="justify"&gt;Una vez que tenemos claro el contrato que debe implementar cada vista, podemos desarrollar la lógica de presentación de forma paralela al diseño gráfico.&lt;/p&gt;  &lt;p align="justify"&gt;El patrón MVP puede ser caro de implementar en aplicaciones relativamente sencillas, sin embargo brilla en escenarios de grandes aplicaciones.&lt;/p&gt;  &lt;p align="justify"&gt;&lt;a href="http://kartones.net/blogs/coco/SecuenciaMVP1_68BB97FD.jpg"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="SecuenciaMVP[1]" border="0" alt="SecuenciaMVP[1]" src="http://kartones.net/blogs/coco/SecuenciaMVP1_thumb_7F2E3684.jpg" width="534" height="298" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;En un escenario de patrón Modelo Vista Presentador, lo primero que debemos hacer es definir el contrato de cada vista, cada formulario tiene su propia interfaz para hablar con el presentador correspondiente.&lt;/font&gt;&lt;/p&gt;  &lt;p align="justify"&gt;El contrato de la vista identifica el modelo de datos que soporta la vista.&lt;/p&gt;  &lt;p align="justify"&gt;Veamos un ejemplo :&lt;/p&gt;  &lt;p align="justify"&gt;&lt;a href="http://kartones.net/blogs/coco/EjemploVistaMVP1_55D6EE86.jpg"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="EjemploVistaMVP[1]" border="0" alt="EjemploVistaMVP[1]" src="http://kartones.net/blogs/coco/EjemploVistaMVP1_thumb_18F246E7.jpg" width="532" height="237" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p align="justify"&gt;La funcionalidad de la vista de la imagen anterior, esta basada en permitir la edición y el alta de empleados, partiendo de esta base, podemos implementar el siguiente contrato para la vista :&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&lt;font size="1" face="Verdana"&gt;public interface &lt;/font&gt;&lt;/span&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;IVistaEmpleado
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;int &lt;/span&gt;IDEmpleado { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;int &lt;/span&gt;IDCentro { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;string &lt;/span&gt;Nombre { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;string &lt;/span&gt;Apellido1 { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;string &lt;/span&gt;Apellido2 { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;int &lt;/span&gt;IDCategoria { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;int &lt;/span&gt;IDDepartamento { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;int &lt;/span&gt;IDEmpleadoResponsable { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }
}&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p align="justify"&gt;El uso de modificadores “get” y “set” en los miembros de la interfaz, dependerá de las características que queremos que soporte la vista, en nuestro ejemplo la vista será utilizada para modificar y dar de alta empleados, por tanto necesitaremos ambos modificadores.&lt;/p&gt;

&lt;p align="justify"&gt;El siguiente fragmento de código representa la implementación de la vista mediante un formulario ASP.NET :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:blue;"&gt;public partial class frmEditarEmpleado&lt;/span&gt;&lt;span style="color:#2b91af;"&gt; &lt;/span&gt;: &lt;span style="color:#2b91af;"&gt;Page&lt;/span&gt;, &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;IVistaEmpleado
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;#region &lt;/span&gt;IVistaEmpleado Members

    &lt;span style="color:blue;"&gt;public int &lt;/span&gt;IDEmpleado
    {
        &lt;span style="color:blue;"&gt;get &lt;/span&gt;{ &lt;span style="color:blue;"&gt;return int&lt;/span&gt;.Parse(txtIDEmpleado.Text); }
        &lt;span style="color:blue;"&gt;set &lt;/span&gt;{ txtIDEmpleado.Text = &lt;span style="color:blue;"&gt;value&lt;/span&gt;.ToString(); }
    }

    &lt;span style="color:blue;"&gt;public int &lt;/span&gt;IDCentro
    {
        &lt;span style="color:blue;"&gt;get &lt;/span&gt;{ &lt;span style="color:blue;"&gt;return int&lt;/span&gt;.Parse(ddlIDCentro.SelectedValue); }
        &lt;span style="color:blue;"&gt;set &lt;/span&gt;{ ddlIDCentro.SelectedValue = &lt;span style="color:blue;"&gt;value&lt;/span&gt;.ToString(); }
    }

    &lt;span style="color:blue;"&gt;public string &lt;/span&gt;Nombre
    {
        &lt;span style="color:blue;"&gt;get &lt;/span&gt;{ &lt;span style="color:blue;"&gt;return &lt;/span&gt;txtNombre.Text; }
        &lt;span style="color:blue;"&gt;set &lt;/span&gt;{ txtNombre.Text = &lt;span style="color:blue;"&gt;value&lt;/span&gt;; }

    }

    &lt;span style="color:blue;"&gt;public string &lt;/span&gt;Apellido1
    {
        &lt;span style="color:blue;"&gt;get &lt;/span&gt;{ &lt;span style="color:blue;"&gt;return &lt;/span&gt;txtApellido1.Text; }
        &lt;span style="color:blue;"&gt;set &lt;/span&gt;{ txtApellido1.Text = &lt;span style="color:blue;"&gt;value&lt;/span&gt;; }
    }

    &lt;span style="color:blue;"&gt;public string &lt;/span&gt;Apellido2
    {
        &lt;span style="color:blue;"&gt;get &lt;/span&gt;{ &lt;span style="color:blue;"&gt;return &lt;/span&gt;txtApellido2.Text; }
        &lt;span style="color:blue;"&gt;set &lt;/span&gt;{ txtApellido2.Text = &lt;span style="color:blue;"&gt;value&lt;/span&gt;; }
    }

    &lt;span style="color:blue;"&gt;public int &lt;/span&gt;IDCategoria
    {
        &lt;span style="color:blue;"&gt;get &lt;/span&gt;{ &lt;span style="color:blue;"&gt;return int&lt;/span&gt;.Parse(ddlIDCategoria.SelectedValue); }
        &lt;span style="color:blue;"&gt;set &lt;/span&gt;{ ddlIDCategoria.SelectedValue = &lt;span style="color:blue;"&gt;value&lt;/span&gt;.ToString(); }
    }

    &lt;span style="color:blue;"&gt;public int &lt;/span&gt;IDDepartamento
    {
        &lt;span style="color:blue;"&gt;get &lt;/span&gt;{ &lt;span style="color:blue;"&gt;return int&lt;/span&gt;.Parse(ddlIDDepartamento.SelectedValue); }
        &lt;span style="color:blue;"&gt;set &lt;/span&gt;{ ddlIDDepartamento.SelectedValue = &lt;span style="color:blue;"&gt;value&lt;/span&gt;.ToString(); }
    }

    &lt;span style="color:blue;"&gt;public int &lt;/span&gt;IDEmpleadoResponsable
    {
        &lt;span style="color:blue;"&gt;get &lt;/span&gt;{ &lt;span style="color:blue;"&gt;return int&lt;/span&gt;.Parse(ddlIDResponsable.SelectedValue); }
        &lt;span style="color:blue;"&gt;set &lt;/span&gt;{ ddlIDResponsable.SelectedValue = &lt;span style="color:blue;"&gt;value&lt;/span&gt;; }
    }
&lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;
    &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:blue;"&gt;#endregion

    protected void &lt;/span&gt;Page_Load(&lt;span style="color:blue;"&gt;object &lt;/span&gt;sender, &lt;span style="color:#2b91af;"&gt;EventArgs &lt;/span&gt;e)
    {

    }
}&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p align="justify"&gt;Cuando la vista se carga por primera vez, se debe crear una instanciar del presentador y guardarla internamente en un campo privado :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:blue;"&gt;public partial class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;frmEditarEmpleado &lt;/span&gt;: &lt;span style="color:#2b91af;"&gt;Page&lt;/span&gt;, &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;IVistaEmpleado
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;private &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;PresentadorEmpleado &lt;/span&gt;presentador;

    &lt;span style="color:blue;"&gt;protected override void &lt;/span&gt;OnInit(&lt;span style="color:#2b91af;"&gt;EventArgs &lt;/span&gt;e)
    {
        &lt;span style="color:blue;"&gt;base&lt;/span&gt;.OnInit(e);
        presentador = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;PresentadorEmpleado&lt;/span&gt;(&lt;span style="color:blue;"&gt;this&lt;/span&gt;);
    }
    
    &lt;span style="color:blue;"&gt;protected void &lt;/span&gt;Page_Load(&lt;span style="color:blue;"&gt;object &lt;/span&gt;sender, &lt;span style="color:#2b91af;"&gt;EventArgs &lt;/span&gt;e)
    {
        &lt;span style="color:blue;"&gt;if &lt;/span&gt;(!IsPostBack)
        {
            presentador.InicializarVista();

            &lt;span style="color:blue;"&gt;if &lt;/span&gt;(Request[&lt;span style="color:#a31515;"&gt;&amp;quot;Id&amp;quot;&lt;/span&gt;] != &lt;span style="color:blue;"&gt;null&lt;/span&gt;)
            {
                &lt;span style="color:blue;"&gt;int &lt;/span&gt;IdEmpleado = &lt;span style="color:blue;"&gt;int&lt;/span&gt;.Parse(Request[&lt;span style="color:#a31515;"&gt;&amp;quot;Id&amp;quot;&lt;/span&gt;]);

                presentador.CargarEmpleado(IdEmpleado);
            }
        }
    }

    &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// [ IVistaEmpleado Members ]
&lt;/span&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p align="justify"&gt;Como podemos observar la vista contiene una referencia al presentador, y el presentador contiene una referencia a la vista.&lt;/p&gt;

&lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;La mejor forma de crear una clase presentador es con los siguientes miembros :&lt;/font&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;div align="justify"&gt;&lt;font color="#ff8040"&gt;Un método de inicialización&lt;/font&gt;&lt;/div&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;div align="justify"&gt;&lt;font color="#ff8040"&gt;Un método de actualización de la vista&lt;/font&gt;&lt;/div&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;div align="justify"&gt;&lt;font color="#ff8040"&gt;Un conjunto de métodos que ejecutan métodos de la capa de servicios / negocio&lt;/font&gt;&lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p align="justify"&gt;Veamos la implementación de nuestro presentador :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&lt;font size="1" face="Verdana"&gt;public class &lt;/font&gt;&lt;/span&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;PresentadorEmpleado
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;private readonly &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IVistaEmpleado &lt;/span&gt;_vista;

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;PresentadorEmpleado(&lt;span style="color:#2b91af;"&gt;IVistaEmpleado &lt;/span&gt;vista)
    {
        _vista = vista;
    }

    &lt;span style="color:blue;"&gt;public void &lt;/span&gt;CargarEmpleado(&lt;span style="color:blue;"&gt;int &lt;/span&gt;IdEmpleado)
    {
        &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// Llamada a la capa de servicios / negocio ..
        &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Empleado &lt;/span&gt;emp = &lt;span style="color:#2b91af;"&gt;RepositorioEmpleado&lt;/span&gt;.Obtener(IdEmpleado);

        ActualizarVista(emp);
    }

    &lt;span style="color:blue;"&gt;public void &lt;/span&gt;InicializarVista()
    {
        _vista.Apellido1 = &lt;span style="color:blue;"&gt;string&lt;/span&gt;.Empty;
        _vista.Apellido2 = &lt;span style="color:blue;"&gt;string&lt;/span&gt;.Empty;

        &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// ..
    &lt;/span&gt;}

    &lt;span style="color:blue;"&gt;public void &lt;/span&gt;ActualizarVista(&lt;span style="color:#2b91af;"&gt;Empleado &lt;/span&gt;empleado)
    {
        _vista.Apellido1 = empleado.Apellido1;
        _vista.Apellido2 = empleado.Apellido2;
        _vista.IDCategoria = empleado.Categoria.ID;

        &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// ..
    &lt;/span&gt;}
}&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p align="justify"&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;Como se puede observar, el presentador cuelga una referencia a la vista y desconoce por absoluto si se trata de una vista ASP.NET o una vista WinForms, todo lo que sabe es que tiene una referencia a un objeto que implementa una interfaz.&lt;/p&gt;

&lt;p align="justify"&gt;El presentador lee y escribe el estado de la vista a través de los miembros de la interfaz.&lt;/p&gt;

&lt;p align="justify"&gt;A través de la interfaz de la vista, el presentador recoge todos los datos que necesita para ejecutar la acción solicitada en la capa de servicios / negocio.&lt;/p&gt;

&lt;p align="justify"&gt;Para actualizar la vista, el presentador solo tiene que asignar nuevos valores a las propiedades expuestas por la interfaz de la vista.&lt;/p&gt;

&lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Para ayudarnos a implementar el patrón MVP, podemos apoyarnos en los componentes y librerías reusables de Web Client Software Factory (WCSF) ya que nos permiten aplicar varias prácticas y patrones en aplicaciones ASP.NET.&lt;/font&gt;&lt;/p&gt;

&lt;p align="justify"&gt;Podemos descargar Web Client Software Factory desde esta URL :&lt;/p&gt;

&lt;p align="justify"&gt;&lt;a title="http://webclientguidance.codeplex.com/" href="http://webclientguidance.codeplex.com/"&gt;http://webclientguidance.codeplex.com/&lt;/a&gt;&lt;/p&gt;

&lt;p align="justify"&gt;Como comentamos antes, una de las responsabilidades del presentador es exponer funcionalidad para la navegación entre vistas, uno de los beneficios de usar WCSF, es que disponemos de un bloque para implementar flujos de interfaz de usuario a través de formularios web.&lt;/p&gt;

&lt;p align="justify"&gt;Mediante el bloque PFAB (Page Flow Application Block) podemos orquestar la secuencia de formularios web que necesitamos para completar los flujos de interfaz de usuario.&lt;/p&gt;

&lt;p align="justify"&gt;El bloque PFAB de Web Client Software Factory está basado en Windows WorkFlow Foundation y Enterprise Library.&lt;/p&gt;

&lt;p align="justify"&gt;Y eso ha sido todo por hoy ..&lt;/p&gt;
&lt;div id="postorigin" style="margin-left:5px;font-size:80%;padding:5px;border:2px solid #BDB67C;background-color:#DDDBC7;width:300px;text-align:center;-moz-border-radius:4px 4px 4px 4px;-webkit-border-radius:4px;border-radius:4px;"&gt;&lt;a href="http://kartones.net/blogs/coco/archive/2009/12/19/la-capa-de-presentaci-243-n-el-patr-243-n-mvp.aspx"&gt;La Capa de Presentaci&amp;#243;n : El Patr&amp;#243;n MVP&lt;/a&gt; was posted the 12/19/2009 at &lt;a href="http://Kartones.net"&gt;Kartones.Net&lt;/a&gt;.&lt;/div&gt;
&lt;div id="sharing" class="postfoot"&gt;&lt;hr /&gt;&lt;p&gt;Share via:&lt;br&gt;&lt;a rel="nofollow" href="mailto:?subject=Kartones.Net:%20La+Capa+de+Presentaci%26%23243%3bn+%3a+El+Patr%26%23243%3bn+MVP&amp;amp;body=http://kartones.net/blogs/coco/archive/2009/12/19/la-capa-de-presentaci-243-n-el-patr-243-n-mvp.aspx" target="_blank"&gt;Email&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.facebook.com/share.php?u=http://kartones.net/blogs/coco/archive/2009/12/19/la-capa-de-presentaci-243-n-el-patr-243-n-mvp.aspx&amp;amp;t=La+Capa+de+Presentaci%26%23243%3bn+%3a+El+Patr%26%23243%3bn+MVP" target="_blank"&gt;Facebook&lt;/a&gt; | &lt;a rel="nofollow" href="http://twitter.com/home?status=http://kartones.net/blogs/coco/archive/2009/12/19/la-capa-de-presentaci-243-n-el-patr-243-n-mvp.aspx" target="_blank"&gt;Twitter&lt;/a&gt; | &lt;a rel="nofollow" href="http://slashdot.org/bookmark.pl?url=http://kartones.net/blogs/coco/archive/2009/12/19/la-capa-de-presentaci-243-n-el-patr-243-n-mvp.aspx&amp;amp;title=La+Capa+de+Presentaci%26%23243%3bn+%3a+El+Patr%26%23243%3bn+MVP" target="_blank"&gt;SlashDot&lt;/a&gt; | &lt;a rel="nofollow" href="http://delicious.com/post?url=http://kartones.net/blogs/coco/archive/2009/12/19/la-capa-de-presentaci-243-n-el-patr-243-n-mvp.aspx&amp;amp;title=La+Capa+de+Presentaci%26%23243%3bn+%3a+El+Patr%26%23243%3bn+MVP" target="_blank"&gt;del.icio.us&lt;/a&gt; | &lt;a rel="nofollow" href="http://technorati.com/faves?add=http://kartones.net/blogs/coco/archive/2009/12/19/la-capa-de-presentaci-243-n-el-patr-243-n-mvp.aspx" target="_blank"&gt;Technorati&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http://kartones.net/blogs/coco/archive/2009/12/19/la-capa-de-presentaci-243-n-el-patr-243-n-mvp.aspx&amp;amp;title=La+Capa+de+Presentaci%26%23243%3bn+%3a+El+Patr%26%23243%3bn+MVP" target="_blank"&gt;Stumbleupon&lt;/a&gt; | &lt;a rel="nofollow" href="http://reddit.com/submit?url=http://kartones.net/blogs/coco/archive/2009/12/19/la-capa-de-presentaci-243-n-el-patr-243-n-mvp.aspx&amp;amp;title=La+Capa+de+Presentaci%26%23243%3bn+%3a+El+Patr%26%23243%3bn+MVP" target="_blank"&gt;Reddit&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.google.com/reader/link?url=http://kartones.net/blogs/coco/archive/2009/12/19/la-capa-de-presentaci-243-n-el-patr-243-n-mvp.aspx&amp;amp;title=La+Capa+de+Presentaci%26%23243%3bn+%3a+El+Patr%26%23243%3bn+MVP&amp;amp;srcUrl=http://kartones.net/blogs/coco/archive/2009/12/19/la-capa-de-presentaci-243-n-el-patr-243-n-mvp.aspx&amp;amp;srcTitle=La+Capa+de+Presentaci%26%23243%3bn+%3a+El+Patr%26%23243%3bn+MVP" target="_blank"&gt;Google Reader&lt;/a&gt; | &lt;a rel="nofollow" href="http://meneame.net/submit.php?url=http://kartones.net/blogs/coco/archive/2009/12/19/la-capa-de-presentaci-243-n-el-patr-243-n-mvp.aspx" target="_blank"&gt;Meneame&lt;/a&gt; | &lt;a rel="nofollow" href="http://bitacoras.com/anotaciones/http://kartones.net/blogs/coco/archive/2009/12/19/la-capa-de-presentaci-243-n-el-patr-243-n-mvp.aspx" target="_blank"&gt;Bitacoras&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.linkedin.com/shareArticle?mini=true&amp;amp;url=http://kartones.net/blogs/coco/archive/2009/12/19/la-capa-de-presentaci-243-n-el-patr-243-n-mvp.aspx&amp;amp;title=La+Capa+de+Presentaci%26%23243%3bn+%3a+El+Patr%26%23243%3bn+MVP&amp;amp;source=Kartones.Net" target="_blank"&gt;LinkedIn&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.google.com/bookmarks/mark?op=edit&amp;amp;bkmk=http://kartones.net/blogs/coco/archive/2009/12/19/la-capa-de-presentaci-243-n-el-patr-243-n-mvp.aspx&amp;amp;title=La+Capa+de+Presentaci%26%23243%3bn+%3a+El+Patr%26%23243%3bn+MVP" target="_blank"&gt;Google Bookmarks&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.google.com/reader/link?url=http://kartones.net/blogs/coco/archive/2009/12/19/la-capa-de-presentaci-243-n-el-patr-243-n-mvp.aspx&amp;amp;title=La+Capa+de+Presentaci%26%23243%3bn+%3a+El+Patr%26%23243%3bn+MVP" target="_blank"&gt;Google Reader&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.google.com/buzz/post?url=http://kartones.net/blogs/coco/archive/2009/12/19/la-capa-de-presentaci-243-n-el-patr-243-n-mvp.aspx&amp;amp;imageurl=" target="_blank"&gt;Google Buzz&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.friendfeed.com/share?title=La+Capa+de+Presentaci%26%23243%3bn+%3a+El+Patr%26%23243%3bn+MVP&amp;amp;link=http://kartones.net/blogs/coco/archive/2009/12/19/la-capa-de-presentaci-243-n-el-patr-243-n-mvp.aspx" target="_blank"&gt;FriendFeed&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.netvibes.com/share?title=La+Capa+de+Presentaci%26%23243%3bn+%3a+El+Patr%26%23243%3bn+MVP&amp;amp;url=http://kartones.net/blogs/coco/archive/2009/12/19/la-capa-de-presentaci-243-n-el-patr-243-n-mvp.aspx" target="_blank"&gt;Netvibes&lt;/a&gt; | &lt;a rel="nofollow" href="https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;mkt=es-es&amp;amp;url=http://kartones.net/blogs/coco/archive/2009/12/19/la-capa-de-presentaci-243-n-el-patr-243-n-mvp.aspx&amp;amp;title=La+Capa+de+Presentaci%26%23243%3bn+%3a+El+Patr%26%23243%3bn+MVP" target="_blank"&gt;Windows Live&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.myspace.com/Modules/PostTo/Pages/?u=http://kartones.net/blogs/coco/archive/2009/12/19/la-capa-de-presentaci-243-n-el-patr-243-n-mvp.aspx&amp;amp;t=La+Capa+de+Presentaci%26%23243%3bn+%3a+El+Patr%26%23243%3bn+MVP" target="_blank"&gt;MySpace&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;img src="http://kartones.net/aggbug.aspx?PostID=50614" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/ElFrameworkDeCoco/~4/gGJs8E8Q1OA" height="1" width="1"/&gt;</description><feedburner:origLink>http://kartones.net/blogs/coco/archive/2009/12/19/la-capa-de-presentaci-243-n-el-patr-243-n-mvp.aspx</feedburner:origLink></item><item><title>La Capa de Presentación : Conceptos Básicos</title><link>http://feeds.kartones.net/~r/ElFrameworkDeCoco/~3/FV549-WPLSE/la-capa-de-presentaci-243-n-conceptos-b-225-sicos.aspx</link><pubDate>Mon, 14 Dec 2009 11:56:38 GMT</pubDate><guid isPermaLink="false">b86c0850-82e5-42ed-a9d8-bde9e8f94ec1:50604</guid><dc:creator>ccrego</dc:creator><slash:comments>0</slash:comments><comments>http://kartones.net/blogs/coco/archive/2009/12/14/la-capa-de-presentaci-243-n-conceptos-b-225-sicos.aspx#comments</comments><description>&lt;p align="justify"&gt;A día de hoy no conozco ninguna aplicación que pueda utilizarse sin una interfaz de usuario, y aunque parezca curioso, muchos arquitectos tienden a encasillar a la interfaz de usuario como la parte más aburrida en el desarrollo y sin embargo en muchos proyectos es donde más tiempo de emplea.&lt;/p&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;La capa de presentación es a menudo la última parte que se despliega y tiende a ser muy dependiente de las herramientas de desarrollo utilizadas&lt;/font&gt;, sin embargo la capacidad de desenchufar una interfaz de usuario y reemplazarla con otra suele ser un requerimiento clave en todas las capas de presentación.&lt;/p&gt;  &lt;p align="justify"&gt;La implementación de un capa de presentación puede ser muy sencilla, pero hay escenarios donde se puede volver muy compleja mediante el uso de maestros, detalles y flujos de navegación.&lt;/p&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;A grandes rasgos se podría decir que la capa de presentación se compone de :&lt;/font&gt;&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;     &lt;div align="justify"&gt;&lt;font color="#ff8040"&gt;La interfaz de usuario&lt;/font&gt;&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;&lt;font color="#ff8040"&gt;La lógica de presentación&lt;/font&gt;&lt;/div&gt;   &lt;/li&gt; &lt;/ol&gt;  &lt;p align="justify"&gt;La interfaz de usuario ofrece a los usuarios información, sugerencias, acciones y captura los datos de entrada a través del teclado y el ratón.&lt;/p&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;La lógica de presentación hace referencia a todo el procesamiento requerido para mostrar datos y transformar los datos de entrada en acciones que podemos ejecutar contra la capa de negocio o de servicios.&lt;/font&gt;&lt;/p&gt;  &lt;p align="justify"&gt;Se podría decir que la lógica de presentación esta muy relacionada con mostrar datos en la pantalla del usuario.&lt;/p&gt;  &lt;p align="justify"&gt;&amp;#160;&lt;img src="http://kartones.net/images_posts/coco/DiagramaCapaPresentacion.JPG" width="528" height="497" alt="DiagramaCapaPresentacion.JPG" /&gt; &lt;/p&gt;  &lt;p align="justify"&gt;Como se puede observar en la imagen, la capa de presentación es la interfaz entre el usuario y el sistema.&lt;/p&gt;  &lt;p align="justify"&gt;Si le preguntamos a alguien sobre cuales son las responsabilidades de la capa de presentación seguramente nos responderá con algunas de estas :&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;     &lt;div align="justify"&gt;Validación&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;Formateo&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;Estilos&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;Usabilidad&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;…&lt;/div&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p align="justify"&gt;El estilo y la usabilidad pueden considerarse simples atributos, y la validación y formateo pueden implementarse mediante componentes.&lt;/p&gt;  &lt;p align="justify"&gt;Todas estas “responsabilidades” suelen estar estrechamente relacionadas con la tecnología y plataforma elegida para implementar el sistema. &lt;/p&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Una capa de presentación a alto nivel tiene tres grandes responsabilidades :&lt;/font&gt;&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;     &lt;div align="justify"&gt;&lt;font color="#ff8040"&gt;Independencia de la interfaz de usuario&lt;/font&gt;&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;&lt;font color="#ff8040"&gt;Testeabilidad&lt;/font&gt;&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;&lt;font color="#ff8040"&gt;Independencia del modelo de datos&lt;/font&gt;&lt;/div&gt;   &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Seguramente nos habremos encontrado más de una vez con el siguiente dilema :&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;¿ Enlace o Botón ?&lt;/li&gt;    &lt;li&gt;¿ Qué Colores uso ?&lt;/li&gt;    &lt;li&gt;¿ Qué bordes, estilos y fuentes ?&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;El caso es que la capa de presentación debe ser capaz de escalar todas estas incognitas sin que la lógica de presentación se vea afectada, un claro ejemplo de ello son las aplicaciones de blogs como el que estais leyendo ahora mismo.&lt;/p&gt;  &lt;p align="justify"&gt;La capa de presentación también debe ser independiente de la tecnología de interfaz de usuario y plataforma usadas, aunque este requerimiento es muy complicado de cumplir y en la mayoría de las ocasiones es imposible obtener una independencia total.&lt;/p&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Para conseguir desacoplar la interfaz de usuario de la lógica de presentación&amp;#160; debemos hacer uso de contratos de datos&lt;/font&gt;, para entenderlo mejor imaginemos el siguiente formulario web de visualización y entrada de datos :&lt;/p&gt;  &lt;p&gt;&lt;img style="display:block;float:none;margin-left:auto;margin-right:auto;" src="http://kartones.net/images_posts/coco/EjemploInterfazUsuario.JPG" width="403" height="470" alt="EjemploInterfazUsuario.JPG" /&gt; &lt;/p&gt;  &lt;p&gt;A grandes rasgos, tenemos :&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Datos de empleado&lt;/li&gt;    &lt;li&gt;Datos de prendas y tallas disponibles&lt;/li&gt;    &lt;li&gt;Datos de entrada&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Si aplicamos un buen diseño en la capa de presentación nuestro contrato de datos para el formulario estará formado por la siguiente interfaz :&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&lt;font size="1" face="Verdana"&gt;public interface &lt;/font&gt;&lt;/span&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;IViewGarmentIncidence
&lt;/span&gt;{
    &lt;span style="color:#2b91af;"&gt;Employee &lt;/span&gt;Employee { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:#2b91af;"&gt;IList&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Garment&lt;/span&gt;&amp;gt; Garments { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;int &lt;/span&gt;IncidenceGarmentType { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;int &lt;/span&gt;GarmentType { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;int &lt;/span&gt;Size { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;string &lt;/span&gt;Details { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;int &lt;/span&gt;Amount { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;string &lt;/span&gt;Comments { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }
}&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Mediante el uso de contratos podemos reutilizar la lógica de presentación en otras interfaces de usuario, de este modo podremos implementar por ejemplo, el mismo formulario usando formularios Windows, Silverlight o WPF de tal manera que nuestra única preocupación será implementar la interfaz de usuario con la tecnología seleccionada.&lt;/font&gt;&lt;/p&gt;

&lt;p align="justify"&gt;La capa de presentación debería ser probada al igual que el resto de capas, una de las ventajas de conseguir desacoplar la lógica de presentación de la interfaz de usuario, es que podemos probarlas por separado.&lt;/p&gt;

&lt;p align="justify"&gt;Aunque no es fácil probar la interfaz de usuario dentro de un entorno de testing, si que podemos mover todo el código testeable correspondiente a los manejadores de eventos a métodos dentro de una clase.&lt;/p&gt;

&lt;p align="justify"&gt;Un arquitecto no debe implicarse directamente en la definición de los detalles de la interfaz de usuario, en su lugar, debe preocuparse de la definición de los datos que se manejaran en cada formulario y&amp;#160; de aspectos de calidad como por ejemplo la usabilidad y la accesibilidad.&lt;/p&gt;

&lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Una vez que el arquitecto ha definido con éxito los datos que se manejaran en cada formulario con los usuarios del sistema, el equipo de desarrollo puede proceder a implementar y probar la lógica de presentación al mismo tiempo que los diseñadores gráficos se ocupan de desarrollar la interfaz de usuario.&lt;/font&gt;&lt;/p&gt;

&lt;p align="justify"&gt;Y eso es todo por hoy, en el siguiente post hablare sobre el patrón Modelo Vista Presentador, de sus ventajas e implementación.&lt;/p&gt;
&lt;div id="postorigin" style="margin-left:5px;font-size:80%;padding:5px;border:2px solid #BDB67C;background-color:#DDDBC7;width:300px;text-align:center;-moz-border-radius:4px 4px 4px 4px;-webkit-border-radius:4px;border-radius:4px;"&gt;&lt;a href="http://kartones.net/blogs/coco/archive/2009/12/14/la-capa-de-presentaci-243-n-conceptos-b-225-sicos.aspx"&gt;La Capa de Presentaci&amp;#243;n : Conceptos B&amp;#225;sicos&lt;/a&gt; was posted the 12/14/2009 at &lt;a href="http://Kartones.net"&gt;Kartones.Net&lt;/a&gt;.&lt;/div&gt;
&lt;div id="sharing" class="postfoot"&gt;&lt;hr /&gt;&lt;p&gt;Share via:&lt;br&gt;&lt;a rel="nofollow" href="mailto:?subject=Kartones.Net:%20La+Capa+de+Presentaci%26%23243%3bn+%3a+Conceptos+B%26%23225%3bsicos&amp;amp;body=http://kartones.net/blogs/coco/archive/2009/12/14/la-capa-de-presentaci-243-n-conceptos-b-225-sicos.aspx" target="_blank"&gt;Email&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.facebook.com/share.php?u=http://kartones.net/blogs/coco/archive/2009/12/14/la-capa-de-presentaci-243-n-conceptos-b-225-sicos.aspx&amp;amp;t=La+Capa+de+Presentaci%26%23243%3bn+%3a+Conceptos+B%26%23225%3bsicos" target="_blank"&gt;Facebook&lt;/a&gt; | &lt;a rel="nofollow" href="http://twitter.com/home?status=http://kartones.net/blogs/coco/archive/2009/12/14/la-capa-de-presentaci-243-n-conceptos-b-225-sicos.aspx" target="_blank"&gt;Twitter&lt;/a&gt; | &lt;a rel="nofollow" href="http://slashdot.org/bookmark.pl?url=http://kartones.net/blogs/coco/archive/2009/12/14/la-capa-de-presentaci-243-n-conceptos-b-225-sicos.aspx&amp;amp;title=La+Capa+de+Presentaci%26%23243%3bn+%3a+Conceptos+B%26%23225%3bsicos" target="_blank"&gt;SlashDot&lt;/a&gt; | &lt;a rel="nofollow" href="http://delicious.com/post?url=http://kartones.net/blogs/coco/archive/2009/12/14/la-capa-de-presentaci-243-n-conceptos-b-225-sicos.aspx&amp;amp;title=La+Capa+de+Presentaci%26%23243%3bn+%3a+Conceptos+B%26%23225%3bsicos" target="_blank"&gt;del.icio.us&lt;/a&gt; | &lt;a rel="nofollow" href="http://technorati.com/faves?add=http://kartones.net/blogs/coco/archive/2009/12/14/la-capa-de-presentaci-243-n-conceptos-b-225-sicos.aspx" target="_blank"&gt;Technorati&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http://kartones.net/blogs/coco/archive/2009/12/14/la-capa-de-presentaci-243-n-conceptos-b-225-sicos.aspx&amp;amp;title=La+Capa+de+Presentaci%26%23243%3bn+%3a+Conceptos+B%26%23225%3bsicos" target="_blank"&gt;Stumbleupon&lt;/a&gt; | &lt;a rel="nofollow" href="http://reddit.com/submit?url=http://kartones.net/blogs/coco/archive/2009/12/14/la-capa-de-presentaci-243-n-conceptos-b-225-sicos.aspx&amp;amp;title=La+Capa+de+Presentaci%26%23243%3bn+%3a+Conceptos+B%26%23225%3bsicos" target="_blank"&gt;Reddit&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.google.com/reader/link?url=http://kartones.net/blogs/coco/archive/2009/12/14/la-capa-de-presentaci-243-n-conceptos-b-225-sicos.aspx&amp;amp;title=La+Capa+de+Presentaci%26%23243%3bn+%3a+Conceptos+B%26%23225%3bsicos&amp;amp;srcUrl=http://kartones.net/blogs/coco/archive/2009/12/14/la-capa-de-presentaci-243-n-conceptos-b-225-sicos.aspx&amp;amp;srcTitle=La+Capa+de+Presentaci%26%23243%3bn+%3a+Conceptos+B%26%23225%3bsicos" target="_blank"&gt;Google Reader&lt;/a&gt; | &lt;a rel="nofollow" href="http://meneame.net/submit.php?url=http://kartones.net/blogs/coco/archive/2009/12/14/la-capa-de-presentaci-243-n-conceptos-b-225-sicos.aspx" target="_blank"&gt;Meneame&lt;/a&gt; | &lt;a rel="nofollow" href="http://bitacoras.com/anotaciones/http://kartones.net/blogs/coco/archive/2009/12/14/la-capa-de-presentaci-243-n-conceptos-b-225-sicos.aspx" target="_blank"&gt;Bitacoras&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.linkedin.com/shareArticle?mini=true&amp;amp;url=http://kartones.net/blogs/coco/archive/2009/12/14/la-capa-de-presentaci-243-n-conceptos-b-225-sicos.aspx&amp;amp;title=La+Capa+de+Presentaci%26%23243%3bn+%3a+Conceptos+B%26%23225%3bsicos&amp;amp;source=Kartones.Net" target="_blank"&gt;LinkedIn&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.google.com/bookmarks/mark?op=edit&amp;amp;bkmk=http://kartones.net/blogs/coco/archive/2009/12/14/la-capa-de-presentaci-243-n-conceptos-b-225-sicos.aspx&amp;amp;title=La+Capa+de+Presentaci%26%23243%3bn+%3a+Conceptos+B%26%23225%3bsicos" target="_blank"&gt;Google Bookmarks&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.google.com/reader/link?url=http://kartones.net/blogs/coco/archive/2009/12/14/la-capa-de-presentaci-243-n-conceptos-b-225-sicos.aspx&amp;amp;title=La+Capa+de+Presentaci%26%23243%3bn+%3a+Conceptos+B%26%23225%3bsicos" target="_blank"&gt;Google Reader&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.google.com/buzz/post?url=http://kartones.net/blogs/coco/archive/2009/12/14/la-capa-de-presentaci-243-n-conceptos-b-225-sicos.aspx&amp;amp;imageurl=" target="_blank"&gt;Google Buzz&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.friendfeed.com/share?title=La+Capa+de+Presentaci%26%23243%3bn+%3a+Conceptos+B%26%23225%3bsicos&amp;amp;link=http://kartones.net/blogs/coco/archive/2009/12/14/la-capa-de-presentaci-243-n-conceptos-b-225-sicos.aspx" target="_blank"&gt;FriendFeed&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.netvibes.com/share?title=La+Capa+de+Presentaci%26%23243%3bn+%3a+Conceptos+B%26%23225%3bsicos&amp;amp;url=http://kartones.net/blogs/coco/archive/2009/12/14/la-capa-de-presentaci-243-n-conceptos-b-225-sicos.aspx" target="_blank"&gt;Netvibes&lt;/a&gt; | &lt;a rel="nofollow" href="https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;mkt=es-es&amp;amp;url=http://kartones.net/blogs/coco/archive/2009/12/14/la-capa-de-presentaci-243-n-conceptos-b-225-sicos.aspx&amp;amp;title=La+Capa+de+Presentaci%26%23243%3bn+%3a+Conceptos+B%26%23225%3bsicos" target="_blank"&gt;Windows Live&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.myspace.com/Modules/PostTo/Pages/?u=http://kartones.net/blogs/coco/archive/2009/12/14/la-capa-de-presentaci-243-n-conceptos-b-225-sicos.aspx&amp;amp;t=La+Capa+de+Presentaci%26%23243%3bn+%3a+Conceptos+B%26%23225%3bsicos" target="_blank"&gt;MySpace&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;img src="http://kartones.net/aggbug.aspx?PostID=50604" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/ElFrameworkDeCoco/~4/FV549-WPLSE" height="1" width="1"/&gt;</description><feedburner:origLink>http://kartones.net/blogs/coco/archive/2009/12/14/la-capa-de-presentaci-243-n-conceptos-b-225-sicos.aspx</feedburner:origLink></item><item><title>La Capa de Servicios AJAX</title><link>http://feeds.kartones.net/~r/ElFrameworkDeCoco/~3/PQ1joNKgTQc/la-capa-de-servicios-ajax.aspx</link><pubDate>Fri, 11 Dec 2009 12:15:28 GMT</pubDate><guid isPermaLink="false">b86c0850-82e5-42ed-a9d8-bde9e8f94ec1:50595</guid><dc:creator>ccrego</dc:creator><slash:comments>0</slash:comments><comments>http://kartones.net/blogs/coco/archive/2009/12/11/la-capa-de-servicios-ajax.aspx#comments</comments><description>&lt;p align="justify"&gt;Cuando trabajamos con una capa de servicios local implementada a través de un assembly y usamos ASP.NET para implementar nuestra capa de presentación, la capa de servicios se encontrara alojada en el mismo worker process de IIS.&lt;/p&gt;  &lt;p align="justify"&gt;Sin embargo si tenemos intención de explotar nuestra capa de servicios usando AJAX o Silverlight, debemos realizar algunos ajustes, especialmente en el área de seguridad.&lt;/p&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Una de las características de AJAX y Silverlight es la capacidad para llamar a capas de servicios remotas a través de HTTP, en estos casos la comunicación tiene lugar a través de peticiones HTTP a una dirección y puerto determinados que son expuestos públicamente por el servidor web.&lt;/font&gt;&lt;/p&gt;  &lt;p align="justify"&gt;&lt;img src="http://kartones.net/images_posts/coco/ArquitecturaSinCapaAjax.JPG" width="531" height="405" alt="ArquitecturaSinCapaAjax.JPG" /&gt; &lt;/p&gt;  &lt;p align="justify"&gt;Exponer una capa de servicios a un cliente web es definitivamente un agujero de seguridad, en estos casos es necesario una capa que envuelva a los servicios, a esta capa se la conoce como capa de servicios AJAX.&lt;/p&gt;  &lt;p align="justify"&gt;&lt;img src="http://kartones.net/images_posts/coco/ArquitecturaConCapaAjax.JPG" width="528" height="452" alt="ArquitecturaConCapaAjax.JPG" /&gt; &lt;/p&gt;  &lt;p align="justify"&gt;La capa de servicios AJAX es la puerta al corazón de nuestro sistema, y como tal cualquier acceso debe ser identificado y autorizado.&lt;/p&gt;  &lt;p align="justify"&gt;En un escenario Web tradicional normalmente usamos autenticación por formularios para filtrar el acceso de los usuarios a las diversas secciones que componen nuestra capa de presentación, en estos casos la seguridad en la capa de servicios la podemos implementar fácilmente a través de&amp;#160; :&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;     &lt;div align="justify"&gt;Seguridad en el Acceso a Código (CAS)&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;WCF&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;Características de Seguridad para Servicios Web&lt;/div&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p align="justify"&gt;En la autenticación por formularios, el usuario envía sus credenciales y en caso de ser validas, se genera una cookie de autenticación.&lt;/p&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Mediante la autenticación por formularios, podemos comprobar en la capa de servicios AJAX la presencia de la cookie de autenticación en la petición HTTP para de esta forma proceder a ejecutar la lógica o a denegar el acceso.&lt;/font&gt;&lt;/p&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Del mismo modo, podríamos cargar un objeto Usuario en Sesión y recuperarlos en la capa de servicios AJAX para determinar si tiene o no permisos para ejecutar cada uno de los servicios expuestos.&lt;/font&gt;&lt;/p&gt;  &lt;p align="justify"&gt;&lt;img src="http://kartones.net/images_posts/coco/ProcesoAutenticaci&amp;oacute;nArqAjax.JPG" width="530" height="293" alt="ProcesoAutenticaci&amp;oacute;nArqAjax.JPG" /&gt; &lt;/p&gt;  &lt;p align="justify"&gt;Como podemos deducir, una capa de servicios AJAX es una capa “tonta” que asegura las llamadas mediante la verificación de credenciales.&lt;/p&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Para hacer que nuestros servicios sean accesibles desde el navegador debemos hacerlos “scriptables”, es decir, debemos configurarlos para poder ser invocados desde Javascript.&lt;/font&gt;&lt;/p&gt;  &lt;p align="justify"&gt;En .NET podemos implementar una capa de servicios de 3 formas :&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;     &lt;div align="justify"&gt;Mediante un assembly&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;Mediante WCF&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;Mediante Servicios Web Tradicionales&lt;/div&gt;   &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p align="justify"&gt;En el caso de servicios web tradicionales, debemos hacer una puntualización, y es que desde la versión 2.0 del Framework tenemos “Servicios Web XML para ASP.NET” o como se conocen técnicamente ASP.NET XML Web Service.&lt;/p&gt;  &lt;p align="justify"&gt;Cuando el motor de ejecución de ASP.NET recibe una petición para un recurso .ASMX, se fija en el content-type de la cabecera HTTP :&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;     &lt;div align="justify"&gt;Si es application/json, instancia el manejador HTTP REST Handler que solo entiende de peticiones en JSON.&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;Si es application/soap, instancia el manejador HTTP estándar que solo entiende de peticiones SOAP.&lt;/div&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p align="justify"&gt;En el caso del manejador HTTP REST Handler, además se comprueba que la clase que implementa el servicio web .ASMX, este decorada con el atributo [ScriptService].&lt;/p&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Para implementar una capa de servicios mediante servicios web ASP.NET XML y exponerlos al navegador web, debemos decorar nuestras clases ASP.NET XML WebService con el atributo [ScriptService].&lt;/font&gt;&lt;/p&gt;  &lt;pre class="code"&gt;&lt;font size="1" face="Verdana"&gt;[&lt;span style="color:#2b91af;"&gt;ScriptService&lt;/span&gt;]
&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;EmployeeService &lt;/span&gt;: &lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;IEmployeeService
&lt;/span&gt;{
    [&lt;span style="color:#2b91af;"&gt;WebMethod&lt;/span&gt;]
    &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Employee &lt;/span&gt;GetEmployeeJSON(&lt;span style="color:blue;"&gt;int &lt;/span&gt;employeeId)
    {
        &lt;span style="color:#2b91af;"&gt;Employee &lt;/span&gt;emp = &lt;span style="color:blue;"&gt;null&lt;/span&gt;;

        &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// ..

        &lt;/span&gt;&lt;span style="color:blue;"&gt;return &lt;/span&gt;emp;
    }

    [&lt;span style="color:#2b91af;"&gt;WebMethod&lt;/span&gt;]
    [&lt;span style="color:#2b91af;"&gt;ScriptMethod&lt;/span&gt;]
    &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Employee &lt;/span&gt;GetEmployeeXML(&lt;span style="color:blue;"&gt;int &lt;/span&gt;employeeId)
    {
        &lt;span style="color:#2b91af;"&gt;Employee &lt;/span&gt;emp = &lt;span style="color:blue;"&gt;null&lt;/span&gt;;

        &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// ..

        &lt;/span&gt;&lt;span style="color:blue;"&gt;return &lt;/span&gt;emp;
    }
}&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;Como podemos observar en el fragmento de código anterior, tenemos 2 métodos accesibles, la diferencia principal es que uno de ellos está decorado con el atributo [ScriptMethod].&lt;/p&gt;

&lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;El atributo [ScriptMethod] nos permite indicar que los datos de un método en un servicio web decorado con el atributo [ScriptService] serán serializados usando XML en lugar de JSON y que se habilitará al método para ser invocado a través de una llamada HTTP GET.&lt;/font&gt;&lt;/p&gt;

&lt;p align="justify"&gt;Deshabilitar las llamadas HTTP GET es una medida de seguridad que nos ayuda a evitar llamadas a través de injección de scripts ya que cuando se inyecta un tag &amp;lt;script&amp;gt; solo podemos especificar una URL a través de GET.&lt;/p&gt;

&lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Si queremos que nuestro servicio web sea expuesto solo para ser llamado a través de Javascript mediante JSON, tendremos que añadir el siguiente fragmento de configuración en el web.config de la aplicación que aloja los servicios web.&lt;/font&gt;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;system.web&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:blue;"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;webServices&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:blue;"&gt;&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;protocols&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:blue;"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;clear&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:blue;"&gt;/&amp;gt;
      &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;protocols&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:blue;"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;webServices&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Para poder invocar nuestros servicios WCF desde Javacript solo necesitamos :&lt;/font&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;div align="justify"&gt;&lt;font color="#ff8040"&gt;Usar el binding webHttpBinding.&lt;/font&gt;&lt;/div&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;div align="justify"&gt;&lt;font color="#ff8040"&gt;Usar el comportamiento webScriptBehaviour para habilitar la serialización de datos en JSON y habilitar las llamadas desde Javascript.&lt;/font&gt;&lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p align="justify"&gt;Como he explicado antes, los servicios de la capa de servicios AJAX pueden ser llamados por dos tipos de usuarios :&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;div align="justify"&gt;Autenticados&lt;/div&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;div align="justify"&gt;No Autenticados&lt;/div&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p align="justify"&gt;La diferencia entre estos dos tipos de usuarios es que los usuarios Autenticados tienen un objeto de autenticación que nos permite determinar la identidad del usuario y sus roles de autorización, este objeto lo podemos implementar a través de :&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;div align="justify"&gt;La cookie de autenticación generada con autenticación basada en formularios&lt;/div&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;div align="justify"&gt;Un objeto de autenticación cargado en Sesión &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p align="justify"&gt;Partiendo de esta base, los métodos de la capa de servicios AJAX son extremadamente sencillos de implementar, veamos un ejemplo :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&lt;font size="1" face="Verdana"&gt;public class &lt;/font&gt;&lt;/span&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;Role 
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;public int &lt;/span&gt;ID
    { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;public string &lt;/span&gt;Name
    { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;Role(&lt;span style="color:blue;"&gt;int &lt;/span&gt;id, &lt;span style="color:blue;"&gt;string &lt;/span&gt;name)
    {
        &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// Assign the parameters ..
    &lt;/span&gt;}

    &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// Role Members ..
&lt;/span&gt;}

&lt;span style="color:blue;"&gt;public static class &lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;RoleFactory
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;public static &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Role &lt;/span&gt;GetAdministratorRole()
    {
        &lt;span style="color:blue;"&gt;return new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Role&lt;/span&gt;(1, &lt;span style="color:#a31515;"&gt;&amp;quot;Administrator&amp;quot;&lt;/span&gt;);
    }

    &lt;span style="color:blue;"&gt;public static &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Role &lt;/span&gt;GetApplicationRole()
    {
        &lt;span style="color:blue;"&gt;return new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Role&lt;/span&gt;(2, &lt;span style="color:#a31515;"&gt;&amp;quot;ApplicationRole&amp;quot;&lt;/span&gt;);
    }
}

&lt;span style="color:blue;"&gt;public interface &lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;IUser 
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IDictionary&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;Role&lt;/span&gt;&amp;gt; Roles
    { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }
}

&lt;span style="color:blue;"&gt;public static class &lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;UserFactory
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;public static &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IUser &lt;/span&gt;Load(&lt;span style="color:#2b91af;"&gt;HttpContext &lt;/span&gt;context)
    {
        &lt;span style="color:blue;"&gt;return new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;MyUser&lt;/span&gt;(context);
    }
}

&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;MyUser &lt;/span&gt;: &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;IUser
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;public &lt;/span&gt;MyUser(&lt;span style="color:#2b91af;"&gt;HttpContext &lt;/span&gt;context)
    {
        &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// Map the context.User to MyUser ..
    &lt;/span&gt;}

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IDictionary&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;Role&lt;/span&gt;&amp;gt; Roles
    {
        &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:blue;"&gt;get
        &lt;/span&gt;{                
            &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// Get the roles from database ..
        &lt;/span&gt;}
        &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:blue;"&gt;set
        &lt;/span&gt;{
            &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// Set the roles ..
        &lt;/span&gt;}
    }
}&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;pre class="code"&gt;&lt;font size="1" face="Verdana"&gt;[&lt;span style="color:#2b91af;"&gt;ScriptService&lt;/span&gt;]
&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;MyCatalogService &lt;/span&gt;: &lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;ICatalogService
&lt;/span&gt;{
    [&lt;span style="color:#2b91af;"&gt;ScriptMethod&lt;/span&gt;]
    &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Article &lt;/span&gt;GetArticle(&lt;span style="color:blue;"&gt;int &lt;/span&gt;articleId)
    {
        &lt;span style="color:#2b91af;"&gt;Article &lt;/span&gt;article = &lt;span style="color:blue;"&gt;null&lt;/span&gt;;

        &lt;span style="color:blue;"&gt;if &lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;HttpContext&lt;/span&gt;.Current == &lt;span style="color:blue;"&gt;null&lt;/span&gt;)
        {
            &lt;span style="color:blue;"&gt;throw new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ArgumentNullException&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;HttpContext&amp;quot;&lt;/span&gt;);
        }

        &lt;span style="color:#2b91af;"&gt;IUser &lt;/span&gt;user = &lt;span style="color:#2b91af;"&gt;UserFactory&lt;/span&gt;.Load(&lt;span style="color:#2b91af;"&gt;HttpContext&lt;/span&gt;.Current);

        &lt;span style="color:blue;"&gt;if &lt;/span&gt;(user == &lt;span style="color:blue;"&gt;null&lt;/span&gt;)
        {
            &lt;span style="color:blue;"&gt;throw new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ArgumentNullException&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;IUser from HttpContext&amp;quot;&lt;/span&gt;);
        }

        &lt;span style="color:blue;"&gt;if &lt;/span&gt;(user.Roles.ContainsKey(&lt;span style="color:#2b91af;"&gt;RoleFactory&lt;/span&gt;.GetUserApplicationRole().ID))
        {
            &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;&lt;strong&gt;// Get the article from service layer ..&lt;/strong&gt;                
        &lt;/span&gt;}

        &lt;span style="color:blue;"&gt;return &lt;/span&gt;article;
    }

    &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// Other members for ICatalogService ..
&lt;/span&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p align="justify"&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;Como podemos observar, el servicio hace uso del contexto HTTP donde tenemos toda la información relativa al usuario autenticado, en este aspecto podemos :&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;div align="justify"&gt;Implementar nuestro propio mecanismo de seguridad como se hace en el ejemplo a través del objeto IPrincipal HttpContext.Current.User, o bien recibir nuestro propio objeto de autenticación en Sesión a través de HttpContext.Current.Session[“loggedUser”].&lt;/div&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;div align="justify"&gt;Usar seguridad basada en objetos IPrincipal nativos de .NET, siempre y cuando utilicemos autenticación integrada y basemos nuestra seguridad en los Roles de Windows o del Directorio Activo.&lt;/div&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p align="justify"&gt;El uso del objeto HttpContext.Current es soportado de forma nativa por los servicios web ASP.NET XML puesto que se ejecutan en el mismo “worker process” de IIS que la aplicación ASP.NET, sin embargo para usarlos en WCF debemos aplicar un poco de configuración.&lt;/p&gt;

&lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Cuando el motor de ejecución de ASP.NET recibe una petición para un recurso .SVC y comienza a procesarla la redirige al motor de ejecución de WCF se apropia de ella y no la devuelve al motor de ejecución de ASP.NET, como resultado el valor del contexto HTTP siempre es nulo.&lt;/font&gt;&lt;/p&gt;

&lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Para conseguir que ASP.NET y WCF funcionen como es debido, debemos habilitar la compatibilidad ASP.NET en WCF a través del fichero de configuración del servicio WCF :&lt;/font&gt;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;system.serviceModel&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:blue;"&gt;&amp;gt;
  &lt;strong&gt;  &amp;lt;&lt;/strong&gt;&lt;/span&gt;&lt;strong&gt;&lt;span style="color:#a31515;"&gt;serviceHostingEnvironment &lt;/span&gt;&lt;span style="color:red;"&gt;aspNetCompatibilityEnabled&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;true&lt;/span&gt;&amp;quot;&lt;/strong&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:blue;"&gt;&lt;strong&gt;/&amp;gt;&lt;/strong&gt;    
    &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;services&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;span style="color:blue;"&gt;&lt;font size="1" face="Verdana"&gt;&amp;gt;
      &amp;lt;!-- 
        &lt;/font&gt;&lt;/span&gt;&lt;span style="color:green;"&gt;&lt;font size="1" face="Verdana"&gt;Definicion de servicios ..         
          - Importante usar el enlace webHttpBinding
      &lt;/font&gt;&lt;/span&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:blue;"&gt;--&amp;gt;      
    &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;services&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:blue;"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;behaviors&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;span style="color:blue;"&gt;&lt;font size="1" face="Verdana"&gt;&amp;gt;
      &amp;lt;!-- 
        &lt;/font&gt;&lt;/span&gt;&lt;span style="color:green;"&gt;&lt;font size="1" face="Verdana"&gt;Definicion de comportamientos .. 
          - Importante usar webScriptBehaviour ..
      &lt;/font&gt;&lt;/span&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:blue;"&gt;--&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;behaviors&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:blue;"&gt;&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;system.serviceModel&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Además de habilitar la compatibilidad con ASP.NET en la configuración del servicio WCF, debemos indicarlo de forma explícita &lt;u&gt;en la implementación de los contratos&lt;/u&gt; expuestos :&lt;/font&gt;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;font size="1" face="Verdana"&gt;&lt;strong&gt;[&lt;span style="color:#2b91af;"&gt;AspNetCompatibilityRequirements&lt;/span&gt;(
    RequirementsMode = &lt;span style="color:#2b91af;"&gt;AspNetCompatibilityRequirementsMode&lt;/span&gt;.Allowed)]&lt;/strong&gt;
&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;MyCatalogService &lt;/span&gt;: &lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;ICatalogService
&lt;/span&gt;{
    &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// Service Members ..
&lt;/span&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p align="justify"&gt;Y esto es todo por hoy ..&lt;/p&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;div id="postorigin" style="margin-left:5px;font-size:80%;padding:5px;border:2px solid #BDB67C;background-color:#DDDBC7;width:300px;text-align:center;-moz-border-radius:4px 4px 4px 4px;-webkit-border-radius:4px;border-radius:4px;"&gt;&lt;a href="http://kartones.net/blogs/coco/archive/2009/12/11/la-capa-de-servicios-ajax.aspx"&gt;La Capa de Servicios AJAX&lt;/a&gt; was posted the 12/11/2009 at &lt;a href="http://Kartones.net"&gt;Kartones.Net&lt;/a&gt;.&lt;/div&gt;
&lt;div id="sharing" class="postfoot"&gt;&lt;hr /&gt;&lt;p&gt;Share via:&lt;br&gt;&lt;a rel="nofollow" href="mailto:?subject=Kartones.Net:%20La+Capa+de+Servicios+AJAX&amp;amp;body=http://kartones.net/blogs/coco/archive/2009/12/11/la-capa-de-servicios-ajax.aspx" target="_blank"&gt;Email&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.facebook.com/share.php?u=http://kartones.net/blogs/coco/archive/2009/12/11/la-capa-de-servicios-ajax.aspx&amp;amp;t=La+Capa+de+Servicios+AJAX" target="_blank"&gt;Facebook&lt;/a&gt; | &lt;a rel="nofollow" href="http://twitter.com/home?status=http://kartones.net/blogs/coco/archive/2009/12/11/la-capa-de-servicios-ajax.aspx" target="_blank"&gt;Twitter&lt;/a&gt; | &lt;a rel="nofollow" href="http://slashdot.org/bookmark.pl?url=http://kartones.net/blogs/coco/archive/2009/12/11/la-capa-de-servicios-ajax.aspx&amp;amp;title=La+Capa+de+Servicios+AJAX" target="_blank"&gt;SlashDot&lt;/a&gt; | &lt;a rel="nofollow" href="http://delicious.com/post?url=http://kartones.net/blogs/coco/archive/2009/12/11/la-capa-de-servicios-ajax.aspx&amp;amp;title=La+Capa+de+Servicios+AJAX" target="_blank"&gt;del.icio.us&lt;/a&gt; | &lt;a rel="nofollow" href="http://technorati.com/faves?add=http://kartones.net/blogs/coco/archive/2009/12/11/la-capa-de-servicios-ajax.aspx" target="_blank"&gt;Technorati&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http://kartones.net/blogs/coco/archive/2009/12/11/la-capa-de-servicios-ajax.aspx&amp;amp;title=La+Capa+de+Servicios+AJAX" target="_blank"&gt;Stumbleupon&lt;/a&gt; | &lt;a rel="nofollow" href="http://reddit.com/submit?url=http://kartones.net/blogs/coco/archive/2009/12/11/la-capa-de-servicios-ajax.aspx&amp;amp;title=La+Capa+de+Servicios+AJAX" target="_blank"&gt;Reddit&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.google.com/reader/link?url=http://kartones.net/blogs/coco/archive/2009/12/11/la-capa-de-servicios-ajax.aspx&amp;amp;title=La+Capa+de+Servicios+AJAX&amp;amp;srcUrl=http://kartones.net/blogs/coco/archive/2009/12/11/la-capa-de-servicios-ajax.aspx&amp;amp;srcTitle=La+Capa+de+Servicios+AJAX" target="_blank"&gt;Google Reader&lt;/a&gt; | &lt;a rel="nofollow" href="http://meneame.net/submit.php?url=http://kartones.net/blogs/coco/archive/2009/12/11/la-capa-de-servicios-ajax.aspx" target="_blank"&gt;Meneame&lt;/a&gt; | &lt;a rel="nofollow" href="http://bitacoras.com/anotaciones/http://kartones.net/blogs/coco/archive/2009/12/11/la-capa-de-servicios-ajax.aspx" target="_blank"&gt;Bitacoras&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.linkedin.com/shareArticle?mini=true&amp;amp;url=http://kartones.net/blogs/coco/archive/2009/12/11/la-capa-de-servicios-ajax.aspx&amp;amp;title=La+Capa+de+Servicios+AJAX&amp;amp;source=Kartones.Net" target="_blank"&gt;LinkedIn&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.google.com/bookmarks/mark?op=edit&amp;amp;bkmk=http://kartones.net/blogs/coco/archive/2009/12/11/la-capa-de-servicios-ajax.aspx&amp;amp;title=La+Capa+de+Servicios+AJAX" target="_blank"&gt;Google Bookmarks&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.google.com/reader/link?url=http://kartones.net/blogs/coco/archive/2009/12/11/la-capa-de-servicios-ajax.aspx&amp;amp;title=La+Capa+de+Servicios+AJAX" target="_blank"&gt;Google Reader&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.google.com/buzz/post?url=http://kartones.net/blogs/coco/archive/2009/12/11/la-capa-de-servicios-ajax.aspx&amp;amp;imageurl=" target="_blank"&gt;Google Buzz&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.friendfeed.com/share?title=La+Capa+de+Servicios+AJAX&amp;amp;link=http://kartones.net/blogs/coco/archive/2009/12/11/la-capa-de-servicios-ajax.aspx" target="_blank"&gt;FriendFeed&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.netvibes.com/share?title=La+Capa+de+Servicios+AJAX&amp;amp;url=http://kartones.net/blogs/coco/archive/2009/12/11/la-capa-de-servicios-ajax.aspx" target="_blank"&gt;Netvibes&lt;/a&gt; | &lt;a rel="nofollow" href="https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;mkt=es-es&amp;amp;url=http://kartones.net/blogs/coco/archive/2009/12/11/la-capa-de-servicios-ajax.aspx&amp;amp;title=La+Capa+de+Servicios+AJAX" target="_blank"&gt;Windows Live&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.myspace.com/Modules/PostTo/Pages/?u=http://kartones.net/blogs/coco/archive/2009/12/11/la-capa-de-servicios-ajax.aspx&amp;amp;t=La+Capa+de+Servicios+AJAX" target="_blank"&gt;MySpace&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;img src="http://kartones.net/aggbug.aspx?PostID=50595" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/ElFrameworkDeCoco/~4/PQ1joNKgTQc" height="1" width="1"/&gt;</description><category domain="http://kartones.net/blogs/coco/archive/tags/Capa+de+Servicios/default.aspx">Capa de Servicios</category><category domain="http://kartones.net/blogs/coco/archive/tags/AJAX/default.aspx">AJAX</category><category domain="http://kartones.net/blogs/coco/archive/tags/WCF/default.aspx">WCF</category><feedburner:origLink>http://kartones.net/blogs/coco/archive/2009/12/11/la-capa-de-servicios-ajax.aspx</feedburner:origLink></item><item><title>SOA : Arquitectura Orientada a Servicios</title><link>http://feeds.kartones.net/~r/ElFrameworkDeCoco/~3/4I1swFX2Bqk/soa-arquitectura-orientada-a-servicios.aspx</link><pubDate>Tue, 08 Dec 2009 19:19:18 GMT</pubDate><guid isPermaLink="false">b86c0850-82e5-42ed-a9d8-bde9e8f94ec1:50591</guid><dc:creator>ccrego</dc:creator><slash:comments>0</slash:comments><comments>http://kartones.net/blogs/coco/archive/2009/12/08/soa-arquitectura-orientada-a-servicios.aspx#comments</comments><description>&lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;La arquitectura orientada a servicios es un paradigma de programación cuyo objetivo es ver la funcionalidad de un sistema como una colección de procesos de negocio que son expuestos como servicios altamente interoperables.&lt;/font&gt;&lt;/p&gt;  &lt;p align="justify"&gt;Uno de los valores de SOA, es que nos empuja a modelar procesos de negocio débilmente acoplados y altamente interoperables a través de estándares abiertos.&lt;/p&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Una solución SOA se compone de servicios que pueden haber sido implementados en distintos lenguajes de programación y estar alojados en diferentes plataformas.&lt;/font&gt;&lt;/p&gt;  &lt;p align="justify"&gt;Los principios de SOA son :&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;     &lt;div align="justify"&gt;Control limitado&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;Autonomía&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;Uso de contratos en lugar de clases&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;Compatibilidad semántica&lt;/div&gt;   &lt;/li&gt; &lt;/ol&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;El principio de “Control limitado” hace referencia a que cualquier interacción con un servicio se realiza a través de la interfaz pública del mismo donde los parámetros de entrada de los métodos representan los mensajes enviados al servicio.&lt;/font&gt;&lt;/p&gt;  &lt;p align="justify"&gt;A la interfaz pública de un servicio se la conoce como “Contrato de servicio”.&lt;/p&gt;  &lt;p align="justify"&gt;Es muy importante por tanto diseñar un contrato de servicio guardando toda la sencillez que nos sea posible, esto implica :&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;     &lt;div align="justify"&gt;No usar objetos con referencias circulares en los parámetros de entrada y en los valores de retorno.&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;Usar parámetros de entrada y valores de retorno tipados.&lt;/div&gt;   &lt;/li&gt; &lt;/ol&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;El principio de “Autonomía” hace referencia al concepto de servicios débilmente acoplados que puedan diseñarse y ser desplegados independientemente del resto de servicios, pero que a su vez sean capaces de comunicarse con otros a través de contratos y políticas.&lt;/font&gt;&lt;/p&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;En SOA, los servicios se comunican mediante el intercambio de contratos de datos. &lt;/font&gt;&lt;/p&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Un contrato de datos se traduce en una clase que se compone exclusivamente de propiedades y que viene a representar a un objeto DTO que no tiene nada que ver con los objetos del modelo de dominio.&lt;/font&gt;&lt;/p&gt;  &lt;p align="justify"&gt;En resumen, un contrato de datos agrupa los parámetros de entrada de un servicio.&lt;/p&gt;  &lt;p align="justify"&gt;Sin embargo los contratos de servicio y los contratos de datos no son demasiado importantes si el servicio no hace exactamente lo que el consumidor espera de el.&lt;/p&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;La información relativa a la funcionalidad de un servicio es conocida como “semántica de servicio”, dicha semántica debe ser expuesta y descubierta a través de políticas.&lt;/font&gt;&lt;/p&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Para expresar políticas a nivel de servicio y poder descubrirlas es necesario usar la especificación WS-Policy.&lt;/font&gt;&lt;/p&gt;  &lt;p align="justify"&gt;Construir un sistema basado en SOA, es un proceso incremental que no requiere de una revisión completa de los procesos de negocio existentes.&lt;/p&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;SOA habla de servicios, pero los servicios no son un tipo concreto de tecnología y usar servicios en una aplicación no implica que nuestra aplicación use SOA.&lt;/font&gt;&lt;/p&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Lo que nos tiene que quedar claro es que SOA es un conjunto de principios que inspiran buenas prácticas en el diseño de servicios.&lt;/font&gt;&lt;/p&gt;  &lt;p align="justify"&gt;Hay mucha gente que tiene por costumbre relacionar SOA con los servicios web, sin embargo los servicios web no tienen nada que ver con SOA :&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;     &lt;div align="justify"&gt;Una aplicación que use servicios web no es una aplicación SOA&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;Un servicio web no es SOA si no cumple con los 4 principios que acabo de mencionar.&lt;/div&gt;   &lt;/li&gt; &lt;/ol&gt;  &lt;p align="justify"&gt;Hubo un tiempo en que se hablaba mucho sobre SOA y sus ventajas, y entonces todo el mundo se intereso por el tema, sin embargo SOA no es una revolución ya que sus principios fueron escritos hace mas de 15 años.&lt;/p&gt;  &lt;p align="justify"&gt;Nosotros como desarrolladores deberíamos centrarnos en el problema que debemos resolver y pensar en una solución eficaz, en el caso de sistemas distribuidos, para dar forma a nuestra solución debemos identificar los servicios que modelan la solución.&lt;/p&gt;  &lt;p align="justify"&gt;Aplicar los principios SOA a una capa de servicios significa tener contratos de servicios bien definidos que actúen como fachada de la lógica de negocio, para conseguirlo podemos seguir las siguientes reglas prácticas :&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;     &lt;div align="justify"&gt;Los servicios de la capa de servicios no implementan lógica de negocio, en su lugar la exponen y consumen.&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;El intercambio de datos ocurre a través de objetos DTO y no a través de clases del modelo de objetos de dominio.&lt;/li&gt;    &lt;li&gt;Los servicios no distribuyen objetos ni trabajan sobre ellos, en su lugar se limitan a devolver una colección de valores a través de un formato.&lt;/li&gt;    &lt;li&gt;Los servicios de la capa de servicios deben estar enfocados hacia una interfaz de usuario.&lt;/li&gt;    &lt;li&gt;Cualquier servicio con una interfaz basada en objetos tiende a exponer operaciones CRUD, estos servicios son conocidos como CRUDy, y por tanto no son SOA.&lt;/li&gt;    &lt;li&gt;Aplicar versionado y extensibilidad sin modificar los contratos de datos y de servicio.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Veamos un ejemplo de servicios CRUDy :&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&lt;font size="1" face="Verdana"&gt;public interface &lt;/font&gt;&lt;/span&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;IEmployeeService
&lt;/span&gt;{
    &lt;span style="color:#2b91af;"&gt;FindEmployeeByIDResponse &lt;/span&gt;FindEmployeeById(&lt;span style="color:#2b91af;"&gt;FindEmployeeByIDRequest &lt;/span&gt;request);

    &lt;span style="color:#2b91af;"&gt;CreateEmployeeResponse &lt;/span&gt;CreateEmployee(&lt;span style="color:#2b91af;"&gt;CreateEmployeeRequest &lt;/span&gt;request);

    &lt;span style="color:#2b91af;"&gt;UpdateEmployeeResponse &lt;/span&gt;UpdateEmployee(&lt;span style="color:#2b91af;"&gt;UpdateEmployeeRequest &lt;/span&gt;request);

    &lt;span style="color:#2b91af;"&gt;DeleteEmployeeResponse &lt;/span&gt;DeleteEmployee(&lt;span style="color:#2b91af;"&gt;DeleteEmployeeRequest &lt;/span&gt;request);
}&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p align="justify"&gt;Antes de ponernos manos a la obra para implementar un servicio CRUDy, debemos asegurarnos que tenemos casos de uso que utilizan funcionalidad de alta, baja y modificación.&lt;/p&gt;

&lt;p align="justify"&gt;Sin embargo, en un servicio debemos evitar a toda costa tener métodos que sean más específicos que los casos de uso que los consumen.&lt;/p&gt;

&lt;p align="justify"&gt;Imaginemos que para registrar un empleado debemos realizar los siguientes pasos :&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;div align="justify"&gt;Comprobar que el DNI no existe en base de datos&lt;/div&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;div align="justify"&gt;Registrar los datos en base de datos&lt;/div&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;div align="justify"&gt;Obtener el identificador generado&lt;/div&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p align="justify"&gt;Si encapsulamos toda esta funcionalidad en el método CreateEmployee de nuestro servicio IEmployeeService, estaremos haciendo lo correcto, en caso contrario, si exponemos un método para cada paso, estaremos aplicando el antipatrón CRUDy.&lt;/p&gt;

&lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Las interfaces que aplican el antipatrón CRUDy, se conocen como “interfaces chatty”, y se caracterizan por exponer un conjunto de métodos que deben ser llamados en secuencia desde la capa de presentación para cumplir con un determinado caso de uso.&lt;/font&gt;&lt;/p&gt;

&lt;p align="justify"&gt;Y esto ha sido todo por hoy (ahora sí, que ya toca cena) …&lt;/p&gt;
&lt;div id="postorigin" style="margin-left:5px;font-size:80%;padding:5px;border:2px solid #BDB67C;background-color:#DDDBC7;width:300px;text-align:center;-moz-border-radius:4px 4px 4px 4px;-webkit-border-radius:4px;border-radius:4px;"&gt;&lt;a href="http://kartones.net/blogs/coco/archive/2009/12/08/soa-arquitectura-orientada-a-servicios.aspx"&gt;SOA : Arquitectura Orientada a Servicios&lt;/a&gt; was posted the 12/08/2009 at &lt;a href="http://Kartones.net"&gt;Kartones.Net&lt;/a&gt;.&lt;/div&gt;
&lt;div id="sharing" class="postfoot"&gt;&lt;hr /&gt;&lt;p&gt;Share via:&lt;br&gt;&lt;a rel="nofollow" href="mailto:?subject=Kartones.Net:%20SOA+%3a+Arquitectura+Orientada+a+Servicios&amp;amp;body=http://kartones.net/blogs/coco/archive/2009/12/08/soa-arquitectura-orientada-a-servicios.aspx" target="_blank"&gt;Email&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.facebook.com/share.php?u=http://kartones.net/blogs/coco/archive/2009/12/08/soa-arquitectura-orientada-a-servicios.aspx&amp;amp;t=SOA+%3a+Arquitectura+Orientada+a+Servicios" target="_blank"&gt;Facebook&lt;/a&gt; | &lt;a rel="nofollow" href="http://twitter.com/home?status=http://kartones.net/blogs/coco/archive/2009/12/08/soa-arquitectura-orientada-a-servicios.aspx" target="_blank"&gt;Twitter&lt;/a&gt; | &lt;a rel="nofollow" href="http://slashdot.org/bookmark.pl?url=http://kartones.net/blogs/coco/archive/2009/12/08/soa-arquitectura-orientada-a-servicios.aspx&amp;amp;title=SOA+%3a+Arquitectura+Orientada+a+Servicios" target="_blank"&gt;SlashDot&lt;/a&gt; | &lt;a rel="nofollow" href="http://delicious.com/post?url=http://kartones.net/blogs/coco/archive/2009/12/08/soa-arquitectura-orientada-a-servicios.aspx&amp;amp;title=SOA+%3a+Arquitectura+Orientada+a+Servicios" target="_blank"&gt;del.icio.us&lt;/a&gt; | &lt;a rel="nofollow" href="http://technorati.com/faves?add=http://kartones.net/blogs/coco/archive/2009/12/08/soa-arquitectura-orientada-a-servicios.aspx" target="_blank"&gt;Technorati&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http://kartones.net/blogs/coco/archive/2009/12/08/soa-arquitectura-orientada-a-servicios.aspx&amp;amp;title=SOA+%3a+Arquitectura+Orientada+a+Servicios" target="_blank"&gt;Stumbleupon&lt;/a&gt; | &lt;a rel="nofollow" href="http://reddit.com/submit?url=http://kartones.net/blogs/coco/archive/2009/12/08/soa-arquitectura-orientada-a-servicios.aspx&amp;amp;title=SOA+%3a+Arquitectura+Orientada+a+Servicios" target="_blank"&gt;Reddit&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.google.com/reader/link?url=http://kartones.net/blogs/coco/archive/2009/12/08/soa-arquitectura-orientada-a-servicios.aspx&amp;amp;title=SOA+%3a+Arquitectura+Orientada+a+Servicios&amp;amp;srcUrl=http://kartones.net/blogs/coco/archive/2009/12/08/soa-arquitectura-orientada-a-servicios.aspx&amp;amp;srcTitle=SOA+%3a+Arquitectura+Orientada+a+Servicios" target="_blank"&gt;Google Reader&lt;/a&gt; | &lt;a rel="nofollow" href="http://meneame.net/submit.php?url=http://kartones.net/blogs/coco/archive/2009/12/08/soa-arquitectura-orientada-a-servicios.aspx" target="_blank"&gt;Meneame&lt;/a&gt; | &lt;a rel="nofollow" href="http://bitacoras.com/anotaciones/http://kartones.net/blogs/coco/archive/2009/12/08/soa-arquitectura-orientada-a-servicios.aspx" target="_blank"&gt;Bitacoras&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.linkedin.com/shareArticle?mini=true&amp;amp;url=http://kartones.net/blogs/coco/archive/2009/12/08/soa-arquitectura-orientada-a-servicios.aspx&amp;amp;title=SOA+%3a+Arquitectura+Orientada+a+Servicios&amp;amp;source=Kartones.Net" target="_blank"&gt;LinkedIn&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.google.com/bookmarks/mark?op=edit&amp;amp;bkmk=http://kartones.net/blogs/coco/archive/2009/12/08/soa-arquitectura-orientada-a-servicios.aspx&amp;amp;title=SOA+%3a+Arquitectura+Orientada+a+Servicios" target="_blank"&gt;Google Bookmarks&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.google.com/reader/link?url=http://kartones.net/blogs/coco/archive/2009/12/08/soa-arquitectura-orientada-a-servicios.aspx&amp;amp;title=SOA+%3a+Arquitectura+Orientada+a+Servicios" target="_blank"&gt;Google Reader&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.google.com/buzz/post?url=http://kartones.net/blogs/coco/archive/2009/12/08/soa-arquitectura-orientada-a-servicios.aspx&amp;amp;imageurl=" target="_blank"&gt;Google Buzz&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.friendfeed.com/share?title=SOA+%3a+Arquitectura+Orientada+a+Servicios&amp;amp;link=http://kartones.net/blogs/coco/archive/2009/12/08/soa-arquitectura-orientada-a-servicios.aspx" target="_blank"&gt;FriendFeed&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.netvibes.com/share?title=SOA+%3a+Arquitectura+Orientada+a+Servicios&amp;amp;url=http://kartones.net/blogs/coco/archive/2009/12/08/soa-arquitectura-orientada-a-servicios.aspx" target="_blank"&gt;Netvibes&lt;/a&gt; | &lt;a rel="nofollow" href="https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;mkt=es-es&amp;amp;url=http://kartones.net/blogs/coco/archive/2009/12/08/soa-arquitectura-orientada-a-servicios.aspx&amp;amp;title=SOA+%3a+Arquitectura+Orientada+a+Servicios" target="_blank"&gt;Windows Live&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.myspace.com/Modules/PostTo/Pages/?u=http://kartones.net/blogs/coco/archive/2009/12/08/soa-arquitectura-orientada-a-servicios.aspx&amp;amp;t=SOA+%3a+Arquitectura+Orientada+a+Servicios" target="_blank"&gt;MySpace&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;img src="http://kartones.net/aggbug.aspx?PostID=50591" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/ElFrameworkDeCoco/~4/4I1swFX2Bqk" height="1" width="1"/&gt;</description><category domain="http://kartones.net/blogs/coco/archive/tags/Antipatr_F300_n+CRUDy/default.aspx">Antipatrón CRUDy</category><category domain="http://kartones.net/blogs/coco/archive/tags/SOA/default.aspx">SOA</category><feedburner:origLink>http://kartones.net/blogs/coco/archive/2009/12/08/soa-arquitectura-orientada-a-servicios.aspx</feedburner:origLink></item><item><title>La Capa de Servicios : Patrones</title><link>http://feeds.kartones.net/~r/ElFrameworkDeCoco/~3/BdLgAtzcsGE/la-capa-de-servicios-patrones.aspx</link><pubDate>Tue, 08 Dec 2009 13:39:36 GMT</pubDate><guid isPermaLink="false">b86c0850-82e5-42ed-a9d8-bde9e8f94ec1:50589</guid><dc:creator>ccrego</dc:creator><slash:comments>0</slash:comments><comments>http://kartones.net/blogs/coco/archive/2009/12/08/la-capa-de-servicios-patrones.aspx#comments</comments><description>&lt;p align="justify"&gt;La lógica de aplicación que se espera de una capa de servicios es esencialmente :&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;     &lt;div align="justify"&gt;Gestión de roles&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;Validación de datos&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;Notificación&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;Adaptación de datos a la interfaz de usuario &lt;/div&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;&lt;u&gt;El patrón Remote Facade&lt;/u&gt; se aplica a través de un conjunto de métodos que modifican la granularidad de las operaciones existentes, no implementa nuevas funcionalidades, en su lugar, crea una fachada sobre una API existente.&lt;/font&gt;&lt;/p&gt;  &lt;p align="justify"&gt;El patrón Remote Facade modifica el modo en que se accede a un conjunto de objetos, es decir, si queremos tratar con una versión simplificada de una API, debemos crear una fachada que es precisamente la definición de este patrón.&lt;/p&gt;  &lt;p align="justify"&gt;Imaginemos que tenemos el siguiente contrato en una capa de servicios local :&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&lt;font size="1" face="Verdana"&gt;public interface &lt;/font&gt;&lt;/span&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;IEmployeeService
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;int &lt;/span&gt;Create(&lt;span style="color:#2b91af;"&gt;Employee &lt;/span&gt;employee);

    &lt;span style="color:blue;"&gt;int &lt;/span&gt;Update(&lt;span style="color:#2b91af;"&gt;Employee &lt;/span&gt;employee);

    &lt;span style="color:#2b91af;"&gt;IList&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Employee&lt;/span&gt;&amp;gt; FindAll();

    &lt;span style="color:#2b91af;"&gt;Employee &lt;/span&gt;FindById(&lt;span style="color:blue;"&gt;int &lt;/span&gt;employeeId);

    &lt;span style="color:#2b91af;"&gt;Employee &lt;/span&gt;GetBoss(&lt;span style="color:blue;"&gt;int &lt;/span&gt;employeeId);

    &lt;span style="color:#2b91af;"&gt;Department &lt;/span&gt;GetDepartment(&lt;span style="color:blue;"&gt;int &lt;/span&gt;employeeId);

    &lt;span style="color:#2b91af;"&gt;IList&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Employee&lt;/span&gt;&amp;gt; GetSubordinates(&lt;span style="color:blue;"&gt;int &lt;/span&gt;employeeId);
}&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p align="justify"&gt;Ahora el mismo contrato, pero preparado para ser expuesto de forma remota con WCF :&lt;/p&gt;

&lt;p align="justify"&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;[&lt;span style="color:#2b91af;"&gt;ServiceContract&lt;/span&gt;] 

      &lt;br /&gt;&lt;span style="color:blue;"&gt;public interface&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;IEmployeeService 
        &lt;br /&gt;&lt;/span&gt;{ 

      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="color:#2b91af;"&gt;OperationContract&lt;/span&gt;] 

      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;int &lt;/span&gt;Create(&lt;span style="color:#2b91af;"&gt;Employee &lt;/span&gt;employee); 

      &lt;br /&gt;

      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="color:#2b91af;"&gt;OperationContract&lt;/span&gt;] 

      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;int &lt;/span&gt;Update(&lt;span style="color:#2b91af;"&gt;Employee &lt;/span&gt;employee); 

      &lt;br /&gt;

      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="color:#2b91af;"&gt;OperationContract&lt;/span&gt;] 

      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;IList&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Employee&lt;/span&gt;&amp;gt; FindAll(); 

      &lt;br /&gt;

      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="color:#2b91af;"&gt;OperationContract&lt;/span&gt;] 

      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;Employee &lt;/span&gt;FindById(&lt;span style="color:blue;"&gt;int &lt;/span&gt;employeeId); 

      &lt;br /&gt;

      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="color:#2b91af;"&gt;OperationContract&lt;/span&gt;] 

      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;Employee &lt;/span&gt;GetBoss(&lt;span style="color:blue;"&gt;int &lt;/span&gt;employeeId); 

      &lt;br /&gt;

      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="color:#2b91af;"&gt;OperationContract&lt;/span&gt;] 

      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;Department &lt;/span&gt;GetDepartment(&lt;span style="color:blue;"&gt;int &lt;/span&gt;employeeId); 

      &lt;br /&gt;

      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="color:#2b91af;"&gt;OperationContract&lt;/span&gt;] 

      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;IList&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Employee&lt;/span&gt;&amp;gt; GetSubordinates(&lt;span style="color:blue;"&gt;int &lt;/span&gt;employeeId); 

      &lt;br /&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;Ahora la pregunta es, ¿Cuando necesitamos aplicar el patrón Remote Facade?.&lt;/p&gt;

&lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Usaremos el patrón Remote Facade cuando tengamos que refactorizar la capa de servicios a una interfaz más simplificada del contrato IEmployeeService, o cuando tengamos que hacer uso de objetos DTO en la firma de los métodos :&lt;/font&gt;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&lt;font size="1" face="Verdana"&gt;public interface &lt;/font&gt;&lt;/span&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;IEmployeeServiceRF
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;int &lt;/span&gt;Create(&lt;span style="color:#2b91af;"&gt;EmployeeDto &lt;/span&gt;employee);

    &lt;span style="color:blue;"&gt;int &lt;/span&gt;Update(&lt;span style="color:#2b91af;"&gt;EmployeeDto &lt;/span&gt;employee);

    &lt;span style="color:#2b91af;"&gt;IList&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;EmployeeDto&lt;/span&gt;&amp;gt; FindAll();

    &lt;span style="color:#2b91af;"&gt;EmployeeDto &lt;/span&gt;FindById(&lt;span style="color:blue;"&gt;int &lt;/span&gt;employeeId);

    &lt;span style="color:#2b91af;"&gt;EmployeeDto &lt;/span&gt;GetBoss(&lt;span style="color:blue;"&gt;int &lt;/span&gt;employeeId);    

    &lt;span style="color:#2b91af;"&gt;IList&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;EmployeeDto&lt;/span&gt;&amp;gt; GetSubordinates(&lt;span style="color:blue;"&gt;int &lt;/span&gt;employeeId);
}&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p align="justify"&gt;La clase EmployeeDto puede ser un subconjunto o un superconjunto del objeto de dominio Employee (puede incluir el objeto Department).&lt;/p&gt;

&lt;p align="justify"&gt;----------------------------------------------------------------------------------------------------------&lt;/p&gt;

&lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;&lt;u&gt;El patrón DTO&lt;/u&gt; se aplica creando objetos que conducen datos a través de las capas de una aplicación, con el objetivo principal de reducir los accesos a base de datos y minimizar el acoplamiento entre la capa de presentación y el modelo de dominio.&lt;/font&gt;&lt;/p&gt;

&lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;&lt;font color="#000000"&gt;Sea cual sea la motivación que nos lleve a usar objetos DTO, debemos tener muy en cuenta que&lt;/font&gt; un objeto DTO solo expone propiedades.&lt;/font&gt;&lt;/p&gt;

&lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;&lt;font color="#000000"&gt;Lo que está claro es que&lt;/font&gt; &lt;u&gt;no podemos usar objetos nativos del modelo de dominio en todas las capas de servicios, esto solo es posible si la capa de presentación y la capa de servicios están alojadas en la mismo lugar, como por ejemplo en una capa de presentación web.&lt;/u&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;&lt;u&gt;Si una capa de servicios está ubicada en otra capa es muy normal usar objetos DTO en lugar de objetos nativos del dominio.&lt;/u&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Tanto WCF como los servicios web tradicionales no pueden serializar objetos con referencias circulares puesto que están basados en serialización XML y este es uno de los motivos que nos lleva muchas veces a usar objetos DTO en capas de servicios remotas, veamos un ejemplo de referencias circulares en un modelo de dominio :&lt;/font&gt;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&lt;font size="1" face="Verdana"&gt;public class &lt;/font&gt;&lt;/span&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;Section
&lt;/span&gt;{
    &lt;/font&gt;&lt;/font&gt;&lt;span style="color:gray;"&gt;&lt;font size="1" face="Verdana"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/font&gt;&lt;/span&gt;&lt;span style="color:green;"&gt;&lt;font size="1" face="Verdana"&gt;A section of a shopping center has a manager
    &lt;/font&gt;&lt;/span&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Manager &lt;/span&gt;Manager
    {
        &lt;span style="color:blue;"&gt;get&lt;/span&gt;;
        &lt;span style="color:blue;"&gt;set&lt;/span&gt;;
    }

    &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// Other properties ..
&lt;/span&gt;}

&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;Manager
&lt;/span&gt;{
    &lt;/font&gt;&lt;/font&gt;&lt;span style="color:gray;"&gt;&lt;font size="1" face="Verdana"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/font&gt;&lt;/span&gt;&lt;span style="color:green;"&gt;&lt;font size="1" face="Verdana"&gt;A manager of a shopping center runs a section
    &lt;/font&gt;&lt;/span&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Section &lt;/span&gt;Section
    {
        &lt;span style="color:blue;"&gt;get&lt;/span&gt;;
        &lt;span style="color:blue;"&gt;set&lt;/span&gt;;
    }

    &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// Other properties ..
&lt;/span&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;&lt;u&gt;Sin embargo la serialización binaria si soporta referencias circulares.&lt;/u&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;&lt;u&gt;Se recomienda usar objetos DTO para encapsular los parámetros de entrada y los valores de retorno de los métodos de la capa de servicios.&lt;/u&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;&lt;font color="#000000"&gt;Tener objetos DTO en la firma de los métodos de una capa de servicios añade una nueva capa de abstracción, y por tanto un nivel más de complejidad.&lt;/font&gt; &lt;/font&gt;&lt;/p&gt;

&lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;&lt;u&gt;No es aconsejable usar objetos DTO cuando tenemos que trabajar con un modelo de dominio complejo ya que por cada objeto del dominio podríamos :&lt;/u&gt;&lt;/font&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;div align="justify"&gt;&lt;font color="#ff8040"&gt;&lt;u&gt;Tener de 1..N objetos DTO&lt;/u&gt;&lt;/font&gt;&lt;/div&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;div align="justify"&gt;&lt;font color="#ff8040"&gt;&lt;u&gt;Por cada DTO tener una clase que adapte la intefaz del objeto de dominio&lt;/u&gt;&lt;/font&gt;&lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Como nos podemos imaginar en esta situación la refactorización del modelo de dominio se puede convertir en una autentica pesadilla.&lt;/font&gt;&lt;/p&gt;

&lt;p align="justify"&gt;Cuando usamos objetos DTO en aplicaciones multicapa en algún momento tenemos que convertir los objetos del modelo de dominio a objetos DTO y es entonces cuando deberíamos hacer uso del patrón Adapter.&lt;/p&gt;

&lt;p align="justify"&gt;----------------------------------------------------------------------------------------------------------&lt;/p&gt;

&lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;&lt;u&gt;El patrón &lt;/u&gt;&lt;/font&gt;&lt;font color="#ff8040"&gt;&lt;u&gt;Adapter&lt;/u&gt; convierte la interfaz de una clase en otra y viceversa, a este proceso se le conoce como adaptación de interfaces, s&lt;/font&gt;&lt;font color="#ff8040"&gt;in embargo, como acabo de explicar antes en un modelo de dominio complejo, los objetos DTO y los objetos Adapter añaden sobrecarga.&lt;/font&gt;&lt;/p&gt;

&lt;p align="justify"&gt;Veamos un ejemplo de la implementación del patrón Adapter :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&lt;font size="1" face="Verdana"&gt;public class &lt;/font&gt;&lt;/span&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;Employee 
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;private &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;EmployeeAdapter &lt;/span&gt;_adapter;

    &lt;span style="color:blue;"&gt;public int &lt;/span&gt;ID   
    { &lt;span style="color:blue;"&gt;get&lt;/span&gt;;&lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;public string &lt;/span&gt;Name
    { &lt;span style="color:blue;"&gt;get&lt;/span&gt;;&lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;public string &lt;/span&gt;FirstSurname
    { &lt;span style="color:blue;"&gt;get&lt;/span&gt;;&lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;public string &lt;/span&gt;SecondSurname
    { &lt;span style="color:blue;"&gt;get&lt;/span&gt;;&lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;public bool &lt;/span&gt;IsExternal
    { &lt;span style="color:blue;"&gt;get&lt;/span&gt;;&lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;public string &lt;/span&gt;DNI
    { &lt;span style="color:blue;"&gt;get&lt;/span&gt;;&lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DateTime &lt;/span&gt;CreationDate
    { &lt;span style="color:blue;"&gt;get&lt;/span&gt;;&lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;Employee() { }

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;Employee(&lt;span style="color:#2b91af;"&gt;EmployeeDTO &lt;/span&gt;employeeDTO)
    {
        _adapter = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;EmployeeAdapter&lt;/span&gt;(employeeDTO);
        _adapter.Initialize(&lt;span style="color:blue;"&gt;this&lt;/span&gt;);
    }
}

&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;EmployeeDTO
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;private &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;EmployeeDTOAdapter &lt;/span&gt;_adapter;

    &lt;span style="color:blue;"&gt;public int &lt;/span&gt;ID
    { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;public string &lt;/span&gt;FullName
    { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;public bool &lt;/span&gt;IsExternal
    { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;public string &lt;/span&gt;DNI
    { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DateTime &lt;/span&gt;CreationDate
    { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;EmployeeDTO() { }

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;EmployeeDTO(&lt;span style="color:#2b91af;"&gt;Employee &lt;/span&gt;employee)
    {
        _adapter = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;EmployeeDTOAdapter&lt;/span&gt;(employee);
        _adapter.Initialize(&lt;span style="color:blue;"&gt;this&lt;/span&gt;);
    }
}

&lt;span style="color:blue;"&gt;internal class &lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;EmployeeDTOAdapter
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;private &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Employee &lt;/span&gt;_employee;

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;EmployeeDTOAdapter(&lt;span style="color:#2b91af;"&gt;Employee &lt;/span&gt;employee)
    {
        _employee = employee;
    }

    &lt;span style="color:blue;"&gt;public void &lt;/span&gt;Initialize(&lt;span style="color:#2b91af;"&gt;EmployeeDTO &lt;/span&gt;employeeDTO)
    {
        employeeDTO.ID = _employee.ID;
        employeeDTO.DNI = _employee.DNI;            
        employeeDTO.FullName = &lt;span style="color:blue;"&gt;string&lt;/span&gt;.Format(&lt;span style="color:#a31515;"&gt;&amp;quot;{2} {1}, {0}&amp;quot;&lt;/span&gt;, _employee.Name, 
                                                                                       _employee.FirstSurname, 
                                                                                       _employee.SecondSurname);            
        employeeDTO.IsExternal = _employee.IsExternal;
        employeeDTO.CreationDate = _employee.CreationDate;
    }
}

&lt;span style="color:blue;"&gt;internal class &lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;EmployeeAdapter
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;private &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;EmployeeDTO &lt;/span&gt;_employeeDTO;

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;EmployeeAdapter(&lt;span style="color:#2b91af;"&gt;EmployeeDTO &lt;/span&gt;employeeDTO)
    {
        _employeeDTO = employeeDTO;
    }

    &lt;span style="color:blue;"&gt;public void &lt;/span&gt;Initialize(&lt;span style="color:#2b91af;"&gt;Employee &lt;/span&gt;employee)
    {
        employee.ID = _employeeDTO.ID;            
        employee.DNI = _employeeDTO.DNI;

        &lt;span style="color:blue;"&gt;string&lt;/span&gt;[] fullNameSplitComma = _employeeDTO.FullName.Split(&lt;span style="color:#a31515;"&gt;&amp;#39;,&amp;#39;&lt;/span&gt;);
        employee.Name = fullNameSplitComma[1];

        &lt;span style="color:blue;"&gt;string&lt;/span&gt;[] surNamesSplitSpace = fullNameSplitComma[0].Split(&lt;span style="color:#a31515;"&gt;&amp;#39; &amp;#39;&lt;/span&gt;);
        employee.FirstSurname = surNamesSplitSpace[1];
        employee.SecondSurname = surNamesSplitSpace[0];

        employee.IsExternal = _employeeDTO.IsExternal;
        employee.CreationDate = _employeeDTO.CreationDate;
    }
}

&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;TestAdapters
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;public void &lt;/span&gt;Run()
    {
        &lt;span style="color:#2b91af;"&gt;Employee &lt;/span&gt;employee = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Employee&lt;/span&gt;()
        {
            ID = 1,
            Name = &lt;span style="color:#a31515;"&gt;&amp;quot;Carlos&amp;quot;&lt;/span&gt;,
            FirstSurname = &lt;span style="color:#a31515;"&gt;&amp;quot;Crego&amp;quot;&lt;/span&gt;,
            SecondSurname = &lt;span style="color:#a31515;"&gt;&amp;quot;Sanchez&amp;quot;&lt;/span&gt;,
            DNI = &lt;span style="color:#a31515;"&gt;&amp;quot;52497274G&amp;quot;&lt;/span&gt;,
            IsExternal = &lt;span style="color:blue;"&gt;true&lt;/span&gt;,
            CreationDate = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DateTime&lt;/span&gt;(1981, 7, 16)
        };

        &lt;span style="color:#2b91af;"&gt;EmployeeDTO &lt;/span&gt;employeeDto = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;EmployeeDTO&lt;/span&gt;(employee);

        &lt;span style="color:#2b91af;"&gt;Employee &lt;/span&gt;empAdapted = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Employee&lt;/span&gt;(employeeDto);
    }
}&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;Como podemos observar en el ejemplo, para tener una adaptación bidireccional, debemos construir dos clases “Adapter” :&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Una clase Adapter para convertir un objeto del modelo de dominio en un objeto DTO &lt;/li&gt;

  &lt;li&gt;Una clase Adapter para convertir un objeto DTO en un objeto del modelo de dominio. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Terminare de hablar del patrón Adapter con el siguiente trozo de código que seguro que os será muy familiar si alguna vez os habeis pegado con WCF :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&lt;font size="1" face="Verdana"&gt;public static class &lt;/font&gt;&lt;/span&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;EmployeeRepository 
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;public static &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Employee &lt;/span&gt;GetById(&lt;span style="color:blue;"&gt;int &lt;/span&gt;employeeId)
    {
        &lt;span style="color:#2b91af;"&gt;Employee &lt;/span&gt;emp = &lt;span style="color:blue;"&gt;null&lt;/span&gt;;

        &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// Gets the employee from the database ..

        &lt;/span&gt;&lt;span style="color:blue;"&gt;return &lt;/span&gt;emp;
    }
}

&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;EmployeeServiceFindByIdRequest
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;public int &lt;/span&gt;ID   
    { &lt;span style="color:blue;"&gt;get&lt;/span&gt;;&lt;span style="color:blue;"&gt;set&lt;/span&gt;; }
}

&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;EmployeeServiceFindByIdResponse 
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;public int &lt;/span&gt;ID   
    { &lt;span style="color:blue;"&gt;get&lt;/span&gt;;&lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;public string &lt;/span&gt;Name
    { &lt;span style="color:blue;"&gt;get&lt;/span&gt;;&lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;public string &lt;/span&gt;FirstSurname
    { &lt;span style="color:blue;"&gt;get&lt;/span&gt;;&lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;public string &lt;/span&gt;SecondSurname
    { &lt;span style="color:blue;"&gt;get&lt;/span&gt;;&lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;public bool &lt;/span&gt;IsExternal
    { &lt;span style="color:blue;"&gt;get&lt;/span&gt;;&lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;public string &lt;/span&gt;DNI
    { &lt;span style="color:blue;"&gt;get&lt;/span&gt;;&lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DateTime &lt;/span&gt;CreationDate
    { &lt;span style="color:blue;"&gt;get&lt;/span&gt;;&lt;span style="color:blue;"&gt;set&lt;/span&gt;; }
}

&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;EmployeeServiceFindByIdAdapter
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;private &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Employee &lt;/span&gt;_employee;

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;EmployeeServiceFindByIdAdapter(&lt;span style="color:#2b91af;"&gt;Employee &lt;/span&gt;employee)
    {
        _employee = employee;
    }

    &lt;span style="color:blue;"&gt;public void &lt;/span&gt;Initialize(&lt;span style="color:#2b91af;"&gt;EmployeeServiceFindByIdResponse &lt;/span&gt;response)
    {
        response.ID = _employee.ID;
        
        &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// The Others assignations .. 
    &lt;/span&gt;}
}

&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;EmployeeService &lt;/span&gt;: &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;IEmployeeService
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;EmployeeServiceFindByIdResponse &lt;/span&gt;FindById(&lt;span style="color:#2b91af;"&gt;EmployeeServiceFindByIdRequest &lt;/span&gt;request)
    {
        &lt;span style="color:#2b91af;"&gt;Employee &lt;/span&gt;employee = &lt;span style="color:#2b91af;"&gt;EmployeeRepository&lt;/span&gt;.GetById(request.ID);

        &lt;span style="color:#2b91af;"&gt;EmployeeServiceFindByIdAdapter &lt;/span&gt;adapter 
            = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;EmployeeServiceFindByIdAdapter&lt;/span&gt;(employee);

        &lt;span style="color:#2b91af;"&gt;EmployeeServiceFindByIdResponse &lt;/span&gt;response 
            = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;EmployeeServiceFindByIdResponse&lt;/span&gt;();

        adapter.Initialize(response);

        &lt;span style="color:blue;"&gt;return &lt;/span&gt;response;
    }

    &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// Other IEmployeeService methods ..
&lt;/span&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p align="justify"&gt;----------------------------------------------------------------------------------------------------------&lt;/p&gt;

&lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;&lt;u&gt;Como he explicado ya, en un modelo de dominio complejo, es poco práctico hacer uso de objetos DTO y objetos Adapter, pero entonces, ¿Cual es la solución práctica?.&lt;/u&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;&lt;u&gt;Muy sencillo, usar directamente objetos de modelo de dominio.&lt;/u&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;&lt;u&gt;Pero entonces, ¿Cuando podemos prescindir de objetos DTO?&lt;/u&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;&lt;u&gt;Solo podremos eliminar la presencia de objetos DTO cuando la capa de presentación y la capa de servicios estén ubicadas en el mismo proceso, un claro ejemplo son los escenarios .NET to .NET donde los tipos del CLR se pueden entender en ambas capas.&lt;/u&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p align="justify"&gt;Algunos escenarios donde podemos eliminar la presencia de objetos DTO son :&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;div align="justify"&gt;Una capa de presentación en ASP.NET y una capa de servicios implementada a través de un assembly.&lt;/div&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;div align="justify"&gt;&lt;font color="#ff8040"&gt;&lt;font color="#000000"&gt;Una capa de presentación en ASP.NET y&amp;#160; una capa de servicios implementada a través de servicios web ASMX o servicios WCF siempre y cuando ámbas capas estén alojadas en el mismo worker process de IIS.&lt;/font&gt;&lt;/font&gt;&lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p align="justify"&gt;Sin embargo, usar objetos nativos de dominio disminuye la granularidad de la solución puesto que en muchos casos contienen más información de la que realmente necesitamos, y es entonces cuando nos planteamos la posibilidad de crear varias versiones del mismo objeto de dominio :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&lt;font size="1" face="Verdana"&gt;public enum &lt;/font&gt;&lt;/span&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;EmployeeVersion
&lt;/span&gt;{
    FullVersion = 0,
    ShortVersion,
    IdVersion
}

&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;Employee 
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;public int &lt;/span&gt;ID   
    { &lt;span style="color:blue;"&gt;get&lt;/span&gt;;&lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;public string &lt;/span&gt;Name
    { &lt;span style="color:blue;"&gt;get&lt;/span&gt;;&lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;public string &lt;/span&gt;FirstSurname
    { &lt;span style="color:blue;"&gt;get&lt;/span&gt;;&lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;public string &lt;/span&gt;SecondSurname
    { &lt;span style="color:blue;"&gt;get&lt;/span&gt;;&lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;public bool &lt;/span&gt;IsExternal
    { &lt;span style="color:blue;"&gt;get&lt;/span&gt;;&lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;public string &lt;/span&gt;DNI
    { &lt;span style="color:blue;"&gt;get&lt;/span&gt;;&lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DateTime &lt;/span&gt;CreationDate
    { &lt;span style="color:blue;"&gt;get&lt;/span&gt;;&lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;EmployeeVersion &lt;/span&gt;Version
    { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }    
}&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p align="justify"&gt;En el ejemplo anterior, a través de la propiedad “EmployeeVersion”, podremos implementar una capa de presentación inteligente que conozca los campos “no nulos” en función del tipo de versión del objeto de dominio.&lt;/p&gt;

&lt;p align="justify"&gt;Y eso es todo por hoy, en el siguiente post hablare sobre arquitectura SOA.&lt;/p&gt;
&lt;div id="postorigin" style="margin-left:5px;font-size:80%;padding:5px;border:2px solid #BDB67C;background-color:#DDDBC7;width:300px;text-align:center;-moz-border-radius:4px 4px 4px 4px;-webkit-border-radius:4px;border-radius:4px;"&gt;&lt;a href="http://kartones.net/blogs/coco/archive/2009/12/08/la-capa-de-servicios-patrones.aspx"&gt;La Capa de Servicios : Patrones&lt;/a&gt; was posted the 12/08/2009 at &lt;a href="http://Kartones.net"&gt;Kartones.Net&lt;/a&gt;.&lt;/div&gt;
&lt;div id="sharing" class="postfoot"&gt;&lt;hr /&gt;&lt;p&gt;Share via:&lt;br&gt;&lt;a rel="nofollow" href="mailto:?subject=Kartones.Net:%20La+Capa+de+Servicios+%3a+Patrones&amp;amp;body=http://kartones.net/blogs/coco/archive/2009/12/08/la-capa-de-servicios-patrones.aspx" target="_blank"&gt;Email&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.facebook.com/share.php?u=http://kartones.net/blogs/coco/archive/2009/12/08/la-capa-de-servicios-patrones.aspx&amp;amp;t=La+Capa+de+Servicios+%3a+Patrones" target="_blank"&gt;Facebook&lt;/a&gt; | &lt;a rel="nofollow" href="http://twitter.com/home?status=http://kartones.net/blogs/coco/archive/2009/12/08/la-capa-de-servicios-patrones.aspx" target="_blank"&gt;Twitter&lt;/a&gt; | &lt;a rel="nofollow" href="http://slashdot.org/bookmark.pl?url=http://kartones.net/blogs/coco/archive/2009/12/08/la-capa-de-servicios-patrones.aspx&amp;amp;title=La+Capa+de+Servicios+%3a+Patrones" target="_blank"&gt;SlashDot&lt;/a&gt; | &lt;a rel="nofollow" href="http://delicious.com/post?url=http://kartones.net/blogs/coco/archive/2009/12/08/la-capa-de-servicios-patrones.aspx&amp;amp;title=La+Capa+de+Servicios+%3a+Patrones" target="_blank"&gt;del.icio.us&lt;/a&gt; | &lt;a rel="nofollow" href="http://technorati.com/faves?add=http://kartones.net/blogs/coco/archive/2009/12/08/la-capa-de-servicios-patrones.aspx" target="_blank"&gt;Technorati&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http://kartones.net/blogs/coco/archive/2009/12/08/la-capa-de-servicios-patrones.aspx&amp;amp;title=La+Capa+de+Servicios+%3a+Patrones" target="_blank"&gt;Stumbleupon&lt;/a&gt; | &lt;a rel="nofollow" href="http://reddit.com/submit?url=http://kartones.net/blogs/coco/archive/2009/12/08/la-capa-de-servicios-patrones.aspx&amp;amp;title=La+Capa+de+Servicios+%3a+Patrones" target="_blank"&gt;Reddit&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.google.com/reader/link?url=http://kartones.net/blogs/coco/archive/2009/12/08/la-capa-de-servicios-patrones.aspx&amp;amp;title=La+Capa+de+Servicios+%3a+Patrones&amp;amp;srcUrl=http://kartones.net/blogs/coco/archive/2009/12/08/la-capa-de-servicios-patrones.aspx&amp;amp;srcTitle=La+Capa+de+Servicios+%3a+Patrones" target="_blank"&gt;Google Reader&lt;/a&gt; | &lt;a rel="nofollow" href="http://meneame.net/submit.php?url=http://kartones.net/blogs/coco/archive/2009/12/08/la-capa-de-servicios-patrones.aspx" target="_blank"&gt;Meneame&lt;/a&gt; | &lt;a rel="nofollow" href="http://bitacoras.com/anotaciones/http://kartones.net/blogs/coco/archive/2009/12/08/la-capa-de-servicios-patrones.aspx" target="_blank"&gt;Bitacoras&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.linkedin.com/shareArticle?mini=true&amp;amp;url=http://kartones.net/blogs/coco/archive/2009/12/08/la-capa-de-servicios-patrones.aspx&amp;amp;title=La+Capa+de+Servicios+%3a+Patrones&amp;amp;source=Kartones.Net" target="_blank"&gt;LinkedIn&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.google.com/bookmarks/mark?op=edit&amp;amp;bkmk=http://kartones.net/blogs/coco/archive/2009/12/08/la-capa-de-servicios-patrones.aspx&amp;amp;title=La+Capa+de+Servicios+%3a+Patrones" target="_blank"&gt;Google Bookmarks&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.google.com/reader/link?url=http://kartones.net/blogs/coco/archive/2009/12/08/la-capa-de-servicios-patrones.aspx&amp;amp;title=La+Capa+de+Servicios+%3a+Patrones" target="_blank"&gt;Google Reader&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.google.com/buzz/post?url=http://kartones.net/blogs/coco/archive/2009/12/08/la-capa-de-servicios-patrones.aspx&amp;amp;imageurl=" target="_blank"&gt;Google Buzz&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.friendfeed.com/share?title=La+Capa+de+Servicios+%3a+Patrones&amp;amp;link=http://kartones.net/blogs/coco/archive/2009/12/08/la-capa-de-servicios-patrones.aspx" target="_blank"&gt;FriendFeed&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.netvibes.com/share?title=La+Capa+de+Servicios+%3a+Patrones&amp;amp;url=http://kartones.net/blogs/coco/archive/2009/12/08/la-capa-de-servicios-patrones.aspx" target="_blank"&gt;Netvibes&lt;/a&gt; | &lt;a rel="nofollow" href="https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;mkt=es-es&amp;amp;url=http://kartones.net/blogs/coco/archive/2009/12/08/la-capa-de-servicios-patrones.aspx&amp;amp;title=La+Capa+de+Servicios+%3a+Patrones" target="_blank"&gt;Windows Live&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.myspace.com/Modules/PostTo/Pages/?u=http://kartones.net/blogs/coco/archive/2009/12/08/la-capa-de-servicios-patrones.aspx&amp;amp;t=La+Capa+de+Servicios+%3a+Patrones" target="_blank"&gt;MySpace&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;img src="http://kartones.net/aggbug.aspx?PostID=50589" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/ElFrameworkDeCoco/~4/BdLgAtzcsGE" height="1" width="1"/&gt;</description><category domain="http://kartones.net/blogs/coco/archive/tags/DTO/default.aspx">DTO</category><category domain="http://kartones.net/blogs/coco/archive/tags/Patr_26002300_243_3B00_n+Adapter/default.aspx">Patr&amp;#243;n Adapter</category><category domain="http://kartones.net/blogs/coco/archive/tags/Capa+de+Servicios/default.aspx">Capa de Servicios</category><category domain="http://kartones.net/blogs/coco/archive/tags/Patr_F300_n+Remote+Facade/default.aspx">Patrón Remote Facade</category><feedburner:origLink>http://kartones.net/blogs/coco/archive/2009/12/08/la-capa-de-servicios-patrones.aspx</feedburner:origLink></item><item><title>La Capa de Servicios : Aspectos de Implementación</title><link>http://feeds.kartones.net/~r/ElFrameworkDeCoco/~3/T03m1eW_w7w/la-capa-de-servicios-aspectos-de-implementaci-243-n.aspx</link><pubDate>Mon, 07 Dec 2009 22:23:19 GMT</pubDate><guid isPermaLink="false">b86c0850-82e5-42ed-a9d8-bde9e8f94ec1:50587</guid><dc:creator>ccrego</dc:creator><slash:comments>0</slash:comments><comments>http://kartones.net/blogs/coco/archive/2009/12/07/la-capa-de-servicios-aspectos-de-implementaci-243-n.aspx#comments</comments><description>&lt;p align="justify"&gt;Las clases usadas en la capa de servicios deberían exponer un contrato :&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;     &lt;div align="justify"&gt;A través de WCF (para capas de servicios remotas)&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;A través de una interfaz (para capas de servicios locales)&lt;/div&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p align="justify"&gt;Normalmente en una capa de servicios local, la interfaz usada para exponer el contrato hace uso de objetos DTO para el paso de parámetros y el retorno de datos.&lt;/p&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Para preparar la lista de métodos de la interfaz usada para exponer un contrato, es muy normal basarse en los casos de uso del sistema.&lt;/font&gt;&lt;/p&gt;  &lt;p align="justify"&gt;En la mayoría de las ocasiones, acabaremos teniendo un clase de servicio por cada objeto del dominio : &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;     &lt;div align="justify"&gt;CustomerService&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;OrderService&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;EmployeeService &lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;…&lt;/div&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p align="justify"&gt;Sin embargo si tenemos pocas acciones y todas están estrechamente relacionadas con una sola clase de servicio bastaría.&lt;/p&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Una capa de servicios evoluciona de modo independiente del resto del sistema y es la única interfaz para que la capa de presentación haga uso de los procesos de negocio.&lt;/font&gt;&lt;/p&gt;  &lt;p align="justify"&gt;El principal problema de una capa de servicios es que si un caso de uso cambia, tendremos que modificar el servicio correspondiente, el beneficio que ganamos a cambio es que muchas veces no tendremos que modificar la capa de negocio.&lt;/p&gt;  &lt;p align="justify"&gt;Es muy recomendable que cada clase de la capa de servicios exponga una interfaz :&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&lt;font size="1" face="Verdana"&gt;public interface &lt;/font&gt;&lt;/span&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;IEmployeeService
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;int &lt;/span&gt;Create(&lt;span style="color:#2b91af;"&gt;Employee &lt;/span&gt;employee);

    &lt;span style="color:blue;"&gt;int &lt;/span&gt;Update(&lt;span style="color:#2b91af;"&gt;Employee &lt;/span&gt;employee);

    &lt;span style="color:#2b91af;"&gt;IList&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Employee&lt;/span&gt;&amp;gt; FindAll();

    &lt;span style="color:#2b91af;"&gt;Employee &lt;/span&gt;FindById(&lt;span style="color:blue;"&gt;int &lt;/span&gt;employeeId);

    &lt;span style="color:#2b91af;"&gt;Employee &lt;/span&gt;GetBoss(&lt;span style="color:blue;"&gt;int &lt;/span&gt;employeeId);

    &lt;span style="color:#2b91af;"&gt;Department &lt;/span&gt;GetDepartment(&lt;span style="color:blue;"&gt;int &lt;/span&gt;employeeId);

    &lt;span style="color:#2b91af;"&gt;IList&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Employee&lt;/span&gt;&amp;gt; GetSubordinates(&lt;span style="color:blue;"&gt;int &lt;/span&gt;employeeId);
}

&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;MyEmployeeService &lt;/span&gt;: &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;IEmployeeService
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;#region &lt;/span&gt;IEmployeeService Members

    &lt;span style="color:blue;"&gt;public int &lt;/span&gt;Create(&lt;span style="color:#2b91af;"&gt;Employee &lt;/span&gt;employee)
    {
        &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// Create a new employee ..
    &lt;/span&gt;}

    &lt;span style="color:blue;"&gt;public int &lt;/span&gt;Update(&lt;span style="color:#2b91af;"&gt;Employee &lt;/span&gt;employee)
    {
        &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// Updates the employee ..
    &lt;/span&gt;}

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IList&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Employee&lt;/span&gt;&amp;gt; FindAll()
    {
        &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// Find all employees ..
    &lt;/span&gt;}

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Employee &lt;/span&gt;FindById(&lt;span style="color:blue;"&gt;int &lt;/span&gt;employeeId)
    {
        &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// Gets the employee object for the employee identificator ..
    &lt;/span&gt;}

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Employee &lt;/span&gt;GetBoss(&lt;span style="color:blue;"&gt;int &lt;/span&gt;employeeId)
    {
        &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// Gets the employee object that represents the boss for 
        // the employee identificator ..
    &lt;/span&gt;}

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Department &lt;/span&gt;GetDepartment(&lt;span style="color:blue;"&gt;int &lt;/span&gt;employeeId)
    {
        &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// Gets the Department object associated to the 
        // employee identificator ..
    &lt;/span&gt;}

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IList&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Employee&lt;/span&gt;&amp;gt; GetSubordinates(&lt;span style="color:blue;"&gt;int &lt;/span&gt;employeeId)
    {
        &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// Gets the subordinates for the employee identificator ..
    &lt;/span&gt;}

    &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:blue;"&gt;#endregion
&lt;/span&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p align="justify"&gt;Imaginemos que la interfaz IEmployeeService usa los objetos del modelo de dominio directamente, en este caso la clase Employee es exactamente una representación del objeto Employee que hemos creado en el modelo de dominio, en este caso estamos asumiendo el uso del patrón modelo de dominio en la capa de negocio.&lt;/p&gt;

&lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;La mayoría de los expertos en arquitectura de software recomiendan que los métodos CRUD no deberían aparecer en los servicios sin embargo depende de los casos de uso que tengamos, es decir, si la funcionalidad relativa a persistir información forma parte de un caso de uso, entonces dicha funcionalidad debe formar parte del servicio.&lt;/font&gt;&lt;/p&gt;

&lt;p align="justify"&gt;Pasemos a otro tema, ¿Donde deberíamos aplicar el manejo de la seguridad?.&lt;/p&gt;

&lt;p align="justify"&gt;Es decir, ¿Que debería devolver el método FindAll? :&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;div align="justify"&gt;Todos los empleados&lt;/div&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;div align="justify"&gt;Todos los empleados visibles para el usuario actual&lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p align="justify"&gt;Si nos tomamos en serio la seguridad, deberíamos elegir entre : &lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;div align="justify"&gt;Comprobar la identidad del usuario que realiza la llamada al servicio y rechazar las llamadas de usuarios no autorizados.&lt;/div&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;div align="justify"&gt;Asumir que el usuario que realiza la llamada solo tiene acceso a una parte de los datos basándose por ejemplo en los roles a los que pertenece.&lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;La verificación de permisos y la configuración de la respuesta es una responsabilidad exclusivamente de los métodos de la capa de servicios, si usamos roles, el servicio debe obtener la identidad del usuario que realiza la llamada, obtener la lista de roles a los que pertenece y decidir que hacer.&lt;/font&gt;&lt;/p&gt;

&lt;p align="justify"&gt;Resumiendo, la funcionalidad relativa a la restricción de datos en función del perfil del usuario que realiza la llamada a la capa de servicios, forma parte de la definición de un caso de uso y por tanto de las reglas de negocio.&lt;/p&gt;

&lt;p align="justify"&gt;Para terminar hablare de la diferencia entre “lógica de dominio” y “lógica de aplicación” :&lt;/p&gt;

&lt;p align="justify"&gt;La lógica de dominio expresa conceptos de negocio como reglas, persistencia y estado, la lógica de dominio suele ser implementada a través de objetos que ignoran la persistencia pero cuyos datos y comportamiento es consistente en relación a las reglas.&lt;/p&gt;

&lt;p align="justify"&gt;La lógica de aplicación organiza los objetos del dominio y los servicios de aplicación para servir a la capa de presentación lo que se necesita.&lt;/p&gt;

&lt;p align="justify"&gt;Y eso es todo por hoy, en el siguiente post hablare de los patrones que se suelen usar en la implementación de la capa de servicios ..&lt;/p&gt;
&lt;div id="postorigin" style="margin-left:5px;font-size:80%;padding:5px;border:2px solid #BDB67C;background-color:#DDDBC7;width:300px;text-align:center;-moz-border-radius:4px 4px 4px 4px;-webkit-border-radius:4px;border-radius:4px;"&gt;&lt;a href="http://kartones.net/blogs/coco/archive/2009/12/07/la-capa-de-servicios-aspectos-de-implementaci-243-n.aspx"&gt;La Capa de Servicios : Aspectos de Implementaci&amp;#243;n&lt;/a&gt; was posted the 12/07/2009 at &lt;a href="http://Kartones.net"&gt;Kartones.Net&lt;/a&gt;.&lt;/div&gt;
&lt;div id="sharing" class="postfoot"&gt;&lt;hr /&gt;&lt;p&gt;Share via:&lt;br&gt;&lt;a rel="nofollow" href="mailto:?subject=Kartones.Net:%20La+Capa+de+Servicios+%3a+Aspectos+de+Implementaci%26%23243%3bn&amp;amp;body=http://kartones.net/blogs/coco/archive/2009/12/07/la-capa-de-servicios-aspectos-de-implementaci-243-n.aspx" target="_blank"&gt;Email&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.facebook.com/share.php?u=http://kartones.net/blogs/coco/archive/2009/12/07/la-capa-de-servicios-aspectos-de-implementaci-243-n.aspx&amp;amp;t=La+Capa+de+Servicios+%3a+Aspectos+de+Implementaci%26%23243%3bn" target="_blank"&gt;Facebook&lt;/a&gt; | &lt;a rel="nofollow" href="http://twitter.com/home?status=http://kartones.net/blogs/coco/archive/2009/12/07/la-capa-de-servicios-aspectos-de-implementaci-243-n.aspx" target="_blank"&gt;Twitter&lt;/a&gt; | &lt;a rel="nofollow" href="http://slashdot.org/bookmark.pl?url=http://kartones.net/blogs/coco/archive/2009/12/07/la-capa-de-servicios-aspectos-de-implementaci-243-n.aspx&amp;amp;title=La+Capa+de+Servicios+%3a+Aspectos+de+Implementaci%26%23243%3bn" target="_blank"&gt;SlashDot&lt;/a&gt; | &lt;a rel="nofollow" href="http://delicious.com/post?url=http://kartones.net/blogs/coco/archive/2009/12/07/la-capa-de-servicios-aspectos-de-implementaci-243-n.aspx&amp;amp;title=La+Capa+de+Servicios+%3a+Aspectos+de+Implementaci%26%23243%3bn" target="_blank"&gt;del.icio.us&lt;/a&gt; | &lt;a rel="nofollow" href="http://technorati.com/faves?add=http://kartones.net/blogs/coco/archive/2009/12/07/la-capa-de-servicios-aspectos-de-implementaci-243-n.aspx" target="_blank"&gt;Technorati&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http://kartones.net/blogs/coco/archive/2009/12/07/la-capa-de-servicios-aspectos-de-implementaci-243-n.aspx&amp;amp;title=La+Capa+de+Servicios+%3a+Aspectos+de+Implementaci%26%23243%3bn" target="_blank"&gt;Stumbleupon&lt;/a&gt; | &lt;a rel="nofollow" href="http://reddit.com/submit?url=http://kartones.net/blogs/coco/archive/2009/12/07/la-capa-de-servicios-aspectos-de-implementaci-243-n.aspx&amp;amp;title=La+Capa+de+Servicios+%3a+Aspectos+de+Implementaci%26%23243%3bn" target="_blank"&gt;Reddit&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.google.com/reader/link?url=http://kartones.net/blogs/coco/archive/2009/12/07/la-capa-de-servicios-aspectos-de-implementaci-243-n.aspx&amp;amp;title=La+Capa+de+Servicios+%3a+Aspectos+de+Implementaci%26%23243%3bn&amp;amp;srcUrl=http://kartones.net/blogs/coco/archive/2009/12/07/la-capa-de-servicios-aspectos-de-implementaci-243-n.aspx&amp;amp;srcTitle=La+Capa+de+Servicios+%3a+Aspectos+de+Implementaci%26%23243%3bn" target="_blank"&gt;Google Reader&lt;/a&gt; | &lt;a rel="nofollow" href="http://meneame.net/submit.php?url=http://kartones.net/blogs/coco/archive/2009/12/07/la-capa-de-servicios-aspectos-de-implementaci-243-n.aspx" target="_blank"&gt;Meneame&lt;/a&gt; | &lt;a rel="nofollow" href="http://bitacoras.com/anotaciones/http://kartones.net/blogs/coco/archive/2009/12/07/la-capa-de-servicios-aspectos-de-implementaci-243-n.aspx" target="_blank"&gt;Bitacoras&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.linkedin.com/shareArticle?mini=true&amp;amp;url=http://kartones.net/blogs/coco/archive/2009/12/07/la-capa-de-servicios-aspectos-de-implementaci-243-n.aspx&amp;amp;title=La+Capa+de+Servicios+%3a+Aspectos+de+Implementaci%26%23243%3bn&amp;amp;source=Kartones.Net" target="_blank"&gt;LinkedIn&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.google.com/bookmarks/mark?op=edit&amp;amp;bkmk=http://kartones.net/blogs/coco/archive/2009/12/07/la-capa-de-servicios-aspectos-de-implementaci-243-n.aspx&amp;amp;title=La+Capa+de+Servicios+%3a+Aspectos+de+Implementaci%26%23243%3bn" target="_blank"&gt;Google Bookmarks&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.google.com/reader/link?url=http://kartones.net/blogs/coco/archive/2009/12/07/la-capa-de-servicios-aspectos-de-implementaci-243-n.aspx&amp;amp;title=La+Capa+de+Servicios+%3a+Aspectos+de+Implementaci%26%23243%3bn" target="_blank"&gt;Google Reader&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.google.com/buzz/post?url=http://kartones.net/blogs/coco/archive/2009/12/07/la-capa-de-servicios-aspectos-de-implementaci-243-n.aspx&amp;amp;imageurl=" target="_blank"&gt;Google Buzz&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.friendfeed.com/share?title=La+Capa+de+Servicios+%3a+Aspectos+de+Implementaci%26%23243%3bn&amp;amp;link=http://kartones.net/blogs/coco/archive/2009/12/07/la-capa-de-servicios-aspectos-de-implementaci-243-n.aspx" target="_blank"&gt;FriendFeed&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.netvibes.com/share?title=La+Capa+de+Servicios+%3a+Aspectos+de+Implementaci%26%23243%3bn&amp;amp;url=http://kartones.net/blogs/coco/archive/2009/12/07/la-capa-de-servicios-aspectos-de-implementaci-243-n.aspx" target="_blank"&gt;Netvibes&lt;/a&gt; | &lt;a rel="nofollow" href="https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;mkt=es-es&amp;amp;url=http://kartones.net/blogs/coco/archive/2009/12/07/la-capa-de-servicios-aspectos-de-implementaci-243-n.aspx&amp;amp;title=La+Capa+de+Servicios+%3a+Aspectos+de+Implementaci%26%23243%3bn" target="_blank"&gt;Windows Live&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.myspace.com/Modules/PostTo/Pages/?u=http://kartones.net/blogs/coco/archive/2009/12/07/la-capa-de-servicios-aspectos-de-implementaci-243-n.aspx&amp;amp;t=La+Capa+de+Servicios+%3a+Aspectos+de+Implementaci%26%23243%3bn" target="_blank"&gt;MySpace&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;img src="http://kartones.net/aggbug.aspx?PostID=50587" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/ElFrameworkDeCoco/~4/T03m1eW_w7w" height="1" width="1"/&gt;</description><category domain="http://kartones.net/blogs/coco/archive/tags/Capa+de+Servicios/default.aspx">Capa de Servicios</category><feedburner:origLink>http://kartones.net/blogs/coco/archive/2009/12/07/la-capa-de-servicios-aspectos-de-implementaci-243-n.aspx</feedburner:origLink></item><item><title>La Capa de Servicios : Conceptos Básicos</title><link>http://feeds.kartones.net/~r/ElFrameworkDeCoco/~3/zigNzOOyeEo/la-capa-de-servicios-conceptos-b-225-sicos.aspx</link><pubDate>Sat, 05 Dec 2009 19:11:28 GMT</pubDate><guid isPermaLink="false">b86c0850-82e5-42ed-a9d8-bde9e8f94ec1:50580</guid><dc:creator>ccrego</dc:creator><slash:comments>0</slash:comments><comments>http://kartones.net/blogs/coco/archive/2009/12/05/la-capa-de-servicios-conceptos-b-225-sicos.aspx#comments</comments><description>&lt;p align="justify"&gt;Tener cierta cantidad de lógica de negocio en la capa de presentación puede ser aceptable algunas veces, sin embargo, consideremos que guardamos toda esa lógica de negocio fuera de la capa de presentación para tener lo que se considera una vista tonta (view dummy), y débilmente acoplada.&lt;/p&gt;  &lt;p align="justify"&gt;¿Como podríamos acceder a dicha lógica de negocio desde la capa de presentación?.&lt;/p&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;&lt;font color="#000000"&gt;La respuesta es sencilla, definiendo una capa de servicios.&lt;/font&gt;&amp;#160;&lt;/font&gt;&lt;/p&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Una capa de servicios es una capa de abstracción que se crea entre la capa de presentación y la capa de negocio, y que agrupa funcionalidad de la capa de negocio para ser expuesta a la capa de presentación.&lt;/font&gt;&lt;/p&gt;  &lt;p align="justify"&gt;La funcionalidad de una capa de servicios no se debe limitar a llamar a métodos de la capa de negocio ya que actuaria de proxy, por el contrario, &lt;font color="#ff8040"&gt;una capa de servicios debe organizar las llamadas a un conjunto de clases de negocio para ofrecer una funcionalidad muy concreta a la capa de presentación.&lt;/font&gt;&lt;/p&gt;  &lt;p align="justify"&gt;Cualquier interacción que se origine en la capa de presentación, encuentra una respuesta en la capa de servicios.&lt;/p&gt;  &lt;p align="justify"&gt;¿Es la capa de servicios entonces, la única parte del sistema que realiza llamadas directamente a la base de datos?, la respuesta es no.&lt;/p&gt;  &lt;p align="justify"&gt;La lógica de negocio puede contener componentes que no tienen acceso a base de datos, y que manejan datos de otras fuentes a través de servicios web y ficheros.&lt;/p&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Es muy común que la capa de presentación se comunique con la capa de servicios mediante objetos DTO que internamente son convertidos a objetos del modelo de dominio en la capa de servicios.&lt;/font&gt;&lt;/p&gt;  &lt;p align="justify"&gt;&lt;u&gt;&lt;font color="#dd4a21"&gt;&lt;/font&gt;&lt;/u&gt;&lt;a href="http://kartones.net/blogs/coco/ArquitecturaServicios21_5BD08A4B.jpg"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:block;float:none;margin-left:auto;border-top:0px;margin-right:auto;border-right:0px;" title="ArquitecturaServicios2[1]" border="0" alt="ArquitecturaServicios2[1]" src="http://kartones.net/blogs/coco/ArquitecturaServicios21_thumb_0AD2C623.jpg" width="296" height="296" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p align="justify"&gt;Como he comentado antes, un servicio agrupa llamadas a clases de negocio para ofrecer una funcionalidad muy concreta, en este escenario es inevitable pensar que los servicios sean un tipo especial de clase que tome ventaja de algunos aspectos del entorno de ejecución como son:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;     &lt;div align="justify"&gt;Seguridad&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;Transacciones&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;Instrumentación&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;Fiabilidad&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;Políticas&lt;/div&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p align="justify"&gt;Por tanto, &lt;font color="#ff8040"&gt;el entorno de ejecución marca la diferencia entre un servicio y una clase.&lt;/font&gt;&lt;/p&gt;  &lt;p align="justify"&gt;&lt;a href="http://kartones.net/blogs/coco/arquitecturaservicios1_00CB90E0.jpg"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="arquitecturaservicios[1]" border="0" alt="arquitecturaservicios[1]" src="http://kartones.net/blogs/coco/arquitecturaservicios1_thumb_0B0C8F73.jpg" width="537" height="370" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p align="justify"&gt;Como se puede observar en la figura anterior, una capa de servicios puede implementarse de dos formas diferentes :&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;     &lt;div align="justify"&gt;Remota a la capa de presentación&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;Local a la capa de presentación&lt;/div&gt;   &lt;/li&gt; &lt;/ol&gt;  &lt;p align="justify"&gt;Cuando debemos optar por una capa remota?, pues depende del cliente y de los recursos que tengamos a mano. &lt;/p&gt;  &lt;p align="justify"&gt;En la mayoría de ocasiones que implementamos una capa de servicios de forma remota mediante servicios WCF, es debido a que trabajamos en un entorno web. &lt;/p&gt;  &lt;p align="justify"&gt;Mediante el uso de una capa de servicios remota podemos realizar el despliegue en un servidor web dedicado, permitiendo aliviar la carga de trabaja al servidor web donde tenemos alojada nuestra aplicación ASP.NET.&lt;/p&gt;  &lt;p align="justify"&gt;Además tener la capa de servicios externalizada es perfecto para escenarios SOA.&lt;/p&gt;  &lt;p align="justify"&gt;Para terminar, una capa de servicios esta compuesta de :&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;     &lt;div align="justify"&gt;Macro-servicios&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;Micro-servicios&lt;/div&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Los macro-servicios, viven en la capa de servicios y orquestan operaciones que se mapean directamente en casos de uso, son servicios que no entienden de componentes de negocio, solo de flujos de llamadas que dan sentido al caso de uso que representan.&lt;/font&gt;&lt;/p&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Los micro-servicios, viven en la capa de presentación y representan “utilidades” que sirven a la lógica de negocio, un claro ejemplo de estos servicios son las clases de formateo de datos, de conversión y de acceso a ficheros de datos.&lt;/font&gt;&lt;/p&gt;  &lt;p align="justify"&gt;Y eso ha sido todo por hoy ..&lt;/p&gt;
&lt;div id="postorigin" style="margin-left:5px;font-size:80%;padding:5px;border:2px solid #BDB67C;background-color:#DDDBC7;width:300px;text-align:center;-moz-border-radius:4px 4px 4px 4px;-webkit-border-radius:4px;border-radius:4px;"&gt;&lt;a href="http://kartones.net/blogs/coco/archive/2009/12/05/la-capa-de-servicios-conceptos-b-225-sicos.aspx"&gt;La Capa de Servicios : Conceptos B&amp;#225;sicos&lt;/a&gt; was posted the 12/05/2009 at &lt;a href="http://Kartones.net"&gt;Kartones.Net&lt;/a&gt;.&lt;/div&gt;
&lt;div id="sharing" class="postfoot"&gt;&lt;hr /&gt;&lt;p&gt;Share via:&lt;br&gt;&lt;a rel="nofollow" href="mailto:?subject=Kartones.Net:%20La+Capa+de+Servicios+%3a+Conceptos+B%26%23225%3bsicos&amp;amp;body=http://kartones.net/blogs/coco/archive/2009/12/05/la-capa-de-servicios-conceptos-b-225-sicos.aspx" target="_blank"&gt;Email&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.facebook.com/share.php?u=http://kartones.net/blogs/coco/archive/2009/12/05/la-capa-de-servicios-conceptos-b-225-sicos.aspx&amp;amp;t=La+Capa+de+Servicios+%3a+Conceptos+B%26%23225%3bsicos" target="_blank"&gt;Facebook&lt;/a&gt; | &lt;a rel="nofollow" href="http://twitter.com/home?status=http://kartones.net/blogs/coco/archive/2009/12/05/la-capa-de-servicios-conceptos-b-225-sicos.aspx" target="_blank"&gt;Twitter&lt;/a&gt; | &lt;a rel="nofollow" href="http://slashdot.org/bookmark.pl?url=http://kartones.net/blogs/coco/archive/2009/12/05/la-capa-de-servicios-conceptos-b-225-sicos.aspx&amp;amp;title=La+Capa+de+Servicios+%3a+Conceptos+B%26%23225%3bsicos" target="_blank"&gt;SlashDot&lt;/a&gt; | &lt;a rel="nofollow" href="http://delicious.com/post?url=http://kartones.net/blogs/coco/archive/2009/12/05/la-capa-de-servicios-conceptos-b-225-sicos.aspx&amp;amp;title=La+Capa+de+Servicios+%3a+Conceptos+B%26%23225%3bsicos" target="_blank"&gt;del.icio.us&lt;/a&gt; | &lt;a rel="nofollow" href="http://technorati.com/faves?add=http://kartones.net/blogs/coco/archive/2009/12/05/la-capa-de-servicios-conceptos-b-225-sicos.aspx" target="_blank"&gt;Technorati&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http://kartones.net/blogs/coco/archive/2009/12/05/la-capa-de-servicios-conceptos-b-225-sicos.aspx&amp;amp;title=La+Capa+de+Servicios+%3a+Conceptos+B%26%23225%3bsicos" target="_blank"&gt;Stumbleupon&lt;/a&gt; | &lt;a rel="nofollow" href="http://reddit.com/submit?url=http://kartones.net/blogs/coco/archive/2009/12/05/la-capa-de-servicios-conceptos-b-225-sicos.aspx&amp;amp;title=La+Capa+de+Servicios+%3a+Conceptos+B%26%23225%3bsicos" target="_blank"&gt;Reddit&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.google.com/reader/link?url=http://kartones.net/blogs/coco/archive/2009/12/05/la-capa-de-servicios-conceptos-b-225-sicos.aspx&amp;amp;title=La+Capa+de+Servicios+%3a+Conceptos+B%26%23225%3bsicos&amp;amp;srcUrl=http://kartones.net/blogs/coco/archive/2009/12/05/la-capa-de-servicios-conceptos-b-225-sicos.aspx&amp;amp;srcTitle=La+Capa+de+Servicios+%3a+Conceptos+B%26%23225%3bsicos" target="_blank"&gt;Google Reader&lt;/a&gt; | &lt;a rel="nofollow" href="http://meneame.net/submit.php?url=http://kartones.net/blogs/coco/archive/2009/12/05/la-capa-de-servicios-conceptos-b-225-sicos.aspx" target="_blank"&gt;Meneame&lt;/a&gt; | &lt;a rel="nofollow" href="http://bitacoras.com/anotaciones/http://kartones.net/blogs/coco/archive/2009/12/05/la-capa-de-servicios-conceptos-b-225-sicos.aspx" target="_blank"&gt;Bitacoras&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.linkedin.com/shareArticle?mini=true&amp;amp;url=http://kartones.net/blogs/coco/archive/2009/12/05/la-capa-de-servicios-conceptos-b-225-sicos.aspx&amp;amp;title=La+Capa+de+Servicios+%3a+Conceptos+B%26%23225%3bsicos&amp;amp;source=Kartones.Net" target="_blank"&gt;LinkedIn&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.google.com/bookmarks/mark?op=edit&amp;amp;bkmk=http://kartones.net/blogs/coco/archive/2009/12/05/la-capa-de-servicios-conceptos-b-225-sicos.aspx&amp;amp;title=La+Capa+de+Servicios+%3a+Conceptos+B%26%23225%3bsicos" target="_blank"&gt;Google Bookmarks&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.google.com/reader/link?url=http://kartones.net/blogs/coco/archive/2009/12/05/la-capa-de-servicios-conceptos-b-225-sicos.aspx&amp;amp;title=La+Capa+de+Servicios+%3a+Conceptos+B%26%23225%3bsicos" target="_blank"&gt;Google Reader&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.google.com/buzz/post?url=http://kartones.net/blogs/coco/archive/2009/12/05/la-capa-de-servicios-conceptos-b-225-sicos.aspx&amp;amp;imageurl=" target="_blank"&gt;Google Buzz&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.friendfeed.com/share?title=La+Capa+de+Servicios+%3a+Conceptos+B%26%23225%3bsicos&amp;amp;link=http://kartones.net/blogs/coco/archive/2009/12/05/la-capa-de-servicios-conceptos-b-225-sicos.aspx" target="_blank"&gt;FriendFeed&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.netvibes.com/share?title=La+Capa+de+Servicios+%3a+Conceptos+B%26%23225%3bsicos&amp;amp;url=http://kartones.net/blogs/coco/archive/2009/12/05/la-capa-de-servicios-conceptos-b-225-sicos.aspx" target="_blank"&gt;Netvibes&lt;/a&gt; | &lt;a rel="nofollow" href="https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;mkt=es-es&amp;amp;url=http://kartones.net/blogs/coco/archive/2009/12/05/la-capa-de-servicios-conceptos-b-225-sicos.aspx&amp;amp;title=La+Capa+de+Servicios+%3a+Conceptos+B%26%23225%3bsicos" target="_blank"&gt;Windows Live&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.myspace.com/Modules/PostTo/Pages/?u=http://kartones.net/blogs/coco/archive/2009/12/05/la-capa-de-servicios-conceptos-b-225-sicos.aspx&amp;amp;t=La+Capa+de+Servicios+%3a+Conceptos+B%26%23225%3bsicos" target="_blank"&gt;MySpace&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;img src="http://kartones.net/aggbug.aspx?PostID=50580" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/ElFrameworkDeCoco/~4/zigNzOOyeEo" height="1" width="1"/&gt;</description><category domain="http://kartones.net/blogs/coco/archive/tags/Capa+de+Servicios/default.aspx">Capa de Servicios</category><feedburner:origLink>http://kartones.net/blogs/coco/archive/2009/12/05/la-capa-de-servicios-conceptos-b-225-sicos.aspx</feedburner:origLink></item><item><title>La Capa de Negocio (VI) : El Patrón Modelo de Dominio</title><link>http://feeds.kartones.net/~r/ElFrameworkDeCoco/~3/rZ3q3O7MP2Q/la-capa-de-negocio-vi-el-patr-243-n-modelo-de-dominio.aspx</link><pubDate>Thu, 03 Dec 2009 23:20:00 GMT</pubDate><guid isPermaLink="false">b86c0850-82e5-42ed-a9d8-bde9e8f94ec1:50578</guid><dc:creator>ccrego</dc:creator><slash:comments>0</slash:comments><comments>http://kartones.net/blogs/coco/archive/2009/12/03/la-capa-de-negocio-vi-el-patr-243-n-modelo-de-dominio.aspx#comments</comments><description>&lt;p align="justify"&gt;En un diseño orientado al modelo de datos, comenzamos por diseñar la base de datos para después crear los componentes de negocio.&lt;/p&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Cuando la complejidad del sistema crece, nuestro enfoque en los datos deja de tener importancia ya que debemos centrarnos en la funcionalidad y es entonces cuando un diseño orientado a datos deja de ser escalable.&lt;/font&gt;&lt;/p&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;El patrón modelo de dominio nos permite centrarnos en el comportamiento del sistema y en el flujo de datos que lo hace funcionar, además nos ayuda a obtener un modelo de objetos que es una representación del modelo conceptual del sistema.&lt;/font&gt;&lt;/p&gt;  &lt;p align="justify"&gt;El modelo de dominio describe las entidades que participan en el sistema, las relaciones y el flujo de datos que existe entre ellas, dichas entidades se mapean en clases que se componen de propiedades y métodos.&lt;/p&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Un modelo de dominio es independiente de la base de datos y por tanto podemos reutilizarlo en otras aplicaciones.&lt;/font&gt;&lt;/p&gt;  &lt;p align="justify"&gt;Sin embargo el patrón modelo de dominio tiene un alto coste inicial, aunque a cambio ganamos un comportamiento lineal con respecto al aumento de la complejidad.&lt;/p&gt;  &lt;p align="justify"&gt;A diferencia de un diseño orientado al modelo datos, el diseño orientado al dominio es dirigido por los requerimientos y nos obliga a entender las reglas que definen el negocio y a modelarla a través de clases.&lt;/p&gt;  &lt;p align="justify"&gt;El único inconveniente es que es muy complicado tener una visión completa del sistema en términos de entidades y relaciones que describen procesos, además, en algún momento debemos convertir nuestro modelo de dominio en tablas y es entonces cuando nos damos cuenta de lo duro que resulta la persistencia de nuestro modelo.&lt;/p&gt;  &lt;p align="justify"&gt;Para realizar la persistencia de nuestro modelo de dominio podemos apoyarnos en alguna herramienta ORM como NHibernate o Entity Framework.&lt;/p&gt;  &lt;p align="justify"&gt;En un escenario recurrente para objetos de dominio, podemos definir clases base que contienen el comportamiento recurrente que deseamos compartir, imaginemos que deseamos aplicar validación sobre nuestros objetos de dominio, podríamos utilizar el siguiente modelo :&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&lt;font size="1" face="Verdana"&gt;public interface &lt;/font&gt;&lt;/span&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span&gt;IValidable&lt;br /&gt;&lt;/span&gt;{&lt;br /&gt;    &lt;span style="color:blue;"&gt;bool &lt;/span&gt;IsValid { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; }&lt;br /&gt;&lt;br /&gt;    &lt;span&gt;ValidationResults &lt;/span&gt;Validate();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span&gt;BussinesObject &lt;/span&gt;: &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span&gt;IValidable&lt;br /&gt;&lt;/span&gt;{&lt;br /&gt;    &lt;span style="color:blue;"&gt;public bool &lt;/span&gt;IsValid&lt;br /&gt;    {&lt;br /&gt;        &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:blue;"&gt;get&lt;br /&gt;        &lt;/span&gt;{&lt;br /&gt;            &lt;span style="color:blue;"&gt;return &lt;/span&gt;Validate().IsValid;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span&gt;ValidationResults &lt;/span&gt;Validate()&lt;br /&gt;    {&lt;br /&gt;        &lt;span&gt;Validator &lt;/span&gt;validator = &lt;span&gt;ValidationFactory&lt;/span&gt;.CreateValidator(&lt;span style="color:blue;"&gt;this&lt;/span&gt;.GetType());&lt;br /&gt;&lt;br /&gt;        &lt;span&gt;ValidationResults &lt;/span&gt;results = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span&gt;ValidationResults&lt;/span&gt;();&lt;br /&gt;&lt;br /&gt;        validator.Validate(&lt;span style="color:blue;"&gt;this&lt;/span&gt;, results);&lt;br /&gt;&lt;br /&gt;        &lt;span style="color:blue;"&gt;return &lt;/span&gt;results;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span&gt;Order &lt;/span&gt;: &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span&gt;BussinesObject&lt;br /&gt;&lt;/span&gt;{&lt;br /&gt;    &lt;span style="color:blue;"&gt;private int &lt;/span&gt;_id;&lt;br /&gt;    &lt;span style="color:blue;"&gt;private string &lt;/span&gt;_name;&lt;br /&gt;    &lt;span style="color:blue;"&gt;private string &lt;/span&gt;_type;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;private &lt;/span&gt;&lt;span&gt;IList&lt;/span&gt;&amp;lt;&lt;font color="#2b91af"&gt;Product&lt;/font&gt;&amp;gt; _products;&lt;br /&gt;&lt;br /&gt;    [&lt;span&gt;NotNullValidator&lt;/span&gt;]&lt;br /&gt;    [&lt;span&gt;StringLengthValidator&lt;/span&gt;(8,8)]&lt;br /&gt;    &lt;span style="color:blue;"&gt;public int &lt;/span&gt;ID &lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:blue;"&gt;get &lt;/span&gt;{ &lt;span style="color:blue;"&gt;return &lt;/span&gt;_id;  }&lt;br /&gt;        &lt;span style="color:blue;"&gt;set &lt;/span&gt;{ _id = &lt;span style="color:blue;"&gt;value&lt;/span&gt;; }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    [&lt;span&gt;NotNullValidator&lt;/span&gt;]&lt;br /&gt;    [&lt;span&gt;StringLengthValidator&lt;/span&gt;(255)]&lt;br /&gt;    &lt;span style="color:blue;"&gt;public string &lt;/span&gt;Name &lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:blue;"&gt;get &lt;/span&gt;{ &lt;span style="color:blue;"&gt;return &lt;/span&gt;_name;  }&lt;br /&gt;        &lt;span style="color:blue;"&gt;set &lt;/span&gt;{ _name = &lt;span style="color:blue;"&gt;value&lt;/span&gt;; } &lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    [&lt;span&gt;StringLengthValidator&lt;/span&gt;(4,4)]&lt;br /&gt;    &lt;span style="color:blue;"&gt;public string &lt;/span&gt;Type &lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:blue;"&gt;get &lt;/span&gt;{ &lt;span style="color:blue;"&gt;return &lt;/span&gt;_type;  }&lt;br /&gt;        &lt;span style="color:blue;"&gt;set &lt;/span&gt;{ _type = &lt;span style="color:blue;"&gt;value&lt;/span&gt;; }&lt;br /&gt;    }        &lt;br /&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;public void &lt;/span&gt;AddProduct(&lt;span&gt;Product &lt;/span&gt;product)&lt;br /&gt;    {&lt;br /&gt;        &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// ...&lt;br /&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;public void &lt;/span&gt;RemoveProduct(&lt;span style="color:blue;"&gt;int &lt;/span&gt;id)&lt;br /&gt;    {&lt;br /&gt;        &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// ..&lt;br /&gt;    &lt;/span&gt;}        &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span&gt;OrderRepository&lt;br /&gt;&lt;/span&gt;{&lt;br /&gt;    &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span&gt;Order &lt;/span&gt;Recover(&lt;span style="color:blue;"&gt;int &lt;/span&gt;id)&lt;br /&gt;    {&lt;br /&gt;        &lt;span&gt;Order &lt;/span&gt;order = &lt;span style="color:blue;"&gt;null&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;        &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// Gets the fields from database .. &lt;br /&gt;&lt;br /&gt;        // Apply the mapping ..&lt;br /&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color:blue;"&gt;return &lt;/span&gt;order;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;public void &lt;/span&gt;Create(&lt;span&gt;Order &lt;/span&gt;order)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:blue;"&gt;if &lt;/span&gt;(order.IsValid)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color:blue;"&gt;throw new &lt;/span&gt;&lt;span&gt;ValidationException&lt;/span&gt;(&lt;span&gt;&amp;quot;The order is not valid.&amp;quot;&lt;/span&gt;);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// Insert the order in the &amp;#39;Order&amp;#39; table ..&lt;br /&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;public void &lt;/span&gt;Update(&lt;span&gt;Order &lt;/span&gt;order)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:blue;"&gt;if &lt;/span&gt;(order.IsValid)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color:blue;"&gt;throw new &lt;/span&gt;&lt;span&gt;ValidationException&lt;/span&gt;(&lt;span&gt;&amp;quot;The order is not valid.&amp;quot;&lt;/span&gt;);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// Update the order in the &amp;#39;Order&amp;#39; table ..&lt;br /&gt;    &lt;/span&gt;}&lt;br /&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Los objetos del modelo de dominio no deben contener código para cargar el estado de base de datos ni tampoco para guardarlo, dicho código debe declararse en otras clases de la capa de negocio, una buena práctica para unificar este código es usar el patrón repositorio.&lt;/font&gt;&lt;/p&gt;

&lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;El patrón repositorio consiste en crear una capa de abstracción que actúe de puente entre la capa de datos y la capa de negocio.&lt;/font&gt;&lt;/p&gt;

&lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Las clases repositorio, deben poder invocarse desde la capa de presentación, y normalmente tenemos una por cada objeto.&lt;/font&gt;&lt;/p&gt;

&lt;p align="justify"&gt;La separación de las clases de negocio de la persistencia nos permite identificar los métodos de acceso a base de datos para posteriormente crear una interfaz que podremos usar desde una “fábrica de repositorios”, de esta forma podemos reutilizar el modelo de dominio con otros proveedores de base de datos.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&lt;font size="1" face="Verdana"&gt;public class &lt;/font&gt;&lt;/span&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span&gt;IOrderRepository&lt;br /&gt;&lt;/span&gt;{&lt;br /&gt;    &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span&gt;Order &lt;/span&gt;Recover(&lt;span style="color:blue;"&gt;int &lt;/span&gt;id);&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color:blue;"&gt;public void &lt;/span&gt;Create(&lt;span&gt;Order &lt;/span&gt;order);&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;public void &lt;/span&gt;Update(&lt;span&gt;Order &lt;/span&gt;order);    &lt;br /&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Dentro de los métodos de las clases “repositorio”, tenemos llamadas a la capa de datos puesto que en algún momento necesitaremos ejecutar un comando de base de datos, cuando utilizamos el patrón modelo de dominio las clases que realizan las operaciones de conversión de entidades a tablas son las clases que implementan el patrón “Data Mapper”.&lt;/font&gt;&lt;/p&gt;

&lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Una clase “Data Mapper” conoce las columnas de tablas de base de datos necesarias para recuperar el estado de una entidad de negocio.&lt;/font&gt;&lt;/p&gt;



&lt;p align="justify"&gt;Ahora bien, ¿Qué ocurre si no encontramos el estado de una entidad en base de datos?, básicamente tenemos 3 opciones :&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;div align="justify"&gt;Lanzar una excepción&lt;/div&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;div align="justify"&gt;Devolver null&lt;/div&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;div align="justify"&gt;Utilizar el patrón Special Case&lt;/div&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;font color="#ff8040"&gt;El patrón Special Case nos recomienda crear tipos específicos para indicar un fallo durante la recuperación del estado de una entidad de negocio de base de datos sin romper el polimorfismo.&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;La siguiente clase podemos usarla en el método Recover de la clase OrderRepository para indicar la ausencia de estado de entidades Order en base de datos :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span&gt;MissingOrder &lt;/span&gt;: &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span&gt;Order&lt;br /&gt;&lt;/span&gt;{&lt;br /&gt;    &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// ..&lt;br /&gt;&lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span&gt;OrderGateway&lt;br /&gt;&lt;/span&gt;{&lt;br /&gt;    &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span&gt;Order &lt;/span&gt;Recover(&lt;span style="color:blue;"&gt;int &lt;/span&gt;id)&lt;br /&gt;    {&lt;br /&gt;        &lt;span&gt;Order &lt;/span&gt;order = &lt;span style="color:blue;"&gt;null&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color:blue;"&gt;bool &lt;/span&gt;notFound = &lt;span style="color:blue;"&gt;false&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;        &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// Gets the notFound value from Database ..&lt;br /&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color:blue;"&gt;if &lt;/span&gt;(notFound)&lt;br /&gt;        {&lt;br /&gt;            order = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span&gt;MissingOrder&lt;/span&gt;();&lt;br /&gt;        }&lt;br /&gt;        &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:blue;"&gt;else&lt;br /&gt;        &lt;/span&gt;{&lt;br /&gt;            &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// Gets the fields from database .. &lt;br /&gt;&lt;br /&gt;            // Apply the mapping ..&lt;br /&gt;        &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;        &lt;span style="color:blue;"&gt;return &lt;/span&gt;order;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    ..&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;
Y eso ha sido todo por hoy ..
&lt;div id="postorigin" style="margin-left:5px;font-size:80%;padding:5px;border:2px solid #BDB67C;background-color:#DDDBC7;width:300px;text-align:center;-moz-border-radius:4px 4px 4px 4px;-webkit-border-radius:4px;border-radius:4px;"&gt;&lt;a href="http://kartones.net/blogs/coco/archive/2009/12/03/la-capa-de-negocio-vi-el-patr-243-n-modelo-de-dominio.aspx"&gt;La Capa de Negocio (VI) : El Patr&amp;#243;n Modelo de Dominio&lt;/a&gt; was posted the 12/03/2009 at &lt;a href="http://Kartones.net"&gt;Kartones.Net&lt;/a&gt;.&lt;/div&gt;
&lt;div id="sharing" class="postfoot"&gt;&lt;hr /&gt;&lt;p&gt;Share via:&lt;br&gt;&lt;a rel="nofollow" href="mailto:?subject=Kartones.Net:%20La+Capa+de+Negocio+(VI)+%3a+El+Patr%26%23243%3bn+Modelo+de+Dominio&amp;amp;body=http://kartones.net/blogs/coco/archive/2009/12/03/la-capa-de-negocio-vi-el-patr-243-n-modelo-de-dominio.aspx" target="_blank"&gt;Email&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.facebook.com/share.php?u=http://kartones.net/blogs/coco/archive/2009/12/03/la-capa-de-negocio-vi-el-patr-243-n-modelo-de-dominio.aspx&amp;amp;t=La+Capa+de+Negocio+(VI)+%3a+El+Patr%26%23243%3bn+Modelo+de+Dominio" target="_blank"&gt;Facebook&lt;/a&gt; | &lt;a rel="nofollow" href="http://twitter.com/home?status=http://kartones.net/blogs/coco/archive/2009/12/03/la-capa-de-negocio-vi-el-patr-243-n-modelo-de-dominio.aspx" target="_blank"&gt;Twitter&lt;/a&gt; | &lt;a rel="nofollow" href="http://slashdot.org/bookmark.pl?url=http://kartones.net/blogs/coco/archive/2009/12/03/la-capa-de-negocio-vi-el-patr-243-n-modelo-de-dominio.aspx&amp;amp;title=La+Capa+de+Negocio+(VI)+%3a+El+Patr%26%23243%3bn+Modelo+de+Dominio" target="_blank"&gt;SlashDot&lt;/a&gt; | &lt;a rel="nofollow" href="http://delicious.com/post?url=http://kartones.net/blogs/coco/archive/2009/12/03/la-capa-de-negocio-vi-el-patr-243-n-modelo-de-dominio.aspx&amp;amp;title=La+Capa+de+Negocio+(VI)+%3a+El+Patr%26%23243%3bn+Modelo+de+Dominio" target="_blank"&gt;del.icio.us&lt;/a&gt; | &lt;a rel="nofollow" href="http://technorati.com/faves?add=http://kartones.net/blogs/coco/archive/2009/12/03/la-capa-de-negocio-vi-el-patr-243-n-modelo-de-dominio.aspx" target="_blank"&gt;Technorati&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http://kartones.net/blogs/coco/archive/2009/12/03/la-capa-de-negocio-vi-el-patr-243-n-modelo-de-dominio.aspx&amp;amp;title=La+Capa+de+Negocio+(VI)+%3a+El+Patr%26%23243%3bn+Modelo+de+Dominio" target="_blank"&gt;Stumbleupon&lt;/a&gt; | &lt;a rel="nofollow" href="http://reddit.com/submit?url=http://kartones.net/blogs/coco/archive/2009/12/03/la-capa-de-negocio-vi-el-patr-243-n-modelo-de-dominio.aspx&amp;amp;title=La+Capa+de+Negocio+(VI)+%3a+El+Patr%26%23243%3bn+Modelo+de+Dominio" target="_blank"&gt;Reddit&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.google.com/reader/link?url=http://kartones.net/blogs/coco/archive/2009/12/03/la-capa-de-negocio-vi-el-patr-243-n-modelo-de-dominio.aspx&amp;amp;title=La+Capa+de+Negocio+(VI)+%3a+El+Patr%26%23243%3bn+Modelo+de+Dominio&amp;amp;srcUrl=http://kartones.net/blogs/coco/archive/2009/12/03/la-capa-de-negocio-vi-el-patr-243-n-modelo-de-dominio.aspx&amp;amp;srcTitle=La+Capa+de+Negocio+(VI)+%3a+El+Patr%26%23243%3bn+Modelo+de+Dominio" target="_blank"&gt;Google Reader&lt;/a&gt; | &lt;a rel="nofollow" href="http://meneame.net/submit.php?url=http://kartones.net/blogs/coco/archive/2009/12/03/la-capa-de-negocio-vi-el-patr-243-n-modelo-de-dominio.aspx" target="_blank"&gt;Meneame&lt;/a&gt; | &lt;a rel="nofollow" href="http://bitacoras.com/anotaciones/http://kartones.net/blogs/coco/archive/2009/12/03/la-capa-de-negocio-vi-el-patr-243-n-modelo-de-dominio.aspx" target="_blank"&gt;Bitacoras&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.linkedin.com/shareArticle?mini=true&amp;amp;url=http://kartones.net/blogs/coco/archive/2009/12/03/la-capa-de-negocio-vi-el-patr-243-n-modelo-de-dominio.aspx&amp;amp;title=La+Capa+de+Negocio+(VI)+%3a+El+Patr%26%23243%3bn+Modelo+de+Dominio&amp;amp;source=Kartones.Net" target="_blank"&gt;LinkedIn&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.google.com/bookmarks/mark?op=edit&amp;amp;bkmk=http://kartones.net/blogs/coco/archive/2009/12/03/la-capa-de-negocio-vi-el-patr-243-n-modelo-de-dominio.aspx&amp;amp;title=La+Capa+de+Negocio+(VI)+%3a+El+Patr%26%23243%3bn+Modelo+de+Dominio" target="_blank"&gt;Google Bookmarks&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.google.com/reader/link?url=http://kartones.net/blogs/coco/archive/2009/12/03/la-capa-de-negocio-vi-el-patr-243-n-modelo-de-dominio.aspx&amp;amp;title=La+Capa+de+Negocio+(VI)+%3a+El+Patr%26%23243%3bn+Modelo+de+Dominio" target="_blank"&gt;Google Reader&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.google.com/buzz/post?url=http://kartones.net/blogs/coco/archive/2009/12/03/la-capa-de-negocio-vi-el-patr-243-n-modelo-de-dominio.aspx&amp;amp;imageurl=" target="_blank"&gt;Google Buzz&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.friendfeed.com/share?title=La+Capa+de+Negocio+(VI)+%3a+El+Patr%26%23243%3bn+Modelo+de+Dominio&amp;amp;link=http://kartones.net/blogs/coco/archive/2009/12/03/la-capa-de-negocio-vi-el-patr-243-n-modelo-de-dominio.aspx" target="_blank"&gt;FriendFeed&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.netvibes.com/share?title=La+Capa+de+Negocio+(VI)+%3a+El+Patr%26%23243%3bn+Modelo+de+Dominio&amp;amp;url=http://kartones.net/blogs/coco/archive/2009/12/03/la-capa-de-negocio-vi-el-patr-243-n-modelo-de-dominio.aspx" target="_blank"&gt;Netvibes&lt;/a&gt; | &lt;a rel="nofollow" href="https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;mkt=es-es&amp;amp;url=http://kartones.net/blogs/coco/archive/2009/12/03/la-capa-de-negocio-vi-el-patr-243-n-modelo-de-dominio.aspx&amp;amp;title=La+Capa+de+Negocio+(VI)+%3a+El+Patr%26%23243%3bn+Modelo+de+Dominio" target="_blank"&gt;Windows Live&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.myspace.com/Modules/PostTo/Pages/?u=http://kartones.net/blogs/coco/archive/2009/12/03/la-capa-de-negocio-vi-el-patr-243-n-modelo-de-dominio.aspx&amp;amp;t=La+Capa+de+Negocio+(VI)+%3a+El+Patr%26%23243%3bn+Modelo+de+Dominio" target="_blank"&gt;MySpace&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;img src="http://kartones.net/aggbug.aspx?PostID=50578" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/ElFrameworkDeCoco/~4/rZ3q3O7MP2Q" height="1" width="1"/&gt;</description><category domain="http://kartones.net/blogs/coco/archive/tags/Capa+de+negocio/default.aspx">Capa de negocio</category><category domain="http://kartones.net/blogs/coco/archive/tags/Patron+Modelo+de+Dominio/default.aspx">Patron Modelo de Dominio</category><category domain="http://kartones.net/blogs/coco/archive/tags/Patr_26002300_243_3B00_n+Repositorio/default.aspx">Patr&amp;#243;n Repositorio</category><category domain="http://kartones.net/blogs/coco/archive/tags/Patr_26002300_243_3B00_n+Special+Case/default.aspx">Patr&amp;#243;n Special Case</category><category domain="http://kartones.net/blogs/coco/archive/tags/Patr_26002300_243_3B00_n+Data+Mapper/default.aspx">Patr&amp;#243;n Data Mapper</category><feedburner:origLink>http://kartones.net/blogs/coco/archive/2009/12/03/la-capa-de-negocio-vi-el-patr-243-n-modelo-de-dominio.aspx</feedburner:origLink></item><item><title>La Capa de Negocio (V) : El Patrón Active Record</title><link>http://feeds.kartones.net/~r/ElFrameworkDeCoco/~3/WRNPgx0qMsQ/la-capa-de-negocio-v-el-patr-243-n-active-record.aspx</link><pubDate>Wed, 02 Dec 2009 13:16:30 GMT</pubDate><guid isPermaLink="false">b86c0850-82e5-42ed-a9d8-bde9e8f94ec1:50576</guid><dc:creator>ccrego</dc:creator><slash:comments>0</slash:comments><comments>http://kartones.net/blogs/coco/archive/2009/12/02/la-capa-de-negocio-v-el-patr-243-n-active-record.aspx#comments</comments><description>&lt;p align="justify"&gt;Los patrones “Table Module” y “Transaction Script”, son patrones procedimentales cuyo foco de implementación está en el modelo de datos en lugar de en casos de uso, sin embargo el patrón “Table Module” está basado en objetos que representan tablas no en objetos de negocio puros.&lt;/p&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Al conjunto de objetos y cálculos se le conoce como lógica de negocio y está basada en interacciones entre objetos, por tanto para modelar la lógica se requiere de una visión orientada a objetos y no a datos.&lt;/font&gt;&lt;/p&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;El patrón “Active Record” es una buena elección cuando se requiere de una visión orientada a objetos para implementar una lógica de negocio no muy compleja.&lt;/font&gt;&lt;/p&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Un objeto “Active Record”, es un objeto que representa un registro de una tabla en base de datos y que se compone de propiedades (que representan las columnas) y métodos.&lt;/font&gt;&lt;/p&gt;  &lt;p align="justify"&gt;Por ejemplo, si tenemos un objeto “Active Record” representando un registro de la tabla Clientes, tendremos propiedades como el identificador, el nombre, el cif y el tipo de cliente.&lt;/p&gt;  &lt;p align="justify"&gt;Los componentes más comunes en toda clase “Active Record” son los siguientes :&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;     &lt;div align="justify"&gt;Propiedades representando las columnas del registro que se está representando.&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;Métodos de instancia que representan la lógica aplicada al registro representado.&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;Métodos estáticos que actúan sobre cualquier registro.&lt;/div&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p align="justify"&gt;El patrón Active Record funciona bien en escenarios donde la lógica de negocio no es muy compleja y donde además no se requiere de capas de abstracción adicionales sobre el modelo de datos.&lt;/p&gt;  &lt;p align="justify"&gt;Desarrollar y mantener una clase “Active Record” por cada tabla puede llegar a ser un autentico infierno si no disponemos de una herramienta ORM que nos de soporte durante la fase de desarrollo y mantenimiento, menos mal que en el mercado tenemos multitud de herramientas de este tipo :&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;     &lt;div align="justify"&gt;LINQ To SQL&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;Entity Framework&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;NHibernate&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;Castle Active Record&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;…&lt;/div&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Cuando implementamos el patrón “Active Record”, es necesario de una capa adicional que nos permita convertir registros de base de datos a instancias de clase “Active Record”, a esta capa adicional se la conoce como “Capa de mapeo de datos”, aunque los desarrolladores la conocemos mejor por “Mappers”.&lt;/font&gt;&lt;/p&gt;  &lt;p align="justify"&gt;La capa de mapeo de datos nos permite desacoplar nuestra clase “Active Record” de la tabla de base de datos correspondiente, puesto que cualquier cambio en el esquema de la tabla, puede implicar modificar la clase “Active Record” correspondiente, aunque hay cambios donde no nos quedara más remedio.&lt;/p&gt;  &lt;p align="justify"&gt;Otro de los puntos débiles de “Active Record” está en el desarrollo de operaciones donde tengamos que trabajar con miles de registros, ya que no nos quedará más remedio que trabajar con miles de instancias de objetos “Active Record” en casos de operaciones de carga o actualización masiva de datos es mejor usar tecnología ADO.NET.&lt;/p&gt;  &lt;p align="justify"&gt;Veamos un ejemplo de clase “Active Record” :&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&lt;font size="1" face="Verdana"&gt;public class &lt;/font&gt;&lt;/span&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;Company
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;private string &lt;/span&gt;cif;
    &lt;span style="color:blue;"&gt;private string &lt;/span&gt;nationality;
    &lt;span style="color:blue;"&gt;private string &lt;/span&gt;name;
    &lt;span style="color:blue;"&gt;private string &lt;/span&gt;sector;
    &lt;span style="color:blue;"&gt;private &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;CompanyType &lt;/span&gt;type;

    &lt;span style="color:blue;"&gt;public string &lt;/span&gt;CIF
    {
        &lt;span style="color:blue;"&gt;get &lt;/span&gt;{ &lt;span style="color:blue;"&gt;return &lt;/span&gt;cif; }
        &lt;span style="color:blue;"&gt;set &lt;/span&gt;{ cif = &lt;span style="color:blue;"&gt;value&lt;/span&gt;; }
    }

    &lt;span style="color:blue;"&gt;public string &lt;/span&gt;Name
    {
        &lt;span style="color:blue;"&gt;get &lt;/span&gt;{ &lt;span style="color:blue;"&gt;return &lt;/span&gt;name; }
        &lt;span style="color:blue;"&gt;set &lt;/span&gt;{ name = &lt;span style="color:blue;"&gt;value&lt;/span&gt;; }
    }

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;CompanyType &lt;/span&gt;Type
    {
        &lt;span style="color:blue;"&gt;get &lt;/span&gt;{ &lt;span style="color:blue;"&gt;return &lt;/span&gt;type; }
        &lt;span style="color:blue;"&gt;set &lt;/span&gt;{ type = &lt;span style="color:blue;"&gt;value&lt;/span&gt;; }
    }

    &lt;span style="color:blue;"&gt;public string &lt;/span&gt;Sector
    {
        &lt;span style="color:blue;"&gt;get &lt;/span&gt;{ &lt;span style="color:blue;"&gt;return &lt;/span&gt;sector; }
        &lt;span style="color:blue;"&gt;set &lt;/span&gt;{ sector = &lt;span style="color:blue;"&gt;value&lt;/span&gt;; }
    }

    &lt;span style="color:blue;"&gt;public string &lt;/span&gt;Nationality
    {
        &lt;span style="color:blue;"&gt;get &lt;/span&gt;{ &lt;span style="color:blue;"&gt;return &lt;/span&gt;nationality; }
        &lt;span style="color:blue;"&gt;set &lt;/span&gt;{ nationality = &lt;span style="color:blue;"&gt;value&lt;/span&gt;; }
    }

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;Company() { }

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;Company(&lt;span style="color:blue;"&gt;string &lt;/span&gt;cif)
    {

    }

    &lt;span style="color:blue;"&gt;public int &lt;/span&gt;Insert()
    {
        &lt;span style="color:blue;"&gt;int &lt;/span&gt;newId = 0;

        &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// Insert the company record in the Company table ..

        &lt;/span&gt;&lt;span style="color:blue;"&gt;return &lt;/span&gt;newId;
    }

    &lt;span style="color:blue;"&gt;public void &lt;/span&gt;Delete()
    {
        &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// Delete the company record in the Company table ..
    &lt;/span&gt;}

    &lt;span style="color:blue;"&gt;public void &lt;/span&gt;Update()
    {
        &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// Update the company record in the Company table ..
    &lt;/span&gt;}

    &lt;span style="color:blue;"&gt;public static int &lt;/span&gt;GetCount()
    {
        &lt;span style="color:blue;"&gt;int &lt;/span&gt;count = 0;

        &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// Gets the total of Companies in the Company table ..

        &lt;/span&gt;&lt;span style="color:blue;"&gt;return &lt;/span&gt;count;
    }

    &lt;span style="color:blue;"&gt;public static &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IList&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Company&lt;/span&gt;&amp;gt; LoadAll()
    {
        &lt;span style="color:#2b91af;"&gt;IList&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Company&lt;/span&gt;&amp;gt; lst = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Company&lt;/span&gt;&amp;gt;();

        &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// Gets all the Companies in the Company table ..
        // For many records, use DataTable with ADO.NET ..

        &lt;/span&gt;&lt;span style="color:blue;"&gt;return &lt;/span&gt;lst;
    }
}&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p align="justify"&gt;Otro de los aspectos a tener en cuenta cuando diseñamos un objeto “Active Record” es que las tablas de base de datos contienen claves ajenas que referencian a otras tablas, en este aspecto “Active Record” no es distinto y por tanto debemos tomar la decisión de referenciar a otros objetos “Active Record” a través de un identificador o de un objeto puro :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&lt;font size="1" face="Verdana"&gt;public class &lt;/font&gt;&lt;/span&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;Company
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;private string &lt;/span&gt;cif;
    &lt;span style="color:blue;"&gt;private int &lt;/span&gt;sectorId;

    &lt;span style="color:blue;"&gt;public int &lt;/span&gt;IDSector
    {
        &lt;span style="color:blue;"&gt;get &lt;/span&gt;{ &lt;span style="color:blue;"&gt;return &lt;/span&gt;sectorId; }
        &lt;span style="color:blue;"&gt;set &lt;/span&gt;{ sectorId = &lt;span style="color:blue;"&gt;value&lt;/span&gt;; }
    }

    ...&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&lt;font size="1" face="Verdana"&gt;public class &lt;/font&gt;&lt;/span&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;Company
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;private string &lt;/span&gt;cif;
    &lt;span style="color:blue;"&gt;private &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Sector &lt;/span&gt;sector;

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Sector &lt;/span&gt;Sector
    {
        &lt;span style="color:blue;"&gt;get &lt;/span&gt;{ &lt;span style="color:blue;"&gt;return &lt;/span&gt;sector; }
        &lt;span style="color:blue;"&gt;set &lt;/span&gt;{ sector = &lt;span style="color:blue;"&gt;value&lt;/span&gt;; }
    }

    ...&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p align="justify"&gt;Aunque para gustos los colores, es muy recomendable guardar una estructura lo más cercana a la tabla de base de datos que estamos representando, por tanto es preferible utilizar identificadores en lugar de objetos para referenciar otros objetos Active Record.&lt;/p&gt;

&lt;p align="justify"&gt;Otro aspecto importante es el de conversiones de datos puesto que cuando desarrollamos una clase “Active Record” debemos tomar la decisión de traernos los datos en formato original, o aplicar una conversión por ejemplo a un enumerado.&lt;/p&gt;

&lt;p align="justify"&gt;En general la conversión de tipos está bien cuando por ejemplo usando datos Nullables :&lt;/p&gt;

&lt;p align="justify"&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Nullable&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt; IDSector

      &lt;br /&gt;{

      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;get &lt;/span&gt;{ &lt;span style="color:blue;"&gt;return &lt;/span&gt;sectorId; }

      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;set&lt;/span&gt;{ sectorId = &lt;span style="color:blue;"&gt;value&lt;/span&gt;; }

      &lt;br /&gt;}

      &lt;br /&gt;

      &lt;br /&gt;&lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Nullable&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;DateTime&lt;/span&gt;&amp;gt; LastModificationDate

      &lt;br /&gt;{

      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;get &lt;/span&gt;{ &lt;span style="color:blue;"&gt;return &lt;/span&gt;lastModificationDate; }

      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;set&lt;/span&gt;{ lastModificationDate = &lt;span style="color:blue;"&gt;value&lt;/span&gt;; }

      &lt;br /&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p align="justify"&gt;Sin embargo, no es aconsejable agrupar propiedades en un nuevo objeto ya que estaremos añadiendo un nuevo nivel de abstracción al escribir un código más elaborado y que para nada representa fielmente la estructura del registro de la tabla de base de datos correspondiente :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&lt;font size="1" face="Verdana"&gt;public class &lt;/font&gt;&lt;/span&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;Company
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;private string &lt;/span&gt;cif;
    &lt;span style="color:blue;"&gt;private string &lt;/span&gt;street;
    &lt;span style="color:blue;"&gt;private string &lt;/span&gt;streetType;
    &lt;span style="color:blue;"&gt;private string &lt;/span&gt;country;
    &lt;span style="color:blue;"&gt;private string &lt;/span&gt;zipCode;

    &lt;span style="color:blue;"&gt;public string &lt;/span&gt;CIF
    {
      &lt;span style="color:blue;"&gt;get &lt;/span&gt;{ &lt;span style="color:blue;"&gt;return &lt;/span&gt;cif; }
      &lt;span style="color:blue;"&gt;set &lt;/span&gt;{ cif = &lt;span style="color:blue;"&gt;value&lt;/span&gt;; }
    }

    &lt;span style="color:blue;"&gt;public string &lt;/span&gt;Street
    {
      &lt;span style="color:blue;"&gt;get &lt;/span&gt;{ &lt;span style="color:blue;"&gt;return &lt;/span&gt;street; }
      &lt;span style="color:blue;"&gt;set &lt;/span&gt;{ street = &lt;span style="color:blue;"&gt;value&lt;/span&gt;; }
    }

    &lt;span style="color:blue;"&gt;public string &lt;/span&gt;StreetType
    {
      &lt;span style="color:blue;"&gt;get &lt;/span&gt;{ &lt;span style="color:blue;"&gt;return &lt;/span&gt;streetType; }
      &lt;span style="color:blue;"&gt;set &lt;/span&gt;{ streetType = &lt;span style="color:blue;"&gt;value&lt;/span&gt;; }
    }

    &lt;span style="color:blue;"&gt;public string &lt;/span&gt;ZipCode
    {
      &lt;span style="color:blue;"&gt;get &lt;/span&gt;{ &lt;span style="color:blue;"&gt;return &lt;/span&gt;zipCode; }
      &lt;span style="color:blue;"&gt;set &lt;/span&gt;{ zipCode = &lt;span style="color:blue;"&gt;value&lt;/span&gt;; }
    }
        &lt;span style="color:blue;"&gt;private string &lt;/span&gt;city;

    &lt;span style="color:blue;"&gt;public string &lt;/span&gt;City
    {
      &lt;span style="color:blue;"&gt;get &lt;/span&gt;{ &lt;span style="color:blue;"&gt;return &lt;/span&gt;city; }
      &lt;span style="color:blue;"&gt;set &lt;/span&gt;{ city = &lt;span style="color:blue;"&gt;value&lt;/span&gt;; }
    }
    
    ...&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&lt;font size="1" face="Verdana"&gt;public class &lt;/font&gt;&lt;/span&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;Address 
&lt;/span&gt;{ 
    &lt;span style="color:blue;"&gt;private string &lt;/span&gt;street;
    &lt;span style="color:blue;"&gt;private string &lt;/span&gt;streetType;
    &lt;span style="color:blue;"&gt;private string &lt;/span&gt;city;
    &lt;span style="color:blue;"&gt;private string &lt;/span&gt;zipCode;

    &lt;span style="color:blue;"&gt;public string &lt;/span&gt;Street
    {
      &lt;span style="color:blue;"&gt;get &lt;/span&gt;{ &lt;span style="color:blue;"&gt;return &lt;/span&gt;street; }
      &lt;span style="color:blue;"&gt;set &lt;/span&gt;{ street = &lt;span style="color:blue;"&gt;value&lt;/span&gt;; }
    }

    &lt;span style="color:blue;"&gt;public string &lt;/span&gt;StreetType
    {
      &lt;span style="color:blue;"&gt;get &lt;/span&gt;{ &lt;span style="color:blue;"&gt;return &lt;/span&gt;streetType; }
      &lt;span style="color:blue;"&gt;set &lt;/span&gt;{ streetType = &lt;span style="color:blue;"&gt;value&lt;/span&gt;; }
    }

    &lt;span style="color:blue;"&gt;public string &lt;/span&gt;ZipCode
    {
      &lt;span style="color:blue;"&gt;get &lt;/span&gt;{ &lt;span style="color:blue;"&gt;return &lt;/span&gt;zipCode; }
      &lt;span style="color:blue;"&gt;set &lt;/span&gt;{ zipCode = &lt;span style="color:blue;"&gt;value&lt;/span&gt;; }
    }

    &lt;span style="color:blue;"&gt;public string &lt;/span&gt;City
    {
      &lt;span style="color:blue;"&gt;get &lt;/span&gt;{ &lt;span style="color:blue;"&gt;return &lt;/span&gt;city; }
      &lt;span style="color:blue;"&gt;set &lt;/span&gt;{ city = &lt;span style="color:blue;"&gt;value&lt;/span&gt;; }
    }

    ...

&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;Company
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;private string &lt;/span&gt;cif;
    &lt;span style="color:blue;"&gt;private &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Address &lt;/span&gt;address;

    &lt;span style="color:blue;"&gt;public string &lt;/span&gt;CIF
    {
      &lt;span style="color:blue;"&gt;get &lt;/span&gt;{ &lt;span style="color:blue;"&gt;return &lt;/span&gt;cif; }
      &lt;span style="color:blue;"&gt;set &lt;/span&gt;{ cif = &lt;span style="color:blue;"&gt;value&lt;/span&gt;; }
    }

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Address &lt;/span&gt;Address
    {
      &lt;span style="color:blue;"&gt;get &lt;/span&gt;{ &lt;span style="color:blue;"&gt;return &lt;/span&gt;address; }
      &lt;span style="color:blue;"&gt;set &lt;/span&gt;{ address = &lt;span style="color:blue;"&gt;value&lt;/span&gt;; }
    }

    ..&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p align="justify"&gt;Cuando agrupamos propiedades en nuevos objetos, nos estamos moviendo hacia una implementación más propia del patrón “Modelo de dominio” del cual hablare en el siguiente post.&lt;/p&gt;

&lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Para terminar me gustaría hablar sobre el framework “Castle Active Record” ya que se trata de una implementación Open Source del patrón “Active Record” para la plataforma .NET.&lt;/font&gt;&lt;/p&gt;

&lt;p align="justify"&gt;Castle Active Record esta construido sobre NHibernate y por tanto su funcionalidad está basada en la configuración de un fichero Xml que contiene las relaciones entre tablas, sin embargo nos abstrae de muchos detalles que no necesitamos de NHibernate para implementar el patrón “Active Record”.&lt;/p&gt;

&lt;p align="justify"&gt;Más adelante dedicaré un post para cubrir la funcionalidad que nos ofrece este framework.&lt;/p&gt;

&lt;p align="justify"&gt;Y eso ha sido todo por hoy .. &lt;/p&gt;
&lt;div id="postorigin" style="margin-left:5px;font-size:80%;padding:5px;border:2px solid #BDB67C;background-color:#DDDBC7;width:300px;text-align:center;-moz-border-radius:4px 4px 4px 4px;-webkit-border-radius:4px;border-radius:4px;"&gt;&lt;a href="http://kartones.net/blogs/coco/archive/2009/12/02/la-capa-de-negocio-v-el-patr-243-n-active-record.aspx"&gt;La Capa de Negocio (V) : El Patr&amp;#243;n Active Record&lt;/a&gt; was posted the 12/02/2009 at &lt;a href="http://Kartones.net"&gt;Kartones.Net&lt;/a&gt;.&lt;/div&gt;
&lt;div id="sharing" class="postfoot"&gt;&lt;hr /&gt;&lt;p&gt;Share via:&lt;br&gt;&lt;a rel="nofollow" href="mailto:?subject=Kartones.Net:%20La+Capa+de+Negocio+(V)+%3a+El+Patr%26%23243%3bn+Active+Record&amp;amp;body=http://kartones.net/blogs/coco/archive/2009/12/02/la-capa-de-negocio-v-el-patr-243-n-active-record.aspx" target="_blank"&gt;Email&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.facebook.com/share.php?u=http://kartones.net/blogs/coco/archive/2009/12/02/la-capa-de-negocio-v-el-patr-243-n-active-record.aspx&amp;amp;t=La+Capa+de+Negocio+(V)+%3a+El+Patr%26%23243%3bn+Active+Record" target="_blank"&gt;Facebook&lt;/a&gt; | &lt;a rel="nofollow" href="http://twitter.com/home?status=http://kartones.net/blogs/coco/archive/2009/12/02/la-capa-de-negocio-v-el-patr-243-n-active-record.aspx" target="_blank"&gt;Twitter&lt;/a&gt; | &lt;a rel="nofollow" href="http://slashdot.org/bookmark.pl?url=http://kartones.net/blogs/coco/archive/2009/12/02/la-capa-de-negocio-v-el-patr-243-n-active-record.aspx&amp;amp;title=La+Capa+de+Negocio+(V)+%3a+El+Patr%26%23243%3bn+Active+Record" target="_blank"&gt;SlashDot&lt;/a&gt; | &lt;a rel="nofollow" href="http://delicious.com/post?url=http://kartones.net/blogs/coco/archive/2009/12/02/la-capa-de-negocio-v-el-patr-243-n-active-record.aspx&amp;amp;title=La+Capa+de+Negocio+(V)+%3a+El+Patr%26%23243%3bn+Active+Record" target="_blank"&gt;del.icio.us&lt;/a&gt; | &lt;a rel="nofollow" href="http://technorati.com/faves?add=http://kartones.net/blogs/coco/archive/2009/12/02/la-capa-de-negocio-v-el-patr-243-n-active-record.aspx" target="_blank"&gt;Technorati&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http://kartones.net/blogs/coco/archive/2009/12/02/la-capa-de-negocio-v-el-patr-243-n-active-record.aspx&amp;amp;title=La+Capa+de+Negocio+(V)+%3a+El+Patr%26%23243%3bn+Active+Record" target="_blank"&gt;Stumbleupon&lt;/a&gt; | &lt;a rel="nofollow" href="http://reddit.com/submit?url=http://kartones.net/blogs/coco/archive/2009/12/02/la-capa-de-negocio-v-el-patr-243-n-active-record.aspx&amp;amp;title=La+Capa+de+Negocio+(V)+%3a+El+Patr%26%23243%3bn+Active+Record" target="_blank"&gt;Reddit&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.google.com/reader/link?url=http://kartones.net/blogs/coco/archive/2009/12/02/la-capa-de-negocio-v-el-patr-243-n-active-record.aspx&amp;amp;title=La+Capa+de+Negocio+(V)+%3a+El+Patr%26%23243%3bn+Active+Record&amp;amp;srcUrl=http://kartones.net/blogs/coco/archive/2009/12/02/la-capa-de-negocio-v-el-patr-243-n-active-record.aspx&amp;amp;srcTitle=La+Capa+de+Negocio+(V)+%3a+El+Patr%26%23243%3bn+Active+Record" target="_blank"&gt;Google Reader&lt;/a&gt; | &lt;a rel="nofollow" href="http://meneame.net/submit.php?url=http://kartones.net/blogs/coco/archive/2009/12/02/la-capa-de-negocio-v-el-patr-243-n-active-record.aspx" target="_blank"&gt;Meneame&lt;/a&gt; | &lt;a rel="nofollow" href="http://bitacoras.com/anotaciones/http://kartones.net/blogs/coco/archive/2009/12/02/la-capa-de-negocio-v-el-patr-243-n-active-record.aspx" target="_blank"&gt;Bitacoras&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.linkedin.com/shareArticle?mini=true&amp;amp;url=http://kartones.net/blogs/coco/archive/2009/12/02/la-capa-de-negocio-v-el-patr-243-n-active-record.aspx&amp;amp;title=La+Capa+de+Negocio+(V)+%3a+El+Patr%26%23243%3bn+Active+Record&amp;amp;source=Kartones.Net" target="_blank"&gt;LinkedIn&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.google.com/bookmarks/mark?op=edit&amp;amp;bkmk=http://kartones.net/blogs/coco/archive/2009/12/02/la-capa-de-negocio-v-el-patr-243-n-active-record.aspx&amp;amp;title=La+Capa+de+Negocio+(V)+%3a+El+Patr%26%23243%3bn+Active+Record" target="_blank"&gt;Google Bookmarks&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.google.com/reader/link?url=http://kartones.net/blogs/coco/archive/2009/12/02/la-capa-de-negocio-v-el-patr-243-n-active-record.aspx&amp;amp;title=La+Capa+de+Negocio+(V)+%3a+El+Patr%26%23243%3bn+Active+Record" target="_blank"&gt;Google Reader&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.google.com/buzz/post?url=http://kartones.net/blogs/coco/archive/2009/12/02/la-capa-de-negocio-v-el-patr-243-n-active-record.aspx&amp;amp;imageurl=" target="_blank"&gt;Google Buzz&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.friendfeed.com/share?title=La+Capa+de+Negocio+(V)+%3a+El+Patr%26%23243%3bn+Active+Record&amp;amp;link=http://kartones.net/blogs/coco/archive/2009/12/02/la-capa-de-negocio-v-el-patr-243-n-active-record.aspx" target="_blank"&gt;FriendFeed&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.netvibes.com/share?title=La+Capa+de+Negocio+(V)+%3a+El+Patr%26%23243%3bn+Active+Record&amp;amp;url=http://kartones.net/blogs/coco/archive/2009/12/02/la-capa-de-negocio-v-el-patr-243-n-active-record.aspx" target="_blank"&gt;Netvibes&lt;/a&gt; | &lt;a rel="nofollow" href="https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;mkt=es-es&amp;amp;url=http://kartones.net/blogs/coco/archive/2009/12/02/la-capa-de-negocio-v-el-patr-243-n-active-record.aspx&amp;amp;title=La+Capa+de+Negocio+(V)+%3a+El+Patr%26%23243%3bn+Active+Record" target="_blank"&gt;Windows Live&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.myspace.com/Modules/PostTo/Pages/?u=http://kartones.net/blogs/coco/archive/2009/12/02/la-capa-de-negocio-v-el-patr-243-n-active-record.aspx&amp;amp;t=La+Capa+de+Negocio+(V)+%3a+El+Patr%26%23243%3bn+Active+Record" target="_blank"&gt;MySpace&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;img src="http://kartones.net/aggbug.aspx?PostID=50576" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/ElFrameworkDeCoco/~4/WRNPgx0qMsQ" height="1" width="1"/&gt;</description><category domain="http://kartones.net/blogs/coco/archive/tags/Capa+de+negocio/default.aspx">Capa de negocio</category><category domain="http://kartones.net/blogs/coco/archive/tags/Patr_26002300_243_3B00_n+Active+Record/default.aspx">Patr&amp;#243;n Active Record</category><feedburner:origLink>http://kartones.net/blogs/coco/archive/2009/12/02/la-capa-de-negocio-v-el-patr-243-n-active-record.aspx</feedburner:origLink></item><item><title>La Capa de Negocio (IV) : El Patrón Table Module</title><link>http://feeds.kartones.net/~r/ElFrameworkDeCoco/~3/rSZkJ6SolIs/la-capa-de-negocio-iv-el-patr-243-n-table-module.aspx</link><pubDate>Tue, 01 Dec 2009 23:59:24 GMT</pubDate><guid isPermaLink="false">b86c0850-82e5-42ed-a9d8-bde9e8f94ec1:50575</guid><dc:creator>ccrego</dc:creator><slash:comments>0</slash:comments><comments>http://kartones.net/blogs/coco/archive/2009/12/01/la-capa-de-negocio-iv-el-patr-243-n-table-module.aspx#comments</comments><description>&lt;p align="justify"&gt;En escenarios de negocio sencillos es muy probable que podamos convertir cada tabla de base de datos en un componente de negocio.&lt;/p&gt;  &lt;p align="justify"&gt;En la aplicación del patrón “Transaction Script” es muy común usar objetos de tipo DTO para el intercambio de datos, en estos casos lo más normal es que cada propiedad del objeto DTO haga referencia a una columna en base de datos.&lt;/p&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;El patrón “Table Module” consiste en el mapeo de tablas de base de datos a componentes de negocio que contienen las operaciones necesarias para operar con los datos.&lt;/font&gt;&lt;/p&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Los datos con los que trabaja una clase “Table Module” no deben alcanzar &lt;/font&gt;&lt;font color="#ff8040"&gt;nunca el nivel de fila de datos, en su lugar, se debe trabajar a nivel de tabla y especificar una clave o índice para referenciar una fila en particular.&lt;/font&gt;&lt;/p&gt;  &lt;p align="justify"&gt;Seguramente os preguntareis como se realiza el intercambio de datos entre la capa de presentación y la capa de negocio, la respuesta es muy simple, a través de una representación tabular de los datos.&lt;/p&gt;  &lt;p align="justify"&gt;Cuando un sistema utiliza estructuras tabulares de datos en la capa de presentación y en la capa de datos, el patrón “Table Module” funciona a la perfección puesto que la capa de negocio puede intercambiar datos con la capa de datos de forma directa.&lt;/p&gt;  &lt;p align="justify"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:block;float:none;margin-left:auto;border-top:0px;margin-right:auto;border-right:0px;" title="PatronTableModule[1]" border="0" alt="PatronTableModule[1]" src="http://kartones.net/blogs/coco/PatronTableModule1_thumb_18BEA3BA.jpg" width="356" height="253" /&gt; &lt;/p&gt;  &lt;p align="justify"&gt;El patrón “Table Module” no es más complejo que el patrón “Transaction Script”, pero implementarlo con un modelo de datos complejo puede resultar muy laborioso, menos mal que en Visual Studio.NET disponemos de asistentes para crear nuestros orígenes de datos como estructuras de tipo DataSet.&lt;/p&gt;  &lt;p align="justify"&gt;Mediante el uso del diseñador de objetos Dataset, podemos añadir tablas desde la base de datos y definir las relaciones y restricciones de nuestro modelo.&lt;/p&gt;  &lt;p align="justify"&gt;&lt;a href="http://kartones.net/blogs/coco/DataSetDesigner1_3935BD9F.jpg"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="DataSetDesigner[1]" border="0" alt="DataSetDesigner[1]" src="http://kartones.net/blogs/coco/DataSetDesigner1_thumb_27297A12.jpg" width="532" height="229" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;El patrón “Table Module” está orientado a base de datos y no es adecuado cuando tenemos que trabajar con modelos de datos complejos.&lt;/font&gt;&lt;/p&gt;  &lt;p align="justify"&gt;La mayor ventaja que tenemos en el uso del patrón “Table Module” está precisamente en el soporte que nos ofrece Visual Studio .NET, sin embargo, también es una desventaja puesto que a pesar de que tenemos un asistente y entorno de diseño que nos facilitan la vida, el código generado es una autentica caja negra.&lt;/p&gt;  &lt;p align="justify"&gt;En general se podría decir que aplicar el patrón “Table Module” es preferible a aplicar el patrón “Transaction Script” cuando tenemos que trabajar con Visual Studio .NET.&lt;/p&gt;  &lt;p align="justify"&gt;Veamos un ejemplo de código para una clase “Table Module” :&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&lt;font size="1" face="Verdana"&gt;public class &lt;/font&gt;&lt;/span&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;AddressTableModule
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;private &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DataTable &lt;/span&gt;_dataTable;

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DataTable &lt;/span&gt;Addresses
    {
        &lt;span style="color:blue;"&gt;get &lt;/span&gt;{ &lt;span style="color:blue;"&gt;return &lt;/span&gt;_dataTable; }
    }
    
    &lt;span style="color:blue;"&gt;public &lt;/span&gt;AddressTableModule(&lt;span style="color:#2b91af;"&gt;DataTable &lt;/span&gt;dataTable)
    {
        _dataTable = dataTable;
    }

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DataRow &lt;/span&gt;GetDataRow(&lt;span style="color:blue;"&gt;int &lt;/span&gt;index)
    {
        &lt;span style="color:blue;"&gt;return &lt;/span&gt;_dataTable.Rows[index];
    }

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DataRow &lt;/span&gt;GetRowByID(&lt;span style="color:blue;"&gt;int &lt;/span&gt;addressId)
    {
        &lt;span style="color:blue;"&gt;return &lt;/span&gt;_dataTable.Rows.Find(addressId);
    }

    &lt;span style="color:blue;"&gt;public int &lt;/span&gt;Insert(&lt;span style="color:blue;"&gt;int &lt;/span&gt;id, &lt;span style="color:blue;"&gt;string &lt;/span&gt;name, &lt;span style="color:blue;"&gt;int &lt;/span&gt;affiliateId, &lt;span style="color:blue;"&gt;string &lt;/span&gt;address, 
                      &lt;span style="color:blue;"&gt;string &lt;/span&gt;city, &lt;span style="color:blue;"&gt;string &lt;/span&gt;codeProvince, &lt;span style="color:blue;"&gt;string &lt;/span&gt;zip, &lt;span style="color:blue;"&gt;string &lt;/span&gt;phone, 
                      &lt;span style="color:blue;"&gt;string &lt;/span&gt;contactPerson, &lt;span style="color:#2b91af;"&gt;DateTime &lt;/span&gt;createdDate)
    {
        &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// ...

        &lt;/span&gt;&lt;span style="color:blue;"&gt;return &lt;/span&gt;1;
    }

    &lt;span style="color:blue;"&gt;public int &lt;/span&gt;Update(&lt;span style="color:blue;"&gt;int &lt;/span&gt;addressId, &lt;span style="color:#2b91af;"&gt;DataRow &lt;/span&gt;dataRow)
    {
        &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// ...

        &lt;/span&gt;&lt;span style="color:blue;"&gt;return &lt;/span&gt;1;
    }

    &lt;span style="color:blue;"&gt;public int &lt;/span&gt;Delete(&lt;span style="color:blue;"&gt;int &lt;/span&gt;addressId)
    {
        &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// ..

        &lt;/span&gt;&lt;span style="color:blue;"&gt;return &lt;/span&gt;1;
    }
}&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p align="justify"&gt;Como podemos observar, una clase “Table Module” tiene una variable interna que contiene los datos en formato tabular, dichos datos están en memoria y son filtrados y manipulados por varios métodos.&lt;/p&gt;

&lt;p align="justify"&gt;Además la clase “Table Module” hace referencia internamente a una colección de filas de datos en lugar de una colección de objetos de tipo Address.&lt;/p&gt;

&lt;p align="justify"&gt;El problema del código anterior, es que los datos son débilmente tipados y por tanto no tenemos control sobre el contenido real, sin embargo &lt;font color="#ff8040"&gt;podemos usar objetos TableAdapters en lugar de objetos DataTable para conseguir que nuestras clases “Table Module” sean fuertemente tipadas.&lt;/font&gt;&lt;/p&gt;

&lt;p align="justify"&gt;Los objetos TableAdapter fueron introducidos en la versión 2.0 del Framework para trabajar de forma fuertemente tipada con objetos DataTable.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;AddressTableAdapter &lt;/span&gt;adapter = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;AddressTableAdapter&lt;/span&gt;();

&lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// DataModel is a typed DataSet with a DataTable with the name &amp;#39;Address&amp;#39; ..
&lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DataModel&lt;/span&gt;.&lt;span style="color:#2b91af;"&gt;AddressDataTable &lt;/span&gt;dataTable = dataTable = adapter.GetData();&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p align="justify"&gt;&lt;font color="#ff8040"&gt;Hemos estado viendo como aplicar el patrón “Table Module” sobre estructuras de datos tabulares pero nos falta la funcionalidad necesaria para llenar estas estructuras con datos, para desplegar dicha funcionalidad usamos el patrón “Table Data Gateway”.&lt;/font&gt;&lt;/p&gt;

&lt;p align="justify"&gt;Veamos un ejemplo :&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&lt;font size="1" face="Verdana"&gt;public static class &lt;/font&gt;&lt;/span&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:#2b91af;"&gt;AddressGateway
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;public static &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DataTable &lt;/span&gt;LoadByEmployee(&lt;span style="color:blue;"&gt;int &lt;/span&gt;employeeId)
    {
        &lt;span style="color:#2b91af;"&gt;DataTable &lt;/span&gt;dataTable = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DataTable&lt;/span&gt;();

        &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// ..

        &lt;/span&gt;&lt;span style="color:blue;"&gt;return &lt;/span&gt;dataTable;
    }
}&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;pre class="code"&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// Gets the tabular structure ..
&lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DataTable &lt;/span&gt;dataTable = &lt;span style="color:#2b91af;"&gt;AddressGateway&lt;/span&gt;.LoadByEmployee(1);

&lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// Gets the table module object ..
&lt;/span&gt;&lt;span style="color:#2b91af;"&gt;AddressTableModule &lt;/span&gt;addressTM = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;AddressTableModule&lt;/span&gt;(dataTable);

&lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Verdana"&gt;&lt;span style="color:green;"&gt;// Uses the table module object behaviour ..
&lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DataRow &lt;/span&gt;dataRow = addressTM.GetRowByID(364);&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;pre class="code"&gt;&lt;font size="1" face="Verdana"&gt;&lt;/font&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;Y eso ha sido todo por hoy ..
&lt;div id="postorigin" style="margin-left:5px;font-size:80%;padding:5px;border:2px solid #BDB67C;background-color:#DDDBC7;width:300px;text-align:center;-moz-border-radius:4px 4px 4px 4px;-webkit-border-radius:4px;border-radius:4px;"&gt;&lt;a href="http://kartones.net/blogs/coco/archive/2009/12/01/la-capa-de-negocio-iv-el-patr-243-n-table-module.aspx"&gt;La Capa de Negocio (IV) : El Patr&amp;#243;n Table Module&lt;/a&gt; was posted the 12/01/2009 at &lt;a href="http://Kartones.net"&gt;Kartones.Net&lt;/a&gt;.&lt;/div&gt;
&lt;div id="sharing" class="postfoot"&gt;&lt;hr /&gt;&lt;p&gt;Share via:&lt;br&gt;&lt;a rel="nofollow" href="mailto:?subject=Kartones.Net:%20La+Capa+de+Negocio+(IV)+%3a+El+Patr%26%23243%3bn+Table+Module&amp;amp;body=http://kartones.net/blogs/coco/archive/2009/12/01/la-capa-de-negocio-iv-el-patr-243-n-table-module.aspx" target="_blank"&gt;Email&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.facebook.com/share.php?u=http://kartones.net/blogs/coco/archive/2009/12/01/la-capa-de-negocio-iv-el-patr-243-n-table-module.aspx&amp;amp;t=La+Capa+de+Negocio+(IV)+%3a+El+Patr%26%23243%3bn+Table+Module" target="_blank"&gt;Facebook&lt;/a&gt; | &lt;a rel="nofollow" href="http://twitter.com/home?status=http://kartones.net/blogs/coco/archive/2009/12/01/la-capa-de-negocio-iv-el-patr-243-n-table-module.aspx" target="_blank"&gt;Twitter&lt;/a&gt; | &lt;a rel="nofollow" href="http://slashdot.org/bookmark.pl?url=http://kartones.net/blogs/coco/archive/2009/12/01/la-capa-de-negocio-iv-el-patr-243-n-table-module.aspx&amp;amp;title=La+Capa+de+Negocio+(IV)+%3a+El+Patr%26%23243%3bn+Table+Module" target="_blank"&gt;SlashDot&lt;/a&gt; | &lt;a rel="nofollow" href="http://delicious.com/post?url=http://kartones.net/blogs/coco/archive/2009/12/01/la-capa-de-negocio-iv-el-patr-243-n-table-module.aspx&amp;amp;title=La+Capa+de+Negocio+(IV)+%3a+El+Patr%26%23243%3bn+Table+Module" target="_blank"&gt;del.icio.us&lt;/a&gt; | &lt;a rel="nofollow" href="http://technorati.com/faves?add=http://kartones.net/blogs/coco/archive/2009/12/01/la-capa-de-negocio-iv-el-patr-243-n-table-module.aspx" target="_blank"&gt;Technorati&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http://kartones.net/blogs/coco/archive/2009/12/01/la-capa-de-negocio-iv-el-patr-243-n-table-module.aspx&amp;amp;title=La+Capa+de+Negocio+(IV)+%3a+El+Patr%26%23243%3bn+Table+Module" target="_blank"&gt;Stumbleupon&lt;/a&gt; | &lt;a rel="nofollow" href="http://reddit.com/submit?url=http://kartones.net/blogs/coco/archive/2009/12/01/la-capa-de-negocio-iv-el-patr-243-n-table-module.aspx&amp;amp;title=La+Capa+de+Negocio+(IV)+%3a+El+Patr%26%23243%3bn+Table+Module" target="_blank"&gt;Reddit&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.google.com/reader/link?url=http://kartones.net/blogs/coco/archive/2009/12/01/la-capa-de-negocio-iv-el-patr-243-n-table-module.aspx&amp;amp;title=La+Capa+de+Negocio+(IV)+%3a+El+Patr%26%23243%3bn+Table+Module&amp;amp;srcUrl=http://kartones.net/blogs/coco/archive/2009/12/01/la-capa-de-negocio-iv-el-patr-243-n-table-module.aspx&amp;amp;srcTitle=La+Capa+de+Negocio+(IV)+%3a+El+Patr%26%23243%3bn+Table+Module" target="_blank"&gt;Google Reader&lt;/a&gt; | &lt;a rel="nofollow" href="http://meneame.net/submit.php?url=http://kartones.net/blogs/coco/archive/2009/12/01/la-capa-de-negocio-iv-el-patr-243-n-table-module.aspx" target="_blank"&gt;Meneame&lt;/a&gt; | &lt;a rel="nofollow" href="http://bitacoras.com/anotaciones/http://kartones.net/blogs/coco/archive/2009/12/01/la-capa-de-negocio-iv-el-patr-243-n-table-module.aspx" target="_blank"&gt;Bitacoras&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.linkedin.com/shareArticle?mini=true&amp;amp;url=http://kartones.net/blogs/coco/archive/2009/12/01/la-capa-de-negocio-iv-el-patr-243-n-table-module.aspx&amp;amp;title=La+Capa+de+Negocio+(IV)+%3a+El+Patr%26%23243%3bn+Table+Module&amp;amp;source=Kartones.Net" target="_blank"&gt;LinkedIn&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.google.com/bookmarks/mark?op=edit&amp;amp;bkmk=http://kartones.net/blogs/coco/archive/2009/12/01/la-capa-de-negocio-iv-el-patr-243-n-table-module.aspx&amp;amp;title=La+Capa+de+Negocio+(IV)+%3a+El+Patr%26%23243%3bn+Table+Module" target="_blank"&gt;Google Bookmarks&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.google.com/reader/link?url=http://kartones.net/blogs/coco/archive/2009/12/01/la-capa-de-negocio-iv-el-patr-243-n-table-module.aspx&amp;amp;title=La+Capa+de+Negocio+(IV)+%3a+El+Patr%26%23243%3bn+Table+Module" target="_blank"&gt;Google Reader&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.google.com/buzz/post?url=http://kartones.net/blogs/coco/archive/2009/12/01/la-capa-de-negocio-iv-el-patr-243-n-table-module.aspx&amp;amp;imageurl=" target="_blank"&gt;Google Buzz&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.friendfeed.com/share?title=La+Capa+de+Negocio+(IV)+%3a+El+Patr%26%23243%3bn+Table+Module&amp;amp;link=http://kartones.net/blogs/coco/archive/2009/12/01/la-capa-de-negocio-iv-el-patr-243-n-table-module.aspx" target="_blank"&gt;FriendFeed&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.netvibes.com/share?title=La+Capa+de+Negocio+(IV)+%3a+El+Patr%26%23243%3bn+Table+Module&amp;amp;url=http://kartones.net/blogs/coco/archive/2009/12/01/la-capa-de-negocio-iv-el-patr-243-n-table-module.aspx" target="_blank"&gt;Netvibes&lt;/a&gt; | &lt;a rel="nofollow" href="https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;mkt=es-es&amp;amp;url=http://kartones.net/blogs/coco/archive/2009/12/01/la-capa-de-negocio-iv-el-patr-243-n-table-module.aspx&amp;amp;title=La+Capa+de+Negocio+(IV)+%3a+El+Patr%26%23243%3bn+Table+Module" target="_blank"&gt;Windows Live&lt;/a&gt; | &lt;a rel="nofollow" href="http://www.myspace.com/Modules/PostTo/Pages/?u=http://kartones.net/blogs/coco/archive/2009/12/01/la-capa-de-negocio-iv-el-patr-243-n-table-module.aspx&amp;amp;t=La+Capa+de+Negocio+(IV)+%3a+El+Patr%26%23243%3bn+Table+Module" target="_blank"&gt;MySpace&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;img src="http://kartones.net/aggbug.aspx?PostID=50575" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/ElFrameworkDeCoco/~4/rSZkJ6SolIs" height="1" width="1"/&gt;</description><category domain="http://kartones.net/blogs/coco/archive/tags/Capa+de+negocio/default.aspx">Capa de negocio</category><category domain="http://kartones.net/blogs/coco/archive/tags/Table+Data+Gateway/default.aspx">Table Data Gateway</category><category domain="http://kartones.net/blogs/coco/archive/tags/Table+Module/default.aspx">Table Module</category><feedburner:origLink>http://kartones.net/blogs/coco/archive/2009/12/01/la-capa-de-negocio-iv-el-patr-243-n-table-module.aspx</feedburner:origLink></item></channel></rss>
