<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://geeks.ms/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">Jorge Serrano - MVP Visual Developer - Visual Basic</title><subtitle type="html">Blog sobre tecnología .NET en general y sobre Visual Basic en particular.</subtitle><id>http://geeks.ms/blogs/jorge/atom.aspx</id><link rel="alternate" type="text/html" href="http://geeks.ms/blogs/jorge/default.aspx" /><link rel="self" type="application/atom+xml" href="http://geeks.ms/blogs/jorge/atom.aspx" /><generator uri="http://communityserver.org" version="4.1.31106.3070">Community Server</generator><updated>2012-11-25T21:30:00Z</updated><entry><title>Obteniendo la Url de Office 365 para programar contra EWS</title><link rel="alternate" type="text/html" href="/blogs/jorge/archive/2013/04/29/obteniendo-la-url-de-office-365-para-programar-contra-ews.aspx" /><id>/blogs/jorge/archive/2013/04/29/obteniendo-la-url-de-office-365-para-programar-contra-ews.aspx</id><published>2013-04-29T12:00:00Z</published><updated>2013-04-29T12:00:00Z</updated><content type="html">&lt;p&gt;&lt;img src="http://www.ymant.com/sites/default/files/office_365.jpg" width="220" height="134" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;En esta entrada nada estelar, querría comentar un pequeño truquillo para quien se adentre en el fabuloso mundo de la programación contra Office 365.&lt;/p&gt;  &lt;p&gt;En concreto, con respecto a la Url de Office 365.&lt;/p&gt;  &lt;p&gt;Las cuentas de correo para Office 365 normalmente poseen un largo nombre del tipo xxxoffice365.onmicrosoft.com&lt;/p&gt;  &lt;p&gt;De esta manera, accederemos al portal de Office 365 para nuestro usuario a un sitio del tipo portal.microsoftonline.com.&lt;/p&gt;  &lt;p&gt;Sin embargo, cuando queremos crear una aplicación en Visual Studio para atacar o trabajar contra Office 365, nos surgirá una pregunta.&lt;/p&gt;  &lt;p&gt;¿Qué Url es la que posee el servidor de nuestra empresa contra la que queremos trabajar?.&lt;/p&gt;  &lt;p&gt;Una forma sencilla es acceder al portal de Office 365, y una vez en el portal, acceder a la url: &lt;a href="http://mail.office365.com/"&gt;http://mail.office365.com/&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Automáticamente nos llevará a una url del tipo: &lt;a title="https://am2prd0210.outlook.com/owa/" href="https://xxx.outlook.com/owa/"&gt;https://xxx.outlook.com/owa/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Así que si queremos acceder contra EWS (Exchange Web Services), lo único que tendremos que hacer, será cambiar esa url anterior por la que normalmente tendrá la descripción de los servicios, como por ejemplo:&lt;/p&gt;  &lt;p&gt;&lt;a title="https://xxx.outlook.com/ews/Services.wsdl" href="https://xxx.outlook.com/ews/Services.wsdl"&gt;https://xxx.outlook.com/ews/Services.wsdl&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;De esta manera, podremos acceder sin problemas a nuestro servicio de Exchange y a todos sus métodos y funciones.&lt;/p&gt;  &lt;p&gt;Espero que le sirva a más de uno.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=209314" width="1" height="1"&gt;</content><author><name>jorge</name><uri>http://geeks.ms/members/jorge/default.aspx</uri></author><category term="C#" scheme="http://geeks.ms/blogs/jorge/archive/tags/C_2300_/default.aspx" /><category term="Visual Studio 2012" scheme="http://geeks.ms/blogs/jorge/archive/tags/Visual+Studio+2012/default.aspx" /><category term="Office 365" scheme="http://geeks.ms/blogs/jorge/archive/tags/Office+365/default.aspx" /></entry><entry><title>Error TF31003 en Visual Studio 2012 con Windows 8 y Team Foundation Service</title><link rel="alternate" type="text/html" href="/blogs/jorge/archive/2013/04/22/error-tf31003-en-visual-studio-2012-con-windows-8-y-team-foundation-service.aspx" /><id>/blogs/jorge/archive/2013/04/22/error-tf31003-en-visual-studio-2012-con-windows-8-y-team-foundation-service.aspx</id><published>2013-04-22T06:00:00Z</published><updated>2013-04-22T06:00:00Z</updated><content type="html">&lt;p&gt;&lt;strong&gt;Introducción&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Si estás utilizando &lt;em&gt;Visual Studio 2012&lt;/em&gt; en &lt;em&gt;Windows 8&lt;/em&gt; y estás intentando conectar con &lt;em&gt;&lt;a href="https://tfs.visualstudio.com/"&gt;Team Foundation Service&lt;/a&gt;&lt;/em&gt; (lo que antiguamente se llamaba TFS Preview), quizás hayas tenido la fabulosa experiencia de toparte con un error de tipo TF31003.&lt;/p&gt;  &lt;p&gt;Si es así, esta entrada creo que podría ayudarte.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Al lío…&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Supongamos que tenemos ya nuestro servicio de TFS creado y una dirección de tipo &lt;a href="https://{nombre}.visualstudio.com"&gt;https://{nombre}.visualstudio.com&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Iniciamos Visual Studio 2012 y nos encontramos con la siguiente pantalla:&lt;/p&gt;  &lt;p&gt;&lt;img src="https://a3klma.sn2.livefilestore.com/y1pEJWgItNefU7gn_V3ACxthw0he5vOduzaeqUzNqGlTzPGNXKi9qwYOaHeef0KNRdz6lKdbdDjGzFRG2RtPHH8b5ItdkMzLLaT/20130422_01.png?psid=1" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;Nuestra primera idea es la de conectarnos a Team Foundation Server, así que pulsamos sobre este enlace y obtenemos una nueva ventana donde deberemos establecer la conexión.&lt;/p&gt;  &lt;p&gt;&lt;img src="https://a3klma.sn2.livefilestore.com/y1pEJWgItNefU4NKoie0snpEA1DN8xEEkDKF6-6oLJtFqahPCQ2eg2YuOwX3bXAiKv0XrDwRZ6ZaMtlKqgmfaHTlr6jW85V4GyZ/20130422_02.png?psid=1" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;En mi caso no tengo ninguna conexión, así que deberé hacer clic sobre el botón &lt;strong&gt;Servers&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;De esta manera aparecerá la siguiente ventana:&lt;/p&gt;  &lt;p&gt;&lt;img src="https://a3klma.sn2.livefilestore.com/y1pEJWgItNefU6UiAuA4J4tqZuElCjXedbtcIB9gIOqtE3Enh_HDbTcTBfYbNr7qdkcqTr01lXu0ZQDd-WRGQxHAM7cZ5Mi8SYJ/20130422_03.png?psid=1" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;En mi caso no tengo ninguna conexión, así que deberé hacer clic sobre el botón &lt;strong&gt;Add&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;En el caso de que tengáis ya conexiones creadas pero no con el server de TFS que queremos conectar, deberemos igualmente hacer clic sobre el botón &lt;strong&gt;Add&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;Aquí aparecerá una nueva ventana en la que añadiremos la conexión a nuestro Team Foundation Server introduciendo la url de nuestro servicio: &lt;a href="https://{nombre}.visualstudio.com"&gt;https://{nombre}.visualstudio.com&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="https://a3klma.sn2.livefilestore.com/y1p100WiL3mRIYrOPZ8CKQOeDAhd0Tb2ihnyUQMyXdIoF463kH-NWq0_aLz36JxQ9Vp6YtIyyVlmVkcBhR30UIxZAeP5heZPoR8/20130422_04.png?psid=1" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;Una vez que tenemos todo listo, haremos clic al botón &lt;strong&gt;OK&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;El proceso de autenticación se iniciará y obtendremos una ventana en blanco como la siguiente:&lt;/p&gt;  &lt;p&gt;&lt;img src="https://a3klma.sn2.livefilestore.com/y1p100WiL3mRIZHa1vqKpWlrZT6NiBdTPAl0VVjE_9H2ZWdle9iMeXcaEzOR97VDXp84dG99PrIosmmraKzVsMYTT82YsBzchqv/20130422_05.png?psid=1" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;Después de unos segundos, aparecerá un mensaje en pantalla indicándonos que se ha producir un error de tipo TF31003.&lt;/p&gt;  &lt;p&gt;&lt;img src="https://a3klma.sn2.livefilestore.com/y1p100WiL3mRIaiILVQivxSiMKARbRft-GXO2GfZDetv4Ix9NhovqKklLRUo9FF8T0b1NNL4Fhl1PAsTdqwP4s3gX_2sGJFiIY1/20130422_06.png?psid=1" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;Da igual que reiniciemos el ordenador, ya que el error persistirá.&lt;/p&gt;  &lt;p&gt;En este punto, ¿cómo resolver el problema?.&lt;/p&gt;  &lt;p&gt;Independientemente de que existan otras formas menos dañinas, la forma más sencilla es &lt;a href="http://kb.wisc.edu/page.php?id=15141"&gt;limpiar las Cookies del navegador Internet Explorer&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Basta hacer esto y repetir los pasos anteriores para comprobar que a la hora de pedir las credenciales de autenticación, la ventana sí se muestra correctamente.&lt;/p&gt;  &lt;p&gt;&lt;img src="https://a3klma.sn2.livefilestore.com/y1p-AWbZ4QGNDT8S2s9i835h6m5SPRGpO7Ie6vrVmMvLbzoHDbBVEohw85yO6YzCLq9lngdC1hdP-NIHaXRayTuuS6hI4r-uzsY/20130422_07.png?psid=1" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;Así que se puede decir que con esto, resolveremos el problema.&lt;/p&gt;  &lt;p&gt;Espero que a alguno más le ayude.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=209130" width="1" height="1"&gt;</content><author><name>jorge</name><uri>http://geeks.ms/members/jorge/default.aspx</uri></author><category term=".NET Framework 4.0" scheme="http://geeks.ms/blogs/jorge/archive/tags/.NET+Framework+4.0/default.aspx" /><category term="Microsoft .NET Framework 4.0" scheme="http://geeks.ms/blogs/jorge/archive/tags/Microsoft+.NET+Framework+4.0/default.aspx" /><category term="Windows 8" scheme="http://geeks.ms/blogs/jorge/archive/tags/Windows+8/default.aspx" /><category term="Microsoft .NET Framework 4.5" scheme="http://geeks.ms/blogs/jorge/archive/tags/Microsoft+.NET+Framework+4.5/default.aspx" /><category term=".NET Framework 4.5" scheme="http://geeks.ms/blogs/jorge/archive/tags/.NET+Framework+4.5/default.aspx" /><category term="Visual Studio 2012" scheme="http://geeks.ms/blogs/jorge/archive/tags/Visual+Studio+2012/default.aspx" /></entry><entry><title>Reutilización de código, mantenimiento de aplicaciones (VI)</title><link rel="alternate" type="text/html" href="/blogs/jorge/archive/2013/04/19/reutilizaci-243-n-de-c-243-digo-mantenimiento-de-aplicaciones-vi.aspx" /><id>/blogs/jorge/archive/2013/04/19/reutilizaci-243-n-de-c-243-digo-mantenimiento-de-aplicaciones-vi.aspx</id><published>2013-04-19T06:00:00Z</published><updated>2013-04-19T06:00:00Z</updated><content type="html">&lt;p&gt;&lt;strong&gt;&lt;img alt="" src="http://www.kidney-support.org/uploads/allimg/121222/5-1212221AZN50.jpg" width="276" height="224" /&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Introducción&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Hasta ahora, hemos visto como pasar de una aplicación de Software que cumple los requisitos a una aplicación de Software que cumple los requisitos, que es reutilizable y que mejora el mantenimiento de aplicaciones, llevándolo todo a un mundo ideal.&lt;/p&gt;  &lt;p&gt;¿Pero es ese mundo ideal de desarrollo el mundo ideal de la oportunidad de negocio o de mercado?.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Cuando las prioridades se imponen al mundo ideal&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;&lt;font color="#c0504d"&gt;Hablo de desarrollo del Software…&lt;/font&gt;&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;El problema hoy día de muchas empresas, por no decir todas, es la prioridad.&lt;/p&gt;  &lt;p&gt;El riesgo o amenaza de una empresa es la competitividad de la competencia.&lt;/p&gt;  &lt;p&gt;Y las incógnitas de la ecuación de toda empresa es el tiempo, los gastos y los ingresos.&lt;/p&gt;  &lt;p&gt;Si mezclamos todos estos ingredientes en un mismo tarro, podemos obtener un &lt;em&gt;cocktail&lt;/em&gt; de lo más explosivo.&lt;/p&gt;  &lt;p&gt;En el mundo ideal, los desarrolladores queremos hacer un código bonito y que cumpla todas las posibles premisas de lo que es un desarrollo correcto, sin embargo, no siempre esto es posible.&lt;/p&gt;  &lt;p&gt;La presión por terminar los proyectos en un corto plazo de tiempo, pensar en ingresar todo lo que se pueda y ofrecer unos gastos reducidos, hacen que el proyecto sea atractivo, la empresa ingrese un variable muy goloso y se vuelva a desarrollar otro producto. Así funcionan la mayoría de empresas de servicios hoy día. Es lo que mucha gente denomina como un modelo de negocio práctico.&lt;/p&gt;  &lt;p&gt;Sin embargo, hay clientes (existen y los hay), que prefieren no ser tan “prácticos” y dedicar parte de los esfuerzos y dinero a lograr un sistema que recoja todas estas bondades. Y con ello, no se está queriendo decir que el proyecto haya sido más largo o más costoso entendiendo como coste los gastos o la diferencia entre ingresos menos gastos.&lt;/p&gt;  &lt;p&gt;Muchas veces, pensamos que hacer proyectos que dispongan de todas estas posibilidades no es ventajoso, pero pensemos en que podemos estar delante de un proyecto cuyos requisitos cambian o se saben de antemano, que variarán en el tiempo y mucho,… quizás convenga hacer las cosas de la mejor forma posible.&lt;/p&gt;  &lt;p&gt;No quiero indicar con todo esto que es mejor una forma de hacer los proyectos (por ejemplo en la parte I de este conjunto de entradas), o de la última forma aplicando estrictamente SOLID.&lt;/p&gt;  &lt;p&gt;Me gustaría que este conjunto de entradas sirvieran de reflexión para indicar que ni existe el mundo ideal ni el mundo “no ideal” es malo.&lt;/p&gt;  &lt;p&gt;Cada proyecto de Software es único, no me cansaré de repetirlo, y como tal, requiere un planteamiento concreto a la hora de abordarlo.&lt;/p&gt;  &lt;p&gt;Muchas &lt;em&gt;startups&lt;/em&gt; utilizan planteamientos ágiles para sacar adelante su producto, porque no buscan el &lt;em&gt;cojo-producto&lt;/em&gt;, sino dar funcionalidad a una idea para ir comprobando como funciona y en su caso refinarla adecuadamente. Dentro de ese refinamiento, podrían encontrarse con la necesidad de rehacer su producto por completo, y eso siempre y cuando empiecen a tener éxito y mucho antes de que se convierta en &lt;em&gt;cojo-producto&lt;/em&gt; como es obvio.&lt;/p&gt;  &lt;p&gt;A veces debemos sacrificar mantenimiento y reutilización para llegar al mercado primeros y golpear antes.&lt;/p&gt;  &lt;p&gt;Todo, absolutamente todo, es cuestión de prioridades, y nada nos hace más libres que tomar las decisiones que consideremos oportuno en cada momento, pudiendo saltar de una forma de abordar el producto a otra si con ello, tenemos después que rehacer el producto.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=209128" width="1" height="1"&gt;</content><author><name>jorge</name><uri>http://geeks.ms/members/jorge/default.aspx</uri></author><category term="Arquitectura" scheme="http://geeks.ms/blogs/jorge/archive/tags/Arquitectura/default.aspx" /><category term="C#" scheme="http://geeks.ms/blogs/jorge/archive/tags/C_2300_/default.aspx" /><category term=".NET Framework 4.0" scheme="http://geeks.ms/blogs/jorge/archive/tags/.NET+Framework+4.0/default.aspx" /><category term="Visual Studio 2010" scheme="http://geeks.ms/blogs/jorge/archive/tags/Visual+Studio+2010/default.aspx" /><category term="Microsoft .NET Framework 4.0" scheme="http://geeks.ms/blogs/jorge/archive/tags/Microsoft+.NET+Framework+4.0/default.aspx" /><category term="Microsoft .NET Framework 4.5" scheme="http://geeks.ms/blogs/jorge/archive/tags/Microsoft+.NET+Framework+4.5/default.aspx" /><category term=".NET Framework 4.5" scheme="http://geeks.ms/blogs/jorge/archive/tags/.NET+Framework+4.5/default.aspx" /><category term="Visual Studio 2012" scheme="http://geeks.ms/blogs/jorge/archive/tags/Visual+Studio+2012/default.aspx" /></entry><entry><title>Reutilización de código, mantenimiento de aplicaciones (V)</title><link rel="alternate" type="text/html" href="/blogs/jorge/archive/2013/04/17/reutilizaci-243-n-de-c-243-digo-mantenimiento-de-aplicaciones-v.aspx" /><id>/blogs/jorge/archive/2013/04/17/reutilizaci-243-n-de-c-243-digo-mantenimiento-de-aplicaciones-v.aspx</id><published>2013-04-17T06:00:00Z</published><updated>2013-04-17T06:00:00Z</updated><content type="html">&lt;p&gt;&lt;strong&gt;&lt;img src="http://www.kidney-support.org/uploads/allimg/121222/5-1212221AZN50.jpg" width="276" height="224" alt="" /&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Introducción&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;En las entradas anteriores, vimos como desarrollar una aplicación a partir de un problema teóricamente trivial.&lt;/p&gt;  &lt;p&gt;Los requisitos cambian y las necesidades empresariales nos llevan a ser ágiles y adoptar cambios de manera rápida y flexible, facilitar las pruebas unitarias y en definitiva, codificar código lo más limpio posible y con posibilidades de reutilizarlo.&lt;/p&gt;  &lt;p&gt;Hemos llegado a un punto bastante aceptable pero no es suficiente. Al menos no para unos programadores exigentes como nosotros.&lt;/p&gt;  &lt;p&gt;Y de esta manera, hemos llegado a mencionar un conjunto de principios básicos de programación orientada a objetos… bueno, en realidad cinco principios, que reciben el nombre de SOLID.&lt;/p&gt;  &lt;p&gt;Así que en este punto, lo mejor es hacer una pequeña pausa y hablar de esos cinco principios que deberíamos tratar de cumplir siempre que sea posible con el fin de no perdernos más adelante.&lt;/p&gt;  &lt;p&gt;¿Es obligatorio cumplirlos?. No, pero sí es recomendable cumplirlos todos. Sino podemos cumplir todos, cuantos más cumplamos, mejor.&lt;/p&gt;  &lt;p&gt;Empecemos entonces…&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;SOLID&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;SOLID es un acrónimo de 5 principios básicos de programación orientada a objetos que surgieron alrededor del año 2000.&lt;/p&gt;  &lt;p&gt;También lo escucharás citar como los principios SOLID.&lt;/p&gt;  &lt;p&gt;Cada letra de la palabra SOLID corresponde a un principio:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;S&lt;/strong&gt;RP o Single Responsability Principle.&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;O&lt;/strong&gt;CP u Open/Close Principle.&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;L&lt;/strong&gt;SP o Liskov Substitution Principle.&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;I&lt;/strong&gt;SP o Interface Segregation Principle.&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;D&lt;/strong&gt;IP o Dependency Inversion Principle.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Lo mejor para entender cada uno de estos principios, es verlos de forma breve y concisa.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;SRP o Single Responsability Principle&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Es quizás el más fácil de entender.&lt;/p&gt;  &lt;p&gt;El concepto detrás de este principio es el de tener en mente que cada clase tenga una única responsabilidad.&lt;/p&gt;  &lt;p&gt;Esa responsabilidad debería estar contenida dentro de la clase.&lt;/p&gt;  &lt;p&gt;Si tenemos la necesidad de encapsular una responsabilidad en varias clases, quizás nuestra clase estuviera haciendo más cosas de las que debiera y por lo tanto, deberíamos pensar en refactorizar nuestro código para mejorarlo y llegar a cumplir este principio.&lt;/p&gt;  &lt;p&gt;Para este principio, sólo se exige atención a los requisitos, refinamiento si procede y sentido común a la hora de hacer las cosas.&lt;/p&gt;  &lt;p&gt;Un ejemplo sencillo podría ser el siguiente:&lt;/p&gt;  &lt;p&gt;Partimos de una clase &lt;em&gt;Coche&lt;/em&gt; con diferentes comandos y funcionalidades. Básicamente y para no complicarlo, tenemos la posibilidad de arrancar el motor y apagarlo, y de acelerar y frenar.&lt;/p&gt;  &lt;p&gt;&lt;img src="https://aas0dg.sn2.livefilestore.com/y1pC_R6zLwuN75sF9LhyApsICQ3K7Q1WsabEoGEFY2YfHBVlz1kgN480aF5OitGmhQZtHrNlhfFvuPfZIZmjuWGDuX_Bk7vkSJC/20130417_01.png?psid=1" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;Dos variables nos indican si el coche está arrancado así como su velocidad.&lt;/p&gt;  &lt;p&gt;Desde el punto de responsabilidad única y a simple vista, la clase &lt;em&gt;Coche&lt;/em&gt; hace bastantes cosas.&lt;/p&gt;  &lt;p&gt;Podríamos mejorar por lo tanto todo esto para lograr algo parecido a (en aproximación):&lt;/p&gt;  &lt;p&gt;&lt;img src="https://aas0dg.sn2.livefilestore.com/y1pSJ6tepkIO8DBApG5DjSDeg70HEIq44YbnGbQ3l5icb1wGQjSdMKw30oHZOxvZyzF2Mw9rybmGnHgf4An0GHkgSaeYiSK_Ls2/20130417_02.png?psid=1" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;No pongo el código porque creo que se entiende bien, y lo principal realmente aquí es el concepto de este principio.&lt;/p&gt;  &lt;p&gt;Como se puede apreciar, además de separar responsabilidades, podemos hacer pruebas unitarias de cada una de estas partes por separado y de todas ellas conjuntamente.&lt;/p&gt;  &lt;p&gt;No es quizás el mejor ejemplo, pero si sirve para aclarar el concepto, con eso me conformo.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;OCP u Open/Close Principle&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;El concepto detrás de este principio dice que deberíamos codificar nuestras clases, funciones, métodos, etc., de forma abierta a su extensión y cerrada en su modificación.&lt;/p&gt;  &lt;p&gt;Dicho así puede que suene etéreo, así que digámoslo de otra manera.&lt;/p&gt;  &lt;p&gt;Nuestras clases, funciones, métodos, etc., deberían permitir que su comportamiento variara o cambiara sin que tengamos que modificar nuestro código fuente.&lt;/p&gt;  &lt;p&gt;Un ejemplo sencillo podría ser el siguiente:&lt;/p&gt;  &lt;p&gt;&lt;img src="https://aas0dg.sn2.livefilestore.com/y1pseWP1GXKNz8DkQRkhtmm5qWQrpO8UKILCGF40ELPSAkbF3OwdH5ErVWxeoNjC6C98bgrkVg_TlVIoh_N8o4klB3xskdf_f_m/20130417_03.png?psid=1" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;El código de este ejemplo demostrativo sería similar al siguiente:&lt;/p&gt;  &lt;div class="csharpcode"&gt;   &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Rectangulo&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; Alto { get; set; }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; Ancho { get; set; }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;    } &lt;span class="rem"&gt;// Rectangulo&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Circulo&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; Radio { get; set; }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;    } &lt;span class="rem"&gt;// Circulo&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; CalculoArea&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;        &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; GetArea(Circulo circulo)&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; Math.PI * Math.Pow(circulo.Radio, 2);&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;        } &lt;span class="rem"&gt;// GetArea&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;        &lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  23:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; GetArea(Rectangulo rectangulo)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  24:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  25:  &lt;/span&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; rectangulo.Alto * rectangulo.Ancho;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  26:  &lt;/span&gt;        } &lt;span class="rem"&gt;// GetArea&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  27:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  28:  &lt;/span&gt;    } // CalculoArea&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Y si queremos consumir estas clases en nuestra aplicación, emplearíamos un código similar al siguiente:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;CalculoArea calculoArea = &lt;span class="kwrd"&gt;new&lt;/span&gt; CalculoArea();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;Circulo circulo = &lt;span class="kwrd"&gt;new&lt;/span&gt; Circulo();&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;circulo.Radio = 13;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;Rectangulo rectangulo = &lt;span class="kwrd"&gt;new&lt;/span&gt; Rectangulo();&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;rectangulo.Alto = 3;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;rectangulo.Ancho = 7;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;MessageBox.Show(calculoArea.GetArea(circulo).ToString());&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;MessageBox.Show(calculoArea.GetArea(rectangulo).ToString());&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Como podemos apreciar aquí, el ejemplo que hemos desarrollado parece estar bien. De hecho, funciona y hace lo que esperamos que haga. Así que desde el punto de vista de requisitos lo podríamos dar por bueno.&lt;/p&gt;

&lt;p&gt;Sin embargo, si prestamos atención a lo que hemos hecho, veremos que hay algo que nos chirría… o debería chirriarnos… ¿os acordáis del primer principio SOLID?. ¿Ese que trata sobre la responsabilidad simple?. Cuando un principio no se cumple, decimos que violamos ese principio, algo que estamos haciendo aquí.&lt;/p&gt;

&lt;p&gt;Tenemos un objeto de cálculo del área que calcula todas las áreas habidas Y POR HABER, es decir, si decidimos agregar una nueva figura geométrica para calcular su área, nos veremos obligado a modificar la clase &lt;em&gt;CalculoArea&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;El caso es que podríamos mejorar lo presente (&lt;em&gt;quizás&lt;/em&gt;) dando una vuelta de tuerca.&lt;/p&gt;

&lt;p&gt;Imaginemos entonces el siguiente diagrama de objetos refactorizando lo anterior:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://aas0dg.sn2.livefilestore.com/y1pOZc6Ch_WU3g2qc4soaAaUMFAnoVVqb3iOhiGl_MH8JwXu4CTwNfSwk9SP4ia2_kkJRHzuPU72B2Q1YHHu3G0vb0uG4bdYfWH/20130417_04.png?psid=1" alt="" /&gt;&lt;/p&gt;

&lt;p&gt;Aunque a priori hemos mejorado el mantenimiento de nuestra aplicación, sabemos ya a estas alturas que no estamos delante de un marco ideal de cómo hacer las cosas. Así que si incrementamos las figuras geométricas, estaremos nuevamente delante de la necesidad de agregar otra variable dentro de la clase &lt;em&gt;CalculoArea&lt;/em&gt; para la nueva figura geométrica además de tener que agregar en la función &lt;em&gt;GetArea&lt;/em&gt; su correspondiente cálculo.&lt;/p&gt;

&lt;p&gt;En resumidas cuentas, que estaremos más o menos igual que antes.&lt;/p&gt;

&lt;p&gt;Parece evidente analizando nuestro código, que todas las figuras geométricas tienen en común algo. La necesidad o el requisito de calcular su área, nada mejor como su propia figura geométrica para saber y conocer perfectamente cuál es el cálculo de su área.&lt;/p&gt;

&lt;p&gt;Pero aún mucho mejor si abstraemos esa funcionalidad de manera tal que si agregamos una nueva figura, cumpla con ese requisito.&lt;/p&gt;

&lt;p&gt;El siguiente diagrama recoge esta filosofía:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://aas0dg.sn2.livefilestore.com/y1paos5K5ZwRVE3gQp2BbQ8MRnzGoC4UIeg-h5YeKaKV3lq3y3LgXHbjn-HFWLP5EfKrjfM3Ipa6TTK-YwIjZpSuz60wkWlDEVe/20130417_05.png?psid=1" alt="" /&gt;&lt;/p&gt;

&lt;p&gt;Y el código de esta implementación quedaría de la siguiente manera:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;interface&lt;/span&gt; IFiguraGeometrica&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;        &lt;span class="kwrd"&gt;double&lt;/span&gt; GetArea();&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;    } &lt;span class="rem"&gt;// IFiguraGeometrica&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Cuadrado : IFiguraGeometrica&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; Cuadrado(&lt;span class="kwrd"&gt;double&lt;/span&gt; lado)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;            &lt;span class="kwrd"&gt;this&lt;/span&gt;.Lado = lado;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;        } &lt;span class="rem"&gt;// Circulo Constructor&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; Lado { get; set; }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; GetArea()&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; Math.Pow(&lt;span class="kwrd"&gt;this&lt;/span&gt;.Lado, 2);&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  23:  &lt;/span&gt;        } &lt;span class="rem"&gt;// GetArea&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  24:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  25:  &lt;/span&gt;    } &lt;span class="rem"&gt;// Cuadrado&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  26:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  27:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Circulo : IFiguraGeometrica&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  28:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  29:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  30:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; Circulo(&lt;span class="kwrd"&gt;double&lt;/span&gt; radio)&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  31:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  32:  &lt;/span&gt;            &lt;span class="kwrd"&gt;this&lt;/span&gt;.Radio = radio;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  33:  &lt;/span&gt;        } &lt;span class="rem"&gt;// Circulo Constructor&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  34:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  35:  &lt;/span&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; Radio { get; set; }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  36:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  37:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; GetArea()&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  38:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  39:  &lt;/span&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; Math.PI * Math.Pow(&lt;span class="kwrd"&gt;this&lt;/span&gt;.Radio, 2);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  40:  &lt;/span&gt;        } &lt;span class="rem"&gt;// GetArea&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  41:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  42:  &lt;/span&gt;    } &lt;span class="rem"&gt;// Circulo&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  43:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  44:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Rectangulo : IFiguraGeometrica&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  45:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  46:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  47:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; Rectangulo(&lt;span class="kwrd"&gt;double&lt;/span&gt; ancho, &lt;span class="kwrd"&gt;double&lt;/span&gt; alto)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  48:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  49:  &lt;/span&gt;            &lt;span class="kwrd"&gt;this&lt;/span&gt;.Ancho = ancho;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  50:  &lt;/span&gt;            &lt;span class="kwrd"&gt;this&lt;/span&gt;.Alto = alto;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  51:  &lt;/span&gt;        } &lt;span class="rem"&gt;// Rectangulo Constructor&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  52:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  53:  &lt;/span&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; Ancho { get; set; }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  54:  &lt;/span&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; Alto { get; set; }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  55:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  56:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; GetArea()&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  57:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  58:  &lt;/span&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;this&lt;/span&gt;.Alto * &lt;span class="kwrd"&gt;this&lt;/span&gt;.Ancho;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  59:  &lt;/span&gt;        } &lt;span class="rem"&gt;// GetArea&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  60:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  61:  &lt;/span&gt;    } // Rectangulo&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Y una aproximación de utilizar esto quedaría de la siguiente manera aproximada:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;IFiguraGeometrica figuraGeometrica = &lt;span class="kwrd"&gt;new&lt;/span&gt; Circulo(13);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;MessageBox.Show(figuraGeometrica.GetArea().ToString());&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;figuraGeometrica = &lt;span class="kwrd"&gt;new&lt;/span&gt; Rectangulo(7, 3);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;MessageBox.Show(figuraGeometrica.GetArea().ToString());&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Evidentemente, todo esto como podemos ver resulta mucho más simple.&lt;/p&gt;

&lt;p&gt;Si modificamos una implementación de &lt;em&gt;Cuadrado&lt;/em&gt;, &lt;em&gt;Circulo&lt;/em&gt; o &lt;em&gt;Rectangulo&lt;/em&gt;, no estaremos “rompiendo” nada de lo que ya existe.&lt;/p&gt;

&lt;p&gt;Mejoraremos el mantenimiento, e incorporaremos pautas para reutilizar el código.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LSP o Liskov Substitution Principle&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Este principio viene a decir que los objetos de una aplicación deberían ser reemplazables con instancias de sus subtipos sin que por ello tengamos que alterar el funcionamiento y la lógica de la aplicación.&lt;/p&gt;

&lt;p&gt;Dicho de otro modo, que las funciones que utilizan referencias o punteros a clases base, deberían ser capaces de utilizar los objetos de las clases derivadas sin conocerlas.&lt;/p&gt;

&lt;p&gt;Veámoslo con un ejemplo de aproximación partiendo del siguiente diagrama:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://aas0dg.sn2.livefilestore.com/y1pK6EWWfnBnDthrR94ifGVAK_M78WzQ2eafu6WP2vYgkb-j_aTdoZ6Z-Cj5oEJh1iJiWwTRiX5AFpZ8TN-QEXlyXJjPlXtbrL9/20130417_06.png?psid=1" alt="" /&gt;&lt;/p&gt;

&lt;p&gt;Y el código fuente de lo que estamos viendo quedaría de la siguiente manera:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Cuadrado : Rectangulo&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; Ancho&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;            get&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;            {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;                &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;base&lt;/span&gt;.Ancho;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;            }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;            set&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;            {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;                &lt;span class="kwrd"&gt;base&lt;/span&gt;.Ancho = &lt;span class="kwrd"&gt;value&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;                &lt;span class="kwrd"&gt;base&lt;/span&gt;.Alto = &lt;span class="kwrd"&gt;value&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;            }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;        } &lt;span class="rem"&gt;// Ancho&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; Alto&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;            get&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;            {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;                &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;base&lt;/span&gt;.Alto;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;            }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  23:  &lt;/span&gt;            set&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  24:  &lt;/span&gt;            {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  25:  &lt;/span&gt;                &lt;span class="kwrd"&gt;base&lt;/span&gt;.Ancho = &lt;span class="kwrd"&gt;value&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  26:  &lt;/span&gt;                &lt;span class="kwrd"&gt;base&lt;/span&gt;.Alto = &lt;span class="kwrd"&gt;value&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  27:  &lt;/span&gt;            }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  28:  &lt;/span&gt;        } &lt;span class="rem"&gt;// Alto&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  29:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  30:  &lt;/span&gt;    } &lt;span class="rem"&gt;// Cuadrado&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  31:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  32:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Rectangulo&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  33:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  34:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; Ancho { get; set; }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  35:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; Alto { get; set; }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  36:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  37:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; GetArea()&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  38:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  39:  &lt;/span&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;this&lt;/span&gt;.Ancho * &lt;span class="kwrd"&gt;this&lt;/span&gt;.Alto;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  40:  &lt;/span&gt;        } &lt;span class="rem"&gt;// GetArea&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  41:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  42:  &lt;/span&gt;    } // Rectangulo&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;El consumo de este ejemplo quedaría de la siguiente forma:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;Rectangulo rectangulo = &lt;span class="kwrd"&gt;new&lt;/span&gt; Cuadrado();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;rectangulo.Alto = 3;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;rectangulo.Ancho = 7;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;MessageBox.Show(rectangulo.GetArea().ToString());&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;El resultado esperado de este cálculo sería 21, sin embargo, obtendremos 49 que sería el producto de 7 x 7, algo que en el caso del cálculo del rectángulo no es lo que esperábamos.&lt;/p&gt;

&lt;p&gt;¿Cómo resolver el problema?.&lt;/p&gt;

&lt;p&gt;Una posibilidad sería la siguiente:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://aas0dg.sn2.livefilestore.com/y1pkHlZ0z_S8pr-R9pWZw6GDGgSqZaO9bu2-jFkCINLAOaUvaSad_bdhjxp6WtsLk7seTnhbxd4L9TJdioDRFsvHY6mMuxSkaK2/20130417_07.png?psid=1" alt="" /&gt;&lt;/p&gt;

&lt;p&gt;En código, este planteamiento quedaría de la siguiente forma:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Dimensiones&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;        &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; Ancho { get; set; }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; Alto { get; set; }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; GetArea()&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;this&lt;/span&gt;.Ancho * &lt;span class="kwrd"&gt;this&lt;/span&gt;.Alto;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;        } &lt;span class="rem"&gt;// GetArea&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;    } &lt;span class="rem"&gt;// Dimensiones&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Cuadrado : Dimensiones&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; Ancho&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;            get&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;            {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;                &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;                &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;base&lt;/span&gt;.Ancho;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  23:  &lt;/span&gt;            }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  24:  &lt;/span&gt;            set&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  25:  &lt;/span&gt;            {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  26:  &lt;/span&gt;                &lt;span class="kwrd"&gt;base&lt;/span&gt;.Alto = &lt;span class="kwrd"&gt;value&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  27:  &lt;/span&gt;                &lt;span class="kwrd"&gt;base&lt;/span&gt;.Ancho = &lt;span class="kwrd"&gt;value&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  28:  &lt;/span&gt;            }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  29:  &lt;/span&gt;        } &lt;span class="rem"&gt;// Ancho&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  30:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  31:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; Alto&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  32:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  33:  &lt;/span&gt;            get&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  34:  &lt;/span&gt;            {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  35:  &lt;/span&gt;                &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;base&lt;/span&gt;.Alto;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  36:  &lt;/span&gt;            }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  37:  &lt;/span&gt;            set&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  38:  &lt;/span&gt;            {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  39:  &lt;/span&gt;                &lt;span class="kwrd"&gt;base&lt;/span&gt;.Alto = &lt;span class="kwrd"&gt;value&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  40:  &lt;/span&gt;                &lt;span class="kwrd"&gt;base&lt;/span&gt;.Ancho = &lt;span class="kwrd"&gt;value&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  41:  &lt;/span&gt;            }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  42:  &lt;/span&gt;        } &lt;span class="rem"&gt;// Alto&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  43:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  44:  &lt;/span&gt;    } &lt;span class="rem"&gt;// Cuadrado&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  45:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  46:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Rectangulo : Dimensiones&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  47:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  48:  &lt;/span&gt;    } // Rectangulo&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Consumir nuestras clases ahora quedaría de la siguiente manera:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;Dimensiones figura = &lt;span class="kwrd"&gt;new&lt;/span&gt; Rectangulo();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;figura.Alto = 3;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;figura.Ancho = 7;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;MessageBox.Show(figura.GetArea().ToString());&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;De esta manera y con este ejemplo, aproximamos una solución a los problemas planteados.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ISP o Interface Segregation Principle&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Este principio nos indica que los clientes no deberían ser forzados a implementar interfaces que no van a utilizar.&lt;/p&gt;

&lt;p&gt;Deberíamos tener en cuenta que si tenemos una interfaz bastante grande, deberíamos pensar en segregarla en varias más pequeñas y específicas.&lt;/p&gt;

&lt;p&gt;Un ejemplo práctico de esto que estamos comentando en la siguiente interfaz:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://aas0dg.sn2.livefilestore.com/y1pEKCVcE-nxErBu7tBmioN66vyv1ogYebUOb8oU13FNnw2AV_0s5-iwuo6R-8bixkYyy9etZwWS6k1wS9u4xw1HZQcKMxXiYxP/20130417_08.png?psid=1" alt="" /&gt;&lt;/p&gt;

&lt;p&gt;Esta interfaz tiene tres métodos muy sencillos a modo de ejemplo:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;interface&lt;/span&gt; IDesplazarse&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;        &lt;span class="kwrd"&gt;void&lt;/span&gt; Conducir();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;        &lt;span class="kwrd"&gt;void&lt;/span&gt; Correr();&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;        &lt;span class="kwrd"&gt;void&lt;/span&gt; Pasar();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;    } // IDesplazarse&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Sin embargo, aquí nos encontramos con una característica a tener en cuenta.&lt;/p&gt;

&lt;p&gt;Un ser humano que va a desplazarse no tiene porqué saber conducir, o incluso a lo mejor, no tiene edad suficiente para conducir.&lt;/p&gt;

&lt;p&gt;Imaginemos un niño de 15 años. Podrá pasear y podrá correr, pero no podrá conducir.&lt;/p&gt;

&lt;p&gt;Así que nuestra interfaz es correcta para otro grupo de personas que cumplan todos los requisitos de la interfaz o sobre las que queramos ejecutar el método de Conducir, pero si tuviéramos una clase Persona que implementara IDesplazarse y que no pudiera conducir, se produciría una excepción ya que no hemos implementado dicha funcionalidad.&lt;/p&gt;

&lt;p&gt;Es decir, deberíamos segregar la interfaz en más de una interfaz de acuerdo a nuestras necesidades. Y en este caso, nuestra solución quedaría de la siguiente manera:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://aas0dg.sn2.livefilestore.com/y1pyRyPfdjfU4uhiXNiUdoQiW5TsIJpDmEA-bL3_J3TtbGW0Gz3jn03HuM7AiehSMMQqnEF71XiSNOPocphS3m_HEEVhBYdkU1D/20130417_09.png?psid=1" alt="" /&gt;&lt;/p&gt;

&lt;p&gt;Y el código de esta nueva implementación quedaría de la siguiente manera:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;interface&lt;/span&gt; IDesplazarse&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;        &lt;span class="kwrd"&gt;void&lt;/span&gt; Correr();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;        &lt;span class="kwrd"&gt;void&lt;/span&gt; Pasar();&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    } &lt;span class="rem"&gt;// IDesplazarse&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;interface&lt;/span&gt; IDesplazarseConCarnetConducir : IDesplazarse&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;        &lt;span class="kwrd"&gt;void&lt;/span&gt; Conducir();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;    } // IDesplazarseConCarnetConducir&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Como podemos apreciar, tendremos personas que utilicen la interfaz IDesplazarse y otras que además de desplazarse conduzcan, por lo que implementarán la interfaz IDesplazarseConCarnetConducir que implementará a su vez IDesplazarse.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DIP o Dependency Inversion Principle&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;En este principio se enuncia que deberíamos depender de las abstracciones y no de las implementaciones. Las abstracciones no deberían depender de los detalles.&lt;/p&gt;

&lt;p&gt;Por otro lado, Dependency Injection o Inyección de Dependencias es un método que nos permite cumplir con este principio.&lt;/p&gt;

&lt;p&gt;Pero ciñéndonos a los ejemplos, vamos a aproximar una comprensión sobre DIP.&lt;/p&gt;

&lt;p&gt;El diagrama que recogería esta filosofía sería el siguiente:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://aas0dg.sn2.livefilestore.com/y1paWMAnhWeP7K1uIisBjYtW436fv27GzcWR4Y4sxy9dr1TaiqJaV3sgqQNRdNaT1yJfHf_90BQJdi0Y0zUuHDAGrw5UdFs150k/20130417_10.png?psid=1" alt="" /&gt;&lt;/p&gt;

&lt;p&gt;El código del diagrama anterior es el que se indica a continuación:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;interface&lt;/span&gt; IValidator&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;        &lt;span class="kwrd"&gt;bool&lt;/span&gt; Validate();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    } &lt;span class="rem"&gt;// IValidator&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ValidationManager&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; IValidator validator;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; ValidationManager(IValidator validator)&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;            &lt;span class="kwrd"&gt;this&lt;/span&gt;.validator = validator;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;        } &lt;span class="rem"&gt;// ValidationManager&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Execute()&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (!&lt;span class="kwrd"&gt;this&lt;/span&gt;.validator.Validate())&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;            {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;                &lt;span class="rem"&gt;// Do Something&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;            }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;        } &lt;span class="rem"&gt;// Execute&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  23:  &lt;/span&gt;    } // ValidationManager&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Como podemos ver aquí, dependemos de las abstracciones en lugar de las implementaciones, y todas las referencias están basadas en interfaces.&lt;/p&gt;

&lt;p&gt;Independientemente del ejemplo anterior, también podríamos utilizar el patrón factoría (&lt;em&gt;Factory Pattern&lt;/em&gt;) con el fin de resolver a través de ese patrón, todas las dependencias.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=209102" width="1" height="1"&gt;</content><author><name>jorge</name><uri>http://geeks.ms/members/jorge/default.aspx</uri></author><category term="Arquitectura" scheme="http://geeks.ms/blogs/jorge/archive/tags/Arquitectura/default.aspx" /><category term="C#" scheme="http://geeks.ms/blogs/jorge/archive/tags/C_2300_/default.aspx" /><category term=".NET Framework 4.0" scheme="http://geeks.ms/blogs/jorge/archive/tags/.NET+Framework+4.0/default.aspx" /><category term="Visual Studio 2010" scheme="http://geeks.ms/blogs/jorge/archive/tags/Visual+Studio+2010/default.aspx" /><category term="Microsoft .NET Framework 4.0" scheme="http://geeks.ms/blogs/jorge/archive/tags/Microsoft+.NET+Framework+4.0/default.aspx" /><category term="Microsoft .NET Framework 4.5" scheme="http://geeks.ms/blogs/jorge/archive/tags/Microsoft+.NET+Framework+4.5/default.aspx" /><category term=".NET Framework 4.5" scheme="http://geeks.ms/blogs/jorge/archive/tags/.NET+Framework+4.5/default.aspx" /><category term="Visual Studio 2012" scheme="http://geeks.ms/blogs/jorge/archive/tags/Visual+Studio+2012/default.aspx" /></entry><entry><title>Reutilización de código, mantenimiento de aplicaciones (IV)</title><link rel="alternate" type="text/html" href="/blogs/jorge/archive/2013/04/15/reutilizaci-243-n-de-c-243-digo-mantenimiento-de-aplicaciones-iv.aspx" /><id>/blogs/jorge/archive/2013/04/15/reutilizaci-243-n-de-c-243-digo-mantenimiento-de-aplicaciones-iv.aspx</id><published>2013-04-15T06:00:00Z</published><updated>2013-04-15T06:00:00Z</updated><content type="html">&lt;p&gt;&lt;strong&gt;&lt;img height="224" width="276" src="http://www.kidney-support.org/uploads/allimg/121222/5-1212221AZN50.jpg" alt="" /&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Introducci&amp;oacute;n&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Seguimos avanzando en nuestro desarrollo mejor&amp;aacute;ndolo poco a poco.&lt;/p&gt;
&lt;p&gt;Esto me recuerda a aquellos maravillosos a&amp;ntilde;os de la normalizaci&amp;oacute;n de nuestras bases de datos para llegar a tercera forma normal (3NF) o llegar al &amp;eacute;xtasis con Boyce-Codd.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Implementaci&amp;oacute;n de la soluci&amp;oacute;n&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;En este caso, la implementaci&amp;oacute;n de nuestra soluci&amp;oacute;n partiendo del c&amp;oacute;digo anterior nos sugiere &lt;em&gt;partir&lt;/em&gt; el c&amp;oacute;digo en m&amp;oacute;dulos o de una forma tal que nos permita depurar y mantener mejor nuestra aplicaci&amp;oacute;n, al mismo tiempo que podemos abordar la posibilidad de reutilizar el c&amp;oacute;digo.&lt;/p&gt;
&lt;p&gt;Para llevar a cabo nuestro prop&amp;oacute;sito, hemos creado un proyecto en Visual Studio que ser&amp;aacute; una biblioteca de clases a la que he llamado &lt;em&gt;Foo.Framework&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Dentro de este proyecto, vamos a crear nuestra lista enumerada que ya vimos en la entrada anterior, y un objeto que se encargar&amp;aacute; de llevar a cabo el proceso de lectura y escritura de ficheros de texto y documentos Excel.&lt;/p&gt;
&lt;p&gt;Dicho de otro modo, vamos a separar algunas responsabilidades iniciales de modo que aporte diferentes beneficios.&lt;/p&gt;
&lt;p&gt;La lista enumerada se llamar&amp;aacute; &lt;em&gt;ConnectorType&lt;/em&gt; y tendr&amp;aacute; este aspecto:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://owj7va.sn2.livefilestore.com/y1p2hd-u1BkEZgJFkW6LXff69IQOWw6D5m1m66Nx7_6QM4rQkhIlYX5jAGI-0Agq99jrWj8NiBg6Ihu-rJIeBxwUyr8iQe5dicj/20130412_01.png?psid=1" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;El c&amp;oacute;digo de esta lista enumerada corresponder&amp;aacute; con lo que se indica a continuaci&amp;oacute;n:&lt;/p&gt;
&lt;div class="csharpcode"&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; Foo.Framework&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;enum&lt;/span&gt; ConnectorType&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;        Excel,&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;        Text&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;    } &lt;span class="rem"&gt;// ConnectorType&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;} // Foo.Framework&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;El c&amp;oacute;digo dentro del cu&amp;aacute;l vamos a trabajar con ficheros de texto y documentos Excel estar&amp;aacute; alojado en una clase de nombre &lt;em&gt;ConnectorProcess&lt;/em&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://owj7va.sn2.livefilestore.com/y1p5nqr_Mm6t6GcwnwIAz_Hkw15pjG8YoRg4J-D0y2goKyQma6Ta5VFVFOuxARa41JxKTPHRkYS9cJD9rcdk2T5vkVawKIcD2Wb/20130412_02.png?psid=1" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;El c&amp;oacute;digo de esta clase es el que se indica a continuaci&amp;oacute;n:&lt;/p&gt;
&lt;div class="csharpcode"&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; Foo.Framework&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;sealed&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ConnectorProcess&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;    {&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; ConnectorProcess(ConnectorType connectorType)&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;        {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;            &lt;span class="kwrd"&gt;this&lt;/span&gt;.Connector = connectorType;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;        } &lt;span class="rem"&gt;// ConnectorProcess Constructor&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; ConnectorType Connector { get; set; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Read()&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;        {&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;            &lt;span class="kwrd"&gt;switch&lt;/span&gt; (&lt;span class="kwrd"&gt;this&lt;/span&gt;.Connector)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;            {&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;                &lt;span class="kwrd"&gt;case&lt;/span&gt; ConnectorType.Excel:&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;                    &lt;span class="rem"&gt;// Excel&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  23:  &lt;/span&gt;                    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;Excel le&amp;iacute;da&amp;quot;&lt;/span&gt;;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  24:  &lt;/span&gt;                    &lt;span class="rem"&gt;// Hacemos algo con la informaci&amp;oacute;n le&amp;iacute;da.&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  25:  &lt;/span&gt;                    &lt;span class="rem"&gt;// ...&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  26:  &lt;/span&gt;                    &lt;span class="kwrd"&gt;break&lt;/span&gt;;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  27:  &lt;/span&gt;                &lt;span class="kwrd"&gt;default&lt;/span&gt;:&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  28:  &lt;/span&gt;                    &lt;span class="rem"&gt;// Texto&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  29:  &lt;/span&gt;                    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;Texto le&amp;iacute;do&amp;quot;&lt;/span&gt;;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  30:  &lt;/span&gt;                    &lt;span class="rem"&gt;// Hacemos algo con el texto le&amp;iacute;do.&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  31:  &lt;/span&gt;                    &lt;span class="rem"&gt;// ...&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  32:  &lt;/span&gt;                    &lt;span class="kwrd"&gt;break&lt;/span&gt;;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  33:  &lt;/span&gt;            }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  34:  &lt;/span&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; String.Empty;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  35:  &lt;/span&gt;        } &lt;span class="rem"&gt;// Read&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  36:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  37:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Write()&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  38:  &lt;/span&gt;        {&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  39:  &lt;/span&gt;            &lt;span class="kwrd"&gt;switch&lt;/span&gt; (&lt;span class="kwrd"&gt;this&lt;/span&gt;.Connector)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  40:  &lt;/span&gt;            {&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  41:  &lt;/span&gt;                &lt;span class="kwrd"&gt;case&lt;/span&gt; ConnectorType.Excel:&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  42:  &lt;/span&gt;                    &lt;span class="rem"&gt;// Excel&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  43:  &lt;/span&gt;                    &lt;span class="rem"&gt;// Escribimos Excel.&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  44:  &lt;/span&gt;                    &lt;span class="kwrd"&gt;break&lt;/span&gt;;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  45:  &lt;/span&gt;                &lt;span class="kwrd"&gt;default&lt;/span&gt;:&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  46:  &lt;/span&gt;                    &lt;span class="rem"&gt;// Texto&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  47:  &lt;/span&gt;                    &lt;span class="rem"&gt;// Escribimos Texto.&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  48:  &lt;/span&gt;                    &lt;span class="kwrd"&gt;break&lt;/span&gt;;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  49:  &lt;/span&gt;            }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  50:  &lt;/span&gt;        } &lt;span class="rem"&gt;// Write&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  51:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  52:  &lt;/span&gt;    } &lt;span class="rem"&gt;// ConnectorProcess&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  53:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  54:  &lt;/span&gt;} // Foo.Framework&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;Y finalmente, nuestra interfaz de usuario.&lt;/p&gt;
&lt;p&gt;No queda otra de momento, que crear una vinculaci&amp;oacute;n fuerte entre nuestra interfaz de usuario y &lt;em&gt;Foo.Framework&lt;/em&gt;, ya que vamos a utilizar las clases que tenemos dentro de ese ensamblado.&lt;/p&gt;
&lt;p&gt;Habiendo incluido una referencia a &lt;em&gt;Foo.Framework&lt;/em&gt;, lo que tenemos que hacer es escribir el c&amp;oacute;digo de nuestra aplicaci&amp;oacute;n y que tendr&amp;aacute; el siguiente aspecto:&lt;/p&gt;
&lt;div class="csharpcode"&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; UI_Sample&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; System.ComponentModel;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; System.Drawing;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; System.Windows.Forms;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; Foo.Framework;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;partial&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; MainForm : Form&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;    {&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; MainForm()&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;        {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;            InitializeComponent();&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;            &lt;span class="rem"&gt;// Por defecto es un fichero de texto.&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;            &lt;span class="kwrd"&gt;this&lt;/span&gt;.Connector = ConnectorType.Excel;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;        } &lt;span class="rem"&gt;// MainForm Constructor&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  23:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; ConnectorType Connector { get; set; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  24:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  25:  &lt;/span&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; btnSampleTest_Click(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  26:  &lt;/span&gt;        {&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  27:  &lt;/span&gt;            ConnectorProcess connectorProcess = &lt;span class="kwrd"&gt;new&lt;/span&gt; ConnectorProcess(&lt;span class="kwrd"&gt;this&lt;/span&gt;.Connector);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  28:  &lt;/span&gt;            &lt;span class="rem"&gt;// Leemos la informaci&amp;oacute;n.&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  29:  &lt;/span&gt;            &lt;span class="kwrd"&gt;string&lt;/span&gt; data = connectorProcess.Read();&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  30:  &lt;/span&gt;            &lt;span class="rem"&gt;// Escribimos el resultado del supuesto proceso anterior.&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  31:  &lt;/span&gt;            connectorProcess.Write();&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  32:  &lt;/span&gt;            &lt;span class="rem"&gt;// Mostramos un mensaje en pantalla tipo fake.&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  33:  &lt;/span&gt;            MessageBox.Show(&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  34:  &lt;/span&gt;                            data +&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  35:  &lt;/span&gt;                            Environment.NewLine +&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  36:  &lt;/span&gt;                            &lt;span class="str"&gt;&amp;quot;Lectura y escritura realizada.&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  37:  &lt;/span&gt;        } &lt;span class="rem"&gt;// btnSampleTest_Click&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  38:  &lt;/span&gt;        &lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  39:  &lt;/span&gt;    } &lt;span class="rem"&gt;// MainForm&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  40:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  41:  &lt;/span&gt;} // UI_Sample&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;

Como podemos apreciar, el c&amp;oacute;digo de nuestra interfaz de usuario se ha reducido bastante y est&amp;aacute; ahora quiz&amp;aacute;s, mucho m&amp;aacute;s claro que antes. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Posibles problemas&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Hemos mejorado mucho algunos de los problemas detectados en las fases de desarrollo iniciales, y no decimos nada con respecto a como empezamos el proyecto y como est&amp;aacute; ahora. Sin embargo, seguimos teniendo problemas y se nos siguen ocurriendo mejoras.&lt;/p&gt;
&lt;p&gt;El problema m&amp;aacute;s molesto es quiz&amp;aacute;s que nuestra interfaz de usuario tiene una relaci&amp;oacute;n fuerte con nuestro ensamblado &lt;em&gt;Foo.Framework&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Por otro lado algo resuena en nuestras cabezas&amp;hellip; algo denominado como principios b&amp;aacute;sicos de programaci&amp;oacute;n orientada a objetos&amp;hellip; en una sola palabra: Los principios SOLID.&lt;/p&gt;
&lt;p&gt;Retomando la idea que indiqu&amp;eacute; al principio sobre 3NF y Boyce-Codd con respecto al modelado de una base de datos, SOLID es para m&amp;iacute; su espejo con respecto a la programaci&amp;oacute;n orientada a objetos.&lt;/p&gt;
&lt;p&gt;Cierto es que si queremos, podemos preparar una base de datos sin normalizar y que podemos trabajar con ella sin necesidad de llegar a 3FN o Boyce-Codd, pero que duda cabe que evitaremos problemas a largo plazo si la tenemos normalizada correctamente desde un principio.&lt;/p&gt;
&lt;p&gt;Tambi&amp;eacute;n y por similitud, podemos desarrollar una aplicaci&amp;oacute;n Software sin tener en cuenta ning&amp;uacute;n principio SOLID, pero que duda cabe, que tenerlos presentes todos y cumplirlos, nos aportar&amp;aacute; beneficios notables de mantenimiento y reutilizaci&amp;oacute;n.&lt;/p&gt;
&lt;p&gt;La idea principal es la de adaptar nuestra aplicaci&amp;oacute;n a los cambios, ser &amp;aacute;giles ante esos cambios, y tratar de evitar que dichos cambios afecten a otras partes de la aplicaci&amp;oacute;n.&lt;/p&gt;
&lt;p&gt;Pero quiz&amp;aacute;s antes de seguir mejorando nuestro ejemplo, debamos hacer una peque&amp;ntilde;a pausa en el camino&amp;hellip;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=209051" width="1" height="1"&gt;</content><author><name>jorge</name><uri>http://geeks.ms/members/jorge/default.aspx</uri></author><category term="Arquitectura" scheme="http://geeks.ms/blogs/jorge/archive/tags/Arquitectura/default.aspx" /><category term="C#" scheme="http://geeks.ms/blogs/jorge/archive/tags/C_2300_/default.aspx" /><category term=".NET Framework 4.0" scheme="http://geeks.ms/blogs/jorge/archive/tags/.NET+Framework+4.0/default.aspx" /><category term="Visual Studio 2010" scheme="http://geeks.ms/blogs/jorge/archive/tags/Visual+Studio+2010/default.aspx" /><category term="Microsoft .NET Framework 4.0" scheme="http://geeks.ms/blogs/jorge/archive/tags/Microsoft+.NET+Framework+4.0/default.aspx" /><category term="Microsoft .NET Framework 4.5" scheme="http://geeks.ms/blogs/jorge/archive/tags/Microsoft+.NET+Framework+4.5/default.aspx" /><category term=".NET Framework 4.5" scheme="http://geeks.ms/blogs/jorge/archive/tags/.NET+Framework+4.5/default.aspx" /><category term="Visual Studio 2012" scheme="http://geeks.ms/blogs/jorge/archive/tags/Visual+Studio+2012/default.aspx" /></entry><entry><title>Reutilización de código, mantenimiento de aplicaciones (III)</title><link rel="alternate" type="text/html" href="/blogs/jorge/archive/2013/04/12/reutilizaci-243-n-de-c-243-digo-mantenimiento-de-aplicaciones-iii.aspx" /><id>/blogs/jorge/archive/2013/04/12/reutilizaci-243-n-de-c-243-digo-mantenimiento-de-aplicaciones-iii.aspx</id><published>2013-04-12T06:00:00Z</published><updated>2013-04-12T06:00:00Z</updated><content type="html">&lt;p&gt;&lt;strong&gt;&lt;img src="http://www.kidney-support.org/uploads/allimg/121222/5-1212221AZN50.jpg" width="276" height="224" alt="" /&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Introducción&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Nos encontramos en una encrucijada.&lt;/p&gt;  &lt;p&gt;Nuestra aplicación parecía sencilla y empezó siéndolo, pero los requisitos inicialmente marcados han variado y nos está empezando a dar algún que otro dolor de cabeza.&lt;/p&gt;  &lt;p&gt;No obstante, hemos sabido adaptarnos a esos requisitos y hemos modificado nuestra aplicación para cubrirlos.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Implementación de la solución&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;La idea inicial es la de partir del código de la entrada anterior, refactorizar o acondicionar de forma general el código para que cumpla los requisitos de forma aceptable y posibilite un mejor mantenimiento del código.&lt;/p&gt;  &lt;p&gt;Basándonos aún en una aplicación Windows, nuestro código quedará de la siguiente forma.&lt;/p&gt;  &lt;p&gt;En primer lugar, la lista enumerada:&lt;/p&gt;  &lt;div class="csharpcode"&gt;   &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; UI_Sample&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;enum&lt;/span&gt; ConnectorType&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;        Excel,&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;        Text&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;    } &lt;span class="rem"&gt;// ConnectorType&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;} // UI_Sample&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Como podemos ver en el código anterior, nuestra clase enumerada tiene dos valores, uno para definir los ficheros de tipo Excel y otro para los de tipo Text o texto.&lt;/p&gt;

&lt;p&gt;De esta manera, podremos indicar el origen y destino de forma más flexible.&lt;/p&gt;

&lt;p&gt;El código de nuestra aplicación Windows quedará ahora de la siguiente forma:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; UI_Sample&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; System.ComponentModel;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; System.Drawing;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; System.Windows.Forms;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;partial&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; MainForm : Form&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; MainForm()&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;            InitializeComponent();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;            &lt;span class="rem"&gt;// Por defecto es un fichero de texto.&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;            &lt;span class="kwrd"&gt;this&lt;/span&gt;.Connector = ConnectorType.Text;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;        } &lt;span class="rem"&gt;// MainForm Constructor&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; ConnectorType Connector { get; set; }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; btnSampleTest_Click(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  23:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  24:  &lt;/span&gt;            &lt;span class="kwrd"&gt;string&lt;/span&gt; data = String.Empty;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  25:  &lt;/span&gt;            &lt;span class="rem"&gt;// Leemos la información.&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  26:  &lt;/span&gt;            data = Read();&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  27:  &lt;/span&gt;            &lt;span class="rem"&gt;// Escribimos el resultado del supuesto proceso anterior.&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  28:  &lt;/span&gt;            Write();&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  29:  &lt;/span&gt;            &lt;span class="rem"&gt;// Mostramos un mensaje en pantalla tipo fake.&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  30:  &lt;/span&gt;            MessageBox.Show(&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  31:  &lt;/span&gt;                            data +&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  32:  &lt;/span&gt;                            Environment.NewLine +&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  33:  &lt;/span&gt;                            &lt;span class="str"&gt;&amp;quot;Lectura y escritura realizada.&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  34:  &lt;/span&gt;        } &lt;span class="rem"&gt;// btnSampleTest_Click&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  35:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  36:  &lt;/span&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Read()&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  37:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  38:  &lt;/span&gt;            &lt;span class="kwrd"&gt;switch&lt;/span&gt; (&lt;span class="kwrd"&gt;this&lt;/span&gt;.Connector)&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  39:  &lt;/span&gt;            {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  40:  &lt;/span&gt;                &lt;span class="kwrd"&gt;case&lt;/span&gt; ConnectorType.Excel:&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  41:  &lt;/span&gt;                    &lt;span class="rem"&gt;// Excel&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  42:  &lt;/span&gt;                    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;Excel leída&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  43:  &lt;/span&gt;                    &lt;span class="rem"&gt;// Hacemos algo con la información leída.&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  44:  &lt;/span&gt;                    &lt;span class="rem"&gt;// ...&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  45:  &lt;/span&gt;                    &lt;span class="kwrd"&gt;break&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  46:  &lt;/span&gt;                &lt;span class="kwrd"&gt;default&lt;/span&gt;:&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  47:  &lt;/span&gt;                    &lt;span class="rem"&gt;// Texto&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  48:  &lt;/span&gt;                    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;Texto leído&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  49:  &lt;/span&gt;                    &lt;span class="rem"&gt;// Hacemos algo con el texto leído.&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  50:  &lt;/span&gt;                    &lt;span class="rem"&gt;// ...&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  51:  &lt;/span&gt;                    &lt;span class="kwrd"&gt;break&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  52:  &lt;/span&gt;            }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  53:  &lt;/span&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; String.Empty;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  54:  &lt;/span&gt;        } &lt;span class="rem"&gt;// Read&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  55:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  56:  &lt;/span&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Write()&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  57:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  58:  &lt;/span&gt;            &lt;span class="kwrd"&gt;switch&lt;/span&gt; (&lt;span class="kwrd"&gt;this&lt;/span&gt;.Connector)&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  59:  &lt;/span&gt;            {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  60:  &lt;/span&gt;                &lt;span class="kwrd"&gt;case&lt;/span&gt; ConnectorType.Excel:&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  61:  &lt;/span&gt;                    &lt;span class="rem"&gt;// Excel&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  62:  &lt;/span&gt;                    &lt;span class="rem"&gt;// Escribimos Excel.&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  63:  &lt;/span&gt;                    &lt;span class="kwrd"&gt;break&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  64:  &lt;/span&gt;                &lt;span class="kwrd"&gt;default&lt;/span&gt;:&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  65:  &lt;/span&gt;                    &lt;span class="rem"&gt;// Texto&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  66:  &lt;/span&gt;                    &lt;span class="rem"&gt;// Escribimos Texto.&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  67:  &lt;/span&gt;                    &lt;span class="kwrd"&gt;break&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  68:  &lt;/span&gt;            }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  69:  &lt;/span&gt;        } &lt;span class="rem"&gt;// Write&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  70:  &lt;/span&gt;        &lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  71:  &lt;/span&gt;    } &lt;span class="rem"&gt;// MainForm&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  72:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  73:  &lt;/span&gt;} // UI_Sample&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Hemos preparado una propiedad para indicar el tipo de conector a utilizar.&lt;/p&gt;

&lt;p&gt;Y posteriormente hemos llamado a una función &lt;em&gt;Read&lt;/em&gt; y a un método &lt;em&gt;Write&lt;/em&gt; para llevar a cabo nuestras acciones.&lt;/p&gt;



&lt;p&gt;Indudablemente el código tiene un carácter meramente descriptivo porque faltarían más cosas como implementar la lógica de lectura y otras partes importantes de nuestra solución, pero lo importante aquí es quedarnos con la idea.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Posibles problemas&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Empezamos con una aplicación para procesar archivos de texto.&lt;/p&gt;

&lt;p&gt;Más tarde, los requisitos cambiaron y nos pedían procesar archivos de texto y Excel. Hicimos los cambios, pero nos dimos cuenta que de cara al mantenimiento, podríamos tener algún que otro quebradero de cabeza, así que hemos pensado en refactorizar un poco el código y mejorar algunas cosas.&lt;/p&gt;

&lt;p&gt;Así surge esta tercera revisión que mejora aspectos relacionados con el mantenimiento. Además, si alguien nos pide ahora agregar otro conector como por ejemplo uno para leer y escribir en base de datos, bastará con agregar un nuevo elemento a nuestra lista enumerada y modificar &lt;em&gt;Read&lt;/em&gt; y &lt;em&gt;Write&lt;/em&gt; para que procesen también entradas y salidas con bases de datos.&lt;/p&gt;

&lt;p&gt;Parece que todo está más o menos acorde con lo que buscamos, pero tenemos delante de nosotros varios problemas bastante más graves que a simple vista muchas veces no vemos.&lt;/p&gt;

&lt;p&gt;Por un lado la separación de responsabilidades. Aquí el lema es divide y vencerás. Si queremos hacer algo que nos va a llevar mucho tiempo o proceso, lo mejor es separar en unidades pequeñas cada una de esas actividades. Pensemos por poner un ejemplo, en una línea de montaje.&lt;/p&gt;

&lt;p&gt;Por otro lado, y en el caso de &lt;em&gt;&lt;strike&gt;que hiciéramos&lt;/strike&gt; &lt;/em&gt;pruebas unitarias, la posibilidad de probar las porciones de código por separado y centrando los esfuerzos y dedicación únicamente en aquellas unidades de Software que realmente cambian sin que estas afecten a un todo. Pensemos en que alguna parte de nuestro Software se modifica, como por ejemplo que aparece una nueva versión de Excel que afecta como es lógico al proceso de documentos Excel. Si el resto de código de nuestra aplicación funciona perfectamente, la forma en la que hemos codificado nuestra aplicación nos obliga lo queramos o no, a tocar una parte de código que entremezcla cosas que funcionan y otras que no. Además de que puede haber diferentes personas tocando el mismo código y que existen herramientas que lo permiten, es cierto que es un foco de problemas, y además, es posible que toquemos accidentalmente código que funcionaba, por lo que podemos crear nuevos problemas.&lt;/p&gt;

&lt;p&gt;Otro aspecto a destacar y no menos importante, tiene que ver con la dependencia. Y es que nuestra aplicación depende fuertemente de unas piezas de Software que entremezclan UI con lógica de negocio y no sólo ensucian nuestro desarrollo, sino que enmaraña el mantenimiento de la misma y dificulta su depuración.&lt;/p&gt;

&lt;p&gt;Y todo esto sin poner encima de la mesa otro de los problemas más habituales y que siempre pensamos en ellos al final, la reutilización del código realizado. En este caso, al estar todo integrado dentro de una misma aplicación como es la interfaz de usuario, su reutilización se nos antoja al menos, compleja.&lt;/p&gt;

&lt;p&gt;¿Qué hacer entonces?. ¿Cómo resolver estos problemas?.&lt;/p&gt;

&lt;p&gt;En la próxima entrada veremos como resolver alguno de estos problemas.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=209049" width="1" height="1"&gt;</content><author><name>jorge</name><uri>http://geeks.ms/members/jorge/default.aspx</uri></author><category term="Arquitectura" scheme="http://geeks.ms/blogs/jorge/archive/tags/Arquitectura/default.aspx" /><category term="C#" scheme="http://geeks.ms/blogs/jorge/archive/tags/C_2300_/default.aspx" /><category term=".NET Framework 4.0" scheme="http://geeks.ms/blogs/jorge/archive/tags/.NET+Framework+4.0/default.aspx" /><category term="Visual Studio 2010" scheme="http://geeks.ms/blogs/jorge/archive/tags/Visual+Studio+2010/default.aspx" /><category term="Microsoft .NET Framework 4.0" scheme="http://geeks.ms/blogs/jorge/archive/tags/Microsoft+.NET+Framework+4.0/default.aspx" /><category term="Microsoft .NET Framework 4.5" scheme="http://geeks.ms/blogs/jorge/archive/tags/Microsoft+.NET+Framework+4.5/default.aspx" /><category term=".NET Framework 4.5" scheme="http://geeks.ms/blogs/jorge/archive/tags/.NET+Framework+4.5/default.aspx" /><category term="Visual Studio 2012" scheme="http://geeks.ms/blogs/jorge/archive/tags/Visual+Studio+2012/default.aspx" /></entry><entry><title>Reutilización de código, mantenimiento de aplicaciones (II)</title><link rel="alternate" type="text/html" href="/blogs/jorge/archive/2013/04/10/reutilizaci-243-n-de-c-243-digo-mantenimiento-de-aplicaciones-ii.aspx" /><id>/blogs/jorge/archive/2013/04/10/reutilizaci-243-n-de-c-243-digo-mantenimiento-de-aplicaciones-ii.aspx</id><published>2013-04-10T06:00:00Z</published><updated>2013-04-10T06:00:00Z</updated><content type="html">&lt;p&gt;&lt;strong&gt;&lt;img src="http://www.kidney-support.org/uploads/allimg/121222/5-1212221AZN50.jpg" width="276" height="224" alt="" /&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Introducción&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Como vimos en el artículo inicial, nos encontramos con un problema sencillo de resolver pero que poco a poco se iba retorciendo o complicando.&lt;/p&gt;  &lt;p&gt;Inicialmente teníamos en mente la lectura de un fichero de texto y la escritura de una información determinada después de procesarla en un fichero de texto.&lt;/p&gt;  &lt;p&gt;Sin embargo, los requisitos cambian y ahora se nos pide que además de leer y escribir un fichero de texto, hagamos lo mismo pero con un fichero de Excel.&lt;/p&gt;  &lt;p&gt;En realidad sería hacer algo similar a lo siguiente:&lt;/p&gt;  &lt;p&gt;&lt;img src="https://owiwmq.sn2.livefilestore.com/y1pg3EDrJxEQzbAHjlZY-0xebnAqQrJe9jR0kL66jJby4QpfsoQkxd1oZGv9hwfszDHAgxeIkM_NxOmrO947zdSFQdllAdFf0k5/20130405_02.png?psid=1" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Implementación de la solución&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Suponiendo que tengamos toda la lógica en nuestro formulario de prueba (igualmente ocurriría si tuviéramos toda la lógica implementada en una biblioteca de clases aunque los problemas estarían más acusados en el caso de tener todo implementado la interfaz de usuario), el código quedaría en este caso de la siguiente manera:&lt;/p&gt;  &lt;div class="csharpcode"&gt;   &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; UI_Sample&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; System.ComponentModel;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; System.Drawing;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; System.Windows.Forms;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;partial&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; MainForm : Form&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; MainForm()&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;            InitializeComponent();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;            &lt;span class="rem"&gt;// Por defecto es un fichero de texto.&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;            &lt;span class="kwrd"&gt;this&lt;/span&gt;.EsTexto = &lt;span class="kwrd"&gt;true&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;        } &lt;span class="rem"&gt;// MainForm Constructor&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; EsTexto { get; set; }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; btnSampleTest_Click(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  23:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  24:  &lt;/span&gt;            &lt;span class="kwrd"&gt;string&lt;/span&gt; data = String.Empty;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  25:  &lt;/span&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;this&lt;/span&gt;.EsTexto)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  26:  &lt;/span&gt;            {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  27:  &lt;/span&gt;                &lt;span class="rem"&gt;// Texto&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  28:  &lt;/span&gt;                data = ReadText();&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  29:  &lt;/span&gt;                &lt;span class="rem"&gt;// Hacemos algo con el texto leído.&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  30:  &lt;/span&gt;                &lt;span class="rem"&gt;// ...&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  31:  &lt;/span&gt;                &lt;span class="rem"&gt;// Escribimos el resultado del supuesto proceso anterior.&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  32:  &lt;/span&gt;                WriteText();&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  33:  &lt;/span&gt;            }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  34:  &lt;/span&gt;            &lt;span class="kwrd"&gt;else&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  35:  &lt;/span&gt;            {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  36:  &lt;/span&gt;                &lt;span class="rem"&gt;// Excel&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  37:  &lt;/span&gt;                data = ReadExcel();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  38:  &lt;/span&gt;                &lt;span class="rem"&gt;// Hacemos algo con la información leída.&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  39:  &lt;/span&gt;                &lt;span class="rem"&gt;// ...&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  40:  &lt;/span&gt;                &lt;span class="rem"&gt;// Escribimos el resultado del supuesto proceso anterior.&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  41:  &lt;/span&gt;                WriteExcel();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  42:  &lt;/span&gt;            }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  43:  &lt;/span&gt;            &lt;span class="rem"&gt;// Mostramos un mensaje en pantalla tipo fake.&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  44:  &lt;/span&gt;            MessageBox.Show(&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  45:  &lt;/span&gt;                            data +&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  46:  &lt;/span&gt;                            Environment.NewLine +&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  47:  &lt;/span&gt;                            &lt;span class="str"&gt;&amp;quot;Lectura y escritura realizada.&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  48:  &lt;/span&gt;        } &lt;span class="rem"&gt;// btnSampleTest_Click&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  49:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  50:  &lt;/span&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; ReadText()&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  51:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  52:  &lt;/span&gt;            &lt;span class="rem"&gt;// Abrimos el fichero y leemos su contenido.&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  53:  &lt;/span&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;Texto leido&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  54:  &lt;/span&gt;        } &lt;span class="rem"&gt;// ReadText&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  55:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  56:  &lt;/span&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; WriteText()&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  57:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  58:  &lt;/span&gt;            &lt;span class="rem"&gt;// Escribimos el fichero en su lugar destino.&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  59:  &lt;/span&gt;        } &lt;span class="rem"&gt;// WriteText&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  60:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  61:  &lt;/span&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; ReadExcel()&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  62:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  63:  &lt;/span&gt;            &lt;span class="rem"&gt;// Abrimos Excel y leemos su contenido.&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  64:  &lt;/span&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;Excel leída&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  65:  &lt;/span&gt;        } &lt;span class="rem"&gt;// ReadExcel&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  66:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  67:  &lt;/span&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; WriteExcel()&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  68:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  69:  &lt;/span&gt;            &lt;span class="rem"&gt;// Escribimos el Excel en su lugar destino.&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  70:  &lt;/span&gt;        } &lt;span class="rem"&gt;// WriteExcel&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  71:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  72:  &lt;/span&gt;    } &lt;span class="rem"&gt;// MainForm&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  73:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  74:  &lt;/span&gt;} // UI_Sample&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Posibles problemas&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Aunque lo esté exagerando un poco, la idea es la de presentar delante nuestra diferentes problemas cotidianos con los que podemos encontrarnos a la hora de desarrollar una solución a un problema planteado.&lt;/p&gt;

&lt;p&gt;En este caso, vemos que el código se está empezando a volver insoportable de mantener.&lt;/p&gt;

&lt;p&gt;En este punto, tenemos una variable booleana que nos va a permitir discriminar entre un fichero de texto y un documento Excel.&lt;/p&gt;

&lt;p&gt;No siendo la mejor de las soluciones, es hasta cierto punto aceptable.&lt;/p&gt;

&lt;p&gt;Sin embargo, ¿qué ocurre si además de Excel y texto necesitamos acceder a la información de una tabla por ejemplo para leer determinada información, procesarla y volver a almacenarla en otra tabla?.&lt;/p&gt;

&lt;p&gt;Bien, nuestra propiedad bool la podemos hacer nullable y así tendremos tres valores, true, false y null.&lt;/p&gt;

&lt;p&gt;Posible chapuza a la vista aunque bien, es una posible solución.&lt;/p&gt;

&lt;p&gt;Otra posible solución es crear una lista enumerada y a partir de ella determinar el tipo de origen, destino que queremos utilizar.&lt;/p&gt;

&lt;p&gt;Es quizás una solución más elegante.&lt;/p&gt;

&lt;p&gt;Otra es crear una llamada por cada tipo y que se cree el objeto de cada tipo para el objetivo de nuestra aplicación, y bien… quizás así podamos llevar a cabo una solución más o menos gloriosa.&lt;/p&gt;

&lt;p&gt;De hecho, en la próxima entrega voy a ajustar todo esto que estoy comentando para sacar adelante algo que resulte un poco más claro a la hora de leer el código… a ver si lo logro y seguimos avanzando viendo problemas y posibles soluciones.&lt;/p&gt;



&lt;p&gt;Hasta la próxima entrega… :)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=209041" width="1" height="1"&gt;</content><author><name>jorge</name><uri>http://geeks.ms/members/jorge/default.aspx</uri></author><category term="Arquitectura" scheme="http://geeks.ms/blogs/jorge/archive/tags/Arquitectura/default.aspx" /><category term="C#" scheme="http://geeks.ms/blogs/jorge/archive/tags/C_2300_/default.aspx" /><category term=".NET Framework 4.0" scheme="http://geeks.ms/blogs/jorge/archive/tags/.NET+Framework+4.0/default.aspx" /><category term="Visual Studio 2010" scheme="http://geeks.ms/blogs/jorge/archive/tags/Visual+Studio+2010/default.aspx" /><category term="Microsoft .NET Framework 4.0" scheme="http://geeks.ms/blogs/jorge/archive/tags/Microsoft+.NET+Framework+4.0/default.aspx" /><category term="Microsoft .NET Framework 4.5" scheme="http://geeks.ms/blogs/jorge/archive/tags/Microsoft+.NET+Framework+4.5/default.aspx" /><category term=".NET Framework 4.5" scheme="http://geeks.ms/blogs/jorge/archive/tags/.NET+Framework+4.5/default.aspx" /><category term="Visual Studio 2012" scheme="http://geeks.ms/blogs/jorge/archive/tags/Visual+Studio+2012/default.aspx" /></entry><entry><title>Reutilización de código, mantenimiento de aplicaciones (I)</title><link rel="alternate" type="text/html" href="/blogs/jorge/archive/2013/04/08/reutilizaci-243-n-de-c-243-digo-mantenimiento-de-aplicaciones-i.aspx" /><id>/blogs/jorge/archive/2013/04/08/reutilizaci-243-n-de-c-243-digo-mantenimiento-de-aplicaciones-i.aspx</id><published>2013-04-08T06:00:00Z</published><updated>2013-04-08T06:00:00Z</updated><content type="html">&lt;p&gt;&lt;strong&gt;&lt;img src="http://www.kidney-support.org/uploads/allimg/121222/5-1212221AZN50.jpg" width="276" height="224" alt="" /&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Introducción&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;No me voy a andar con grandes tecnicismos, más bien todo lo contrario.&lt;/p&gt;  &lt;p&gt;Voy a ir directo al asunto y de forma concisa, planteando los problemas habituales con los que podemos encontrarnos los desarrolladores y cómo hacerlos frente.&lt;/p&gt;  &lt;p&gt;Como avanzar y mejorar nuestro código basándonos en un proyecto teórico inicial y como ir salvando los diferentes obstáculos con los que podemos encontrarnos.&lt;/p&gt;  &lt;p&gt;¿Seremos capaces?… ¡veámoslo!.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Punto de partida&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Partiremos de un ejemplo muy sencillo de entender.&lt;/p&gt;  &lt;p&gt;Empieza el proyecto de desarrollo y nos dicen que preparemos una aplicación que lea como entrada el contenido de un fichero de texto, y como salida, que escriba también en un fichero de texto.&lt;/p&gt;  &lt;p&gt;Vamos a obviar de momento el proceso intermedio.&lt;/p&gt;  &lt;p&gt;Sería algo similar a lo que se indica en la siguiente imagen:&lt;/p&gt;  &lt;p&gt;&lt;img src="https://owiwmq.sn2.livefilestore.com/y1pgzo-2pYZw5uoE7woIJbhmxxEYRAyvh1FSgUcuetBITbW1kn0f1x5VgYPy3GP0u-6RrAHXNFWLTk94FDkOs0SZ-5WRl3RTrXp/20130405_01.png?psid=1" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;Como podemos apreciar… algo muy sencillito de realizar.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Implementación de partida&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Ante esto, la idea parece muy clara y evidente.&lt;/p&gt;  &lt;p&gt;Vamos a crear un proyecto de aplicación Windows y sobre él vamos a llevar a cabo nuestro desarrollo.&lt;/p&gt;  &lt;p&gt;Dentro del formulario Windows hemos insertado un control &lt;em&gt;Button&lt;/em&gt;.&lt;/p&gt;  &lt;p&gt;Todo muy sencillo.&lt;/p&gt;  &lt;p&gt;El código quedaría de la siguiente manera:&lt;/p&gt;  &lt;div class="csharpcode"&gt;   &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; UI_Sample&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; System.ComponentModel;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; System.Drawing;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; System.Windows.Forms;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;partial&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; MainForm : Form&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; MainForm()&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;            InitializeComponent();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;        } &lt;span class="rem"&gt;// MainForm Constructor&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; btnSampleTest_Click(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;            &lt;span class="kwrd"&gt;string&lt;/span&gt; data = Read();&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;            &lt;span class="rem"&gt;// Hacemos algo con el texto leído.&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;            &lt;span class="rem"&gt;// ...&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  23:  &lt;/span&gt;            &lt;span class="rem"&gt;// Escribimos el resultado del supuesto proceso anterior.&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  24:  &lt;/span&gt;            Write();&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  25:  &lt;/span&gt;            &lt;span class="rem"&gt;// Mostramos un mensaje en pantalla tipo fake.&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  26:  &lt;/span&gt;            MessageBox.Show(&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  27:  &lt;/span&gt;                data +&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  28:  &lt;/span&gt;                Environment.NewLine +&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  29:  &lt;/span&gt;                &lt;span class="str"&gt;&amp;quot;Lectura y escritura realizada.&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  30:  &lt;/span&gt;        } &lt;span class="rem"&gt;// btnSampleTest_Click&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  31:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  32:  &lt;/span&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Read()&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  33:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  34:  &lt;/span&gt;            &lt;span class="rem"&gt;// Abrimos el fichero y leemos su contenido.&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  35:  &lt;/span&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;Texto leido&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  36:  &lt;/span&gt;        } &lt;span class="rem"&gt;// Read&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  37:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  38:  &lt;/span&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Write()&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  39:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  40:  &lt;/span&gt;            &lt;span class="rem"&gt;// Escribimos el fichero en su lugar destino.&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  41:  &lt;/span&gt;        } &lt;span class="rem"&gt;// Write&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  42:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  43:  &lt;/span&gt;    } &lt;span class="rem"&gt;// MainForm&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  44:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  45:  &lt;/span&gt;} // UI_Sample&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Posibles problemas&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;La solución anterior no está mal, sin embargo, puede presentarnos a futuro una serie de problemas que dependiendo de la complejidad del proyecto y otras circunstancias como por ejemplo si el código de nuestra aplicación cambia frecuentemente, etc., puede acarrearnos serios contratiempos.&lt;/p&gt;

&lt;p&gt;Por otro lado, el principal problema que aporta el ejemplo anterior, sería el mantenimiento de la solución propuesta.&lt;/p&gt;

&lt;p&gt;Mezclar lógica e interfaz de usuario debería ponernos los pelos como escarpias de antemano.&lt;/p&gt;

&lt;p&gt;En otro orden de cosas, separar la lógica en una biblioteca de clases para apartarla de la interfaz de usuario, podría resolver parte de este problema, pero se nos presentación otro adicional.&lt;/p&gt;

&lt;p&gt;¿Qué ocurriría si en lugar de querer leer desde un fichero de texto y escribir en un fichero de texto queremos cambiar ese fichero de texto por una hoja Excel?.&lt;/p&gt;

&lt;p&gt;Esto es lo que resolveremos en la siguiente parte del artículo siguiendo con la inercia de desarrollo marcada aquí.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=209040" width="1" height="1"&gt;</content><author><name>jorge</name><uri>http://geeks.ms/members/jorge/default.aspx</uri></author><category term="Arquitectura" scheme="http://geeks.ms/blogs/jorge/archive/tags/Arquitectura/default.aspx" /><category term="C#" scheme="http://geeks.ms/blogs/jorge/archive/tags/C_2300_/default.aspx" /><category term=".NET Framework 4.0" scheme="http://geeks.ms/blogs/jorge/archive/tags/.NET+Framework+4.0/default.aspx" /><category term="Visual Studio 2010" scheme="http://geeks.ms/blogs/jorge/archive/tags/Visual+Studio+2010/default.aspx" /><category term="Microsoft .NET Framework 4.0" scheme="http://geeks.ms/blogs/jorge/archive/tags/Microsoft+.NET+Framework+4.0/default.aspx" /><category term="Microsoft .NET Framework 4.5" scheme="http://geeks.ms/blogs/jorge/archive/tags/Microsoft+.NET+Framework+4.5/default.aspx" /><category term=".NET Framework 4.5" scheme="http://geeks.ms/blogs/jorge/archive/tags/.NET+Framework+4.5/default.aspx" /><category term="Visual Studio 2012" scheme="http://geeks.ms/blogs/jorge/archive/tags/Visual+Studio+2012/default.aspx" /></entry><entry><title>Odiseas, problemas y soluciones en el desbloqueo de un Windows Phone para depurar aplicaciones con Visual Studio</title><link rel="alternate" type="text/html" href="/blogs/jorge/archive/2013/02/13/odiseas-problemas-y-soluciones-en-el-desbloqueo-de-un-windows-phone-para-depurar-aplicaciones-con-visual-studio.aspx" /><id>/blogs/jorge/archive/2013/02/13/odiseas-problemas-y-soluciones-en-el-desbloqueo-de-un-windows-phone-para-depurar-aplicaciones-con-visual-studio.aspx</id><published>2013-02-13T08:00:00Z</published><updated>2013-02-13T08:00:00Z</updated><content type="html">&lt;p&gt;&lt;font color="#c0504d"&gt;&lt;strong&gt;Introducción&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;El título es un poco largo, sí, ya lo sé, pero viene al caso de una serie de problemas que me han ocurrido y que he resuelto uno detrás de otro.&lt;/p&gt;  &lt;p&gt;Comento la situación.&lt;/p&gt;  &lt;p&gt;En mi mano he tenido tres terminales móviles con Windows Phone 7 (un &lt;a href="http://www.lg.com/es/telefonos-moviles/lg-E900-Optimus-7"&gt;LG E900 Windows 7&lt;/a&gt; y dos &lt;a href="http://www.nokia.com/es-es/productos/moviles/lumia800"&gt;Nokia Lumia 800&lt;/a&gt;).    &lt;br /&gt;Ambos han funcionado perfectamente, pero les he hecho alguna que otra perrería como es lógico.    &lt;br /&gt;Entre esas perrerías, reiniciarlos, resetearlos, actualizar firmwares, etc.&lt;/p&gt;  &lt;p&gt;Todos los he registrado y desbloqueado para depurar aplicaciones Windows Phone desde mi &lt;a href="http://www.microsoft.com/visualstudio/eng/products/visual-studio-overview"&gt;Visual Studio&lt;/a&gt;, pero durante todo ese proceso, he cometido algún error que otro que he descubierto ahora y del que aquí expongo la solución.&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;&lt;strong&gt;&lt;font color="#c0504d"&gt;Desbloqueo de un Windows Phone&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Sólo a modo informativo y para aquel que no lo sepa, para desbloquear un Windows Phone y poder depurar aplicaciones Windows Phone en Visual Studio, deberemos desbloquearlo.&lt;/p&gt;  &lt;p&gt;Para desbloquearlo, Microsoft proporciona una aplicación denominada &lt;strong&gt;&lt;em&gt;Windows Phone Developer Registration&lt;/em&gt;&lt;/strong&gt;, que puede ser encontrada en el SDK de Windows Phone 7 ó Windows Phone 8.&lt;/p&gt;  &lt;p&gt;&lt;img src="https://nu1ujg.sn2.livefilestore.com/y1prCzFHzHxnU6yn_SrBbhl6vHSuTPOzczYBe4MS24FRd12Td7BwHZjophmRTwNCM5rt2iH_7MEpMmvZs8dInF_hwZutNKHnCFQ/20130213_01.png?psid=1" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;Esta herramienta detectará si tenemos conectado un Windows Phone 7 ó un Windows Phone 8.&lt;/p&gt;  &lt;p&gt;&lt;img src="https://nu1ujg.sn2.livefilestore.com/y1pOTlM2zTD3WngakwG2ktb_w6u4A15AINurF60N5l1jUIE7EpHX9SpHIqEuJLoPx6eJ-XKnlxIan-qWkYq1r6qrfJlc2AU9974/20130213_02.png?psid=1" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;Al hacer clic sobre registrar nuestro dispositivo, el proceso de desbloqueo se iniciará.&lt;/p&gt;  &lt;p&gt;&lt;img src="https://nu1ujg.sn2.livefilestore.com/y1pOTlM2zTD3Wk_4bUzu66y-DvY6AesGbfNN881bQbUNM3qOzGm67BNOPfTuIhKhTrzOnnCYJi5Hc3JFaMv7qp9fdynO7rArf8Y/20130213_03.png?psid=1" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;Si todo va bien, veremos que aparecerá un mensaje indicándonos que nuestro dispositivo ha sido registrado correctamente, sin embargo y en mi caso, me indica que ya tengo un dispositivo desbloqueado con el mismo nombre.&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;&lt;strong&gt;&lt;font color="#c0504d"&gt;Mi primer error&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Mi primer error ha sido llamar al terminal Nokia Lumia 800 igual que mi antecesor LG E900 Windows 7.   &lt;br /&gt;El LG está de backup ahora mismo, pero fue mi primer Windows Phone y con él he estado trasteando con Visual Studio y demás.&lt;/p&gt;  &lt;p&gt;El hecho es que a la hora de registrar mi dispositivo, la herramienta de desbloqueo detecta, como decía anteriormente, que ya tengo registrado un dispositivo con el mismo nombre.&lt;/p&gt;  &lt;p&gt;¿Cómo resolver este problema?.&lt;/p&gt;  &lt;p&gt;La solución más sencilla no es la más óptima, y consistiría en reiniciar el terminal a fábrica y una vez así, cambiar el nombre del dispositivo. Otra posible solución sería sincronizar con Zune por primera vez el terminal y cambiar el nombre del terminal ahí, pero hay una solución más elegante que veremos a continuación.&lt;/p&gt;  &lt;p&gt;El caso es que si acudimos a la web de Microsoft de Windows Phone (&lt;a href="https://www.windowsphone.com)"&gt;https://www.windowsphone.com)&lt;/a&gt; y accedemos con nuestra cuenta Passport, observaremos que en la sección &lt;strong&gt;&lt;em&gt;Account settings&lt;/em&gt;&lt;/strong&gt; de nuestra cuenta, encontraremos todos los dispositivos registrados para esa cuenta.&lt;/p&gt;  &lt;p&gt;&lt;img src="https://nu1ujg.sn2.livefilestore.com/y1pOTlM2zTD3WngeFh81boUVz-1wCvxwQMn83ubdRPRjzddFZsgLwfgT7iXbbGC0Kv-F6reY37-aGlucapQLfLPBS1647EschfT/20130213_04.png?psid=1" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;Lo sorprendente en mi caso, es que tengo dos dispositivos móviles con el mismo nombre.&lt;/p&gt;  &lt;p&gt;Y claro, no tengo ninguna gana de reiniciar mi terminal a su estado inicial de fábrica.&lt;/p&gt;  &lt;p&gt;Si accedo al terminal, tampoco encuentro dentro ninguna posibilidad para cambiar el nombre de ningún terminal, y en esta web tampoco encuentro nada.&lt;/p&gt;  &lt;p&gt;Bien... pues como decía antes, hay una forma cómoda y elegante para resolver este problema.&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;&lt;font color="#c0504d"&gt;&lt;strong&gt;Solución al primer problema&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;La solución consiste en acudir a &lt;a href="http://www.xbox.com/en-US/Live/Partners/Zune"&gt;Zune&lt;/a&gt;&lt;strong&gt;&lt;em&gt;&lt;/em&gt;&lt;/strong&gt; y dentro de Zune y con el dispositivo conectado (obviamente), ir a &lt;em&gt;&lt;strong&gt;Setting&lt;/strong&gt;&lt;/em&gt; del dispositivo.&lt;/p&gt;  &lt;p&gt;Dentro de la configuración del dispositivo, acudiremos a la opción &lt;strong&gt;&lt;em&gt;&lt;u&gt;NAME YOUR PHONE&lt;/u&gt;&lt;/em&gt;&lt;/strong&gt;, y allí, podremos ver el nombre actual de nuestro dispositivo y cambiar su nombre.&lt;/p&gt;  &lt;p&gt;&lt;img src="https://nu1ujg.sn2.livefilestore.com/y1prCzFHzHxnU5V-f7X_ak21kMBY9pScppeTDiI8KqC4xQZB1d9OLoeTS7seHXfoBrcNizesj8PbHL_PODOG0y_uP31z91LsGyM/20130213_05.png?psid=1" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;Ala,... ya estamos listos para desbloquear nuestro dispositivo móvil, así que volvemos a ejecutar el proceso de la herramienta &lt;em&gt;&lt;strong&gt;Windows Phone Developer Registration&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;&lt;strong&gt;&lt;font color="#c0504d"&gt;Mi segundo error&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Antes comenté que había estado trasteando con diferentes dispositivos móviles y con Visual Studio, así que eso significa que he desbloqueado una gran cantidad de dispositivos móviles con mi cuenta Passport.&lt;/p&gt;  &lt;p&gt;Algo en lo que no he reparado...&lt;/p&gt;  &lt;p&gt;El caso es que después de volver a ejecutar la herramienta de desbloqueo del terminal, me encuentro con otro mensaje nuevo.&lt;/p&gt;  &lt;p&gt;&lt;img src="https://nu1ujg.sn2.livefilestore.com/y1prCzFHzHxnU6xaqUT6cl3ABQq_9kADvWZsFwd4CW4SqKxOTgj0Of_uA85aWjxvnn40i6dHslIIS2gYyijatpDyYJLAlCmBaBP/20130213_06.png?psid=1" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;En este caso, el problema es que tenemos desbloqueados más terminales de los que podemos.&lt;/p&gt;  &lt;p&gt;Así que acudo a la Web anterior y trato de eliminar aquellos terminales que ya no uso dentro de la sección &lt;em&gt;&lt;strong&gt;Account settings&lt;/strong&gt;&lt;/em&gt;, y vuelvo a intentarlo, pero nada... sigo en las mismas.&lt;/p&gt;  &lt;p&gt;Sin embargo, y una vez más... hay solución y no es esta última, sino otra nueva y diferente. ;)&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;&lt;strong&gt;&lt;font color="#c0504d"&gt;Solución al segundo problema&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;La solución a este segundo problema no reside en ir a la Web que indicaba anteriormente, sino en ir a otra Web diferente que desde mediados del año 2012, sustituye al App Hub de Microsoft.&lt;/p&gt;  &lt;p&gt;Esta Web es la web de desarrollo de Windows Phone (&lt;a href="https://dev.windowsphone.com)"&gt;https://dev.windowsphone.com)&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;En esta web podemos subir nuestras aplicaciones Windows Phone, descargar el SDK para desarrollar aplicaciones Windows Phone, y acceder a los detalles de nuestra cuenta.&lt;/p&gt;  &lt;p&gt;Allí debemos registrar a nuestra cuenta y a la subsección &lt;strong&gt;&lt;em&gt;Phones&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;Si nos fijamos bien en esa web pone: &amp;quot;&lt;em&gt;&lt;strong&gt;Maximum number of phones you can register: 3&lt;/strong&gt;&lt;/em&gt;&amp;quot;.&lt;/p&gt;  &lt;p&gt;En caso es que yo tenía 3 terminales ya registrados y 2 de ellos anticuados, así que he eliminado dos de ellos y he vuelto a intentar ejecutar la herramienta de desbloqueo &lt;strong&gt;&lt;em&gt;Windows Phone Developer Registration&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;Ahora sí, el terminal se ha desbloqueado perfectamente.&lt;/p&gt;  &lt;p&gt;&lt;img src="https://nu1ujg.sn2.livefilestore.com/y1prCzFHzHxnU5PL3BfDNXdmR3k3w4oFSHvwcLt78cORNkBkwF4xrCP9pwFqU79lvdG7LsWFLLV4CiyQFKJId-tlaHLGTWfqwpX/20130213_07.png?psid=1" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;Y si nos fijamos en la sección anterior, veremos que nuestro terminal se ha registrado correctamente.&lt;/p&gt;  &lt;p&gt;&lt;img src="https://nu1ujg.sn2.livefilestore.com/y1prCzFHzHxnU5tdr0hZe18N1EmQDAlj79h1jV0C3UjedRMSpgjNkhCNfhxAW2NyO_BAG9X1MpFXu8ECg8oVdLtPjwAyE-lsDGx/20130213_08.png?psid=1" width="844" height="183" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;De hecho, podemos fijarnos en otra columna de datos de esa sección que indica si ha expirado la fecha de desbloqueo o no, para reiniciar el proceso de desbloqueo en ese terminal (en mi caso tengo ya un terminal con fecha expirada tal y como se puede observar).&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;Espero que todo esto le ayude a alguien que se encuentre con estos problemas o problemas parecidos.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=208548" width="1" height="1"&gt;</content><author><name>jorge</name><uri>http://geeks.ms/members/jorge/default.aspx</uri></author><category term="Windows Phone 7" scheme="http://geeks.ms/blogs/jorge/archive/tags/Windows+Phone+7/default.aspx" /><category term="Windows Phone 8" scheme="http://geeks.ms/blogs/jorge/archive/tags/Windows+Phone+8/default.aspx" /></entry><entry><title>Lavando la cara de mi Microsoft Xbox 360 Wireless Racing Wheel</title><link rel="alternate" type="text/html" href="/blogs/jorge/archive/2013/02/05/lavando-la-cara-de-mi-microsoft-xbox-360-wireless-racing-wheel.aspx" /><id>/blogs/jorge/archive/2013/02/05/lavando-la-cara-de-mi-microsoft-xbox-360-wireless-racing-wheel.aspx</id><published>2013-02-05T19:00:00Z</published><updated>2013-02-05T19:00:00Z</updated><content type="html">&lt;p&gt;&lt;span style="color:#c0504d;"&gt;&lt;strong&gt;&lt;img src="http://images.businessweek.com/ss/08/07/0717_idea_winners/image/s_xbox.jpg" alt="" /&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#c0504d;"&gt;&lt;strong&gt;Introducci&amp;oacute;n&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;A los que nos gusta los juegos de coches y la &lt;a href="http://www.xbox.com"&gt;Xbox&lt;/a&gt;, casi se nos hace indispensable disponer de un mando que nos haga vivir con mayor realismo todo lo que acontece en esos juegos.&lt;/p&gt;
&lt;p&gt;Una buena forma de lograr ese realismo sin llegar a unas cotas excesivamente frikis, es adquiriendo un volante.&lt;/p&gt;
&lt;p&gt;La entrada de hoy es un poco friky, y trata sobre una experiencia personal y como lo he solucionado por si a alguien m&amp;aacute;s le pasa y no sabe o no se atreve a hacer lo que yo he hecho.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#c0504d;"&gt;&lt;strong&gt;Tipos de volantes&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Dentro del amplio abanico de volantes que hay en el mercado para las consolas Xbox, hay algunos modelos que poseen &lt;em&gt;&lt;a href="http://es.wikipedia.org/wiki/Controlador_de_videojuego"&gt;force feedback&lt;/a&gt;&lt;/em&gt; y otros no. Mi consejo es que para tener una sensaci&amp;oacute;n m&amp;aacute;s realista en la conducci&amp;oacute;n, vayas a por un volante con &lt;em&gt;force feedback&lt;/em&gt;. Notar&amp;aacute;s la diferencia.&lt;/p&gt;
&lt;p&gt;Y dentro del mercado de volantes (los que tienen &lt;em&gt;force feedback&lt;/em&gt; y los que no), los hay desde &lt;a href="http://www.amazon.es/Super-Sports-Steering-Importaci%C3%B3n-inglesa/dp/B004EBUI6W/ref=sr_1_3?s=videogames&amp;amp;ie=UTF8&amp;amp;qid=1360075557&amp;amp;sr=1-3"&gt;aproximadamente unos 60 &amp;euro;&lt;/a&gt; hasta los nada menos que &lt;a href="http://eu.fanatec.com/RacingWheels/Forza%20Motorsport%20CSR%20Elite%20Wheel%20EU"&gt;600 &amp;euro; dependiendo del acabado y calidad&lt;/a&gt;, y todo esto, sin contar con los asientos, soportes y pantallas donde nos tendr&amp;iacute;amos que rascar del bolsillo &lt;a href="http://eu.fanatec.com/Stand/RennSport%20Cockpit%20EU"&gt;desde 1200 &amp;euro;&lt;/a&gt; s&amp;oacute;lo en asiento y soportes, hasta arriba sumando a esa cantidad las televisiones o monitores aparte.&lt;/p&gt;
&lt;p&gt;Pero si tienes dinero pero no sabes por donde empezar, no te preocupes,&amp;hellip; &lt;a href="http://eu.fanatec.com/index.php?route=module/configurator"&gt;lo tienes f&amp;aacute;cil con este configurador que te facilitar&amp;aacute; la tarea de elegir todo lo que quieras&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Pero para los que no estamos sobrados de dinero y so&amp;ntilde;amos con una loter&amp;iacute;a para lograr ese sue&amp;ntilde;o, debemos ser m&amp;aacute;s modestos, como el ya desaparecido &lt;a href="http://www.hrtf1team.com/es/"&gt;HRT F1 Team&lt;/a&gt; y buscar piezas de segunda mano y dejarlas lo m&amp;aacute;s vistosas posibles para que hagan su funci&amp;oacute;n de entretenimiento.&lt;/p&gt;
&lt;p&gt;As&amp;iacute; que puesto que la primera premisa no la cumplo (el dinero), tendr&amp;eacute; que buscar algo m&amp;aacute;s adecuado a mi econom&amp;iacute;a.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#c0504d;"&gt;&lt;strong&gt;El volante que he decidido comprar&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Para ello, hay en el mercado un tipo de volante muy perseguido por su calidad/precio. Hablo del volante oficial de Microsoft (el que indico en la portada de esta entrada y que se llama &lt;em&gt;&lt;strong&gt;Microsoft Xbox 360 Wireless Racing Wheel&lt;/strong&gt;&lt;/em&gt;),&amp;hellip; sin embargo, ese volante fue descatalogado por Microsoft y su fabricaci&amp;oacute;n es inexistente (&lt;em&gt;tanta imitaci&amp;oacute;n de tableta y similar y &amp;iquest;porqu&amp;eacute; los chinos no se han puesto con esto?&lt;/em&gt;).&lt;/p&gt;
&lt;p&gt;He buscado y buscado, y est&amp;aacute; o agotado en todos los sitios y sin espera de stock por parte del fabricante, o a unos precios tan prohibitivos que casi me sale mejor pedir un cr&amp;eacute;dito al banco (si me lo diera) y optar por la soluci&amp;oacute;n cara que expon&amp;iacute;a anteriormente.&lt;/p&gt;
&lt;p&gt;Desconozco porqu&amp;eacute; Microsoft decidi&amp;oacute; no seguir con la fabricaci&amp;oacute;n de ese volante. Quiz&amp;aacute;s quisiera publicitar &amp;uacute;nicamente la Xbox entre los amantes de los juegos de conducci&amp;oacute;n y el volante no saliera rentable, pero son/somos muchos los que lo hubi&amp;eacute;ramos comprado nuevo hoy.&lt;/p&gt;
&lt;p&gt;Como ese no es el caso y es imposible comprarlo nuevo, siempre hay un sitio en el que buscar&amp;hellip; y no, no es ning&amp;uacute;n estercolero o basurero, sino el mercado de segunda mano donde los precios rondan entre los 75 &amp;euro; y los 120 &amp;euro; en Espa&amp;ntilde;a, hasta por 400 &amp;euro; fuera de Espa&amp;ntilde;a (en eBay por ejemplo).&lt;/p&gt;
&lt;p&gt;Personalmente considero un precio de 100 &amp;euro; caro, as&amp;iacute; que ya no digo nada con respecto a los 120 &amp;euro;, mientras que el precio entre 75 &amp;euro; y 90 &amp;euro; lo considero un precio justo, aceptable y acorde al mercado con respecto a un producto obsoleto ya.&lt;/p&gt;
&lt;p&gt;S&amp;eacute; que este volante lleg&amp;oacute; a costar algo m&amp;aacute;s de 200 &amp;euro; en su tiempo, pero han pasado 4 a&amp;ntilde;os y ya no vale eso, y menos con el uso que algunas personas les da a los volantes.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#c0504d;"&gt;&lt;strong&gt;Mi volante&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;En mi caso, me han ofrecido el volante por 120 &amp;euro; (no me ha interesado a ese precio), y m&amp;aacute;s barato que esa cantidad. Al final he obtenido uno que me ha parecido tener un precio razonable dentro del baremo normal.&lt;/p&gt;
&lt;p&gt;Sin embargo, este tipo de hardware tiene un problema. Su uso. O mejor dicho, el uso que le haya dado el due&amp;ntilde;o.&lt;/p&gt;
&lt;p&gt;El que he comprado tiene el volante en bastante buenas condiciones.&lt;/p&gt;
&lt;p&gt;El soporte que acopla el volante a la mesa tambi&amp;eacute;n estaba en buenas condiciones.&lt;/p&gt;
&lt;p&gt;Pero la pedalera&amp;hellip; bueno, en realidad el pl&amp;aacute;stico que recubre alrededor a los pedales, estaba ara&amp;ntilde;ado e incluso manchado de rotulador rojo y negro.&lt;/p&gt;
&lt;p&gt;Entiendo como normal que la gente que acostumbra a vender las cosas de segunda mano, le da un lavado global o superficial al producto para que la entrega est&amp;eacute; vistosa, pero en mi caso, me lleg&amp;oacute; que daba pena verlo. Quiz&amp;aacute;s sea muy exigente, pero realmente no era lo que me esperaba porque denota poca seriedad por parte del vendedor.&lt;/p&gt;
&lt;p&gt;Estuve a punto de devolverlo pero decid&amp;iacute; qued&amp;aacute;rmelo.&lt;/p&gt;
&lt;p&gt;Sin embargo, ni el volante ni el soporte ni los pedales, ten&amp;iacute;an el aspecto est&amp;eacute;tico que me gustar&amp;iacute;a que tuviera, as&amp;iacute; que me puse a limpiarlo de pegotes de pintura, polvo y suciedad t&amp;iacute;pica de haberlo tenido en un trastero, descuidado o haber soportado las inclemencias de una obra.&lt;/p&gt;
&lt;p&gt;Lamentablemente no hice fotos del estado inicial, pero tengo testigos que pueden corroborar lo que comento.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#c0504d;"&gt;&lt;strong&gt;Limpieza&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Lo primero que hice fue limpiar el volante, los cables, el soporte que une el volante a la mesa y los pedales.&lt;/p&gt;
&lt;p&gt;Para ello, hice una visita al chino del barrio y por 6,5 &amp;euro; adquir&amp;iacute; todo esto:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://b0svjq.sn2.livefilestore.com/y1pOTep0lSNd8PB4D9flvwSH1e3gXMd9ZElvKtOgfDGWduAUDpCdu1U9sSyMaznu0CHyxM_iOXtG69imXpYiK7kdbBAZ_1Inwuv/20130205_02.png?psid=1" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;El contenido es muy simple:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Un bote de alcohol.&lt;/li&gt;
&lt;li&gt;Algodones.&lt;/li&gt;
&lt;li&gt;Toallitas de beb&amp;eacute;.&lt;/li&gt;
&lt;li&gt;Protectores adhesivos para la base de los pedales a la hora de ponerlo al suelo (faltaban dos de los cinco que tiene de f&amp;aacute;brica).&lt;/li&gt;
&lt;li&gt;Pintura blanca para pl&amp;aacute;sticos.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Para esta primera fase, utilic&amp;eacute; todo menos los protectores adhesivos y la pintura.&lt;/p&gt;
&lt;p&gt;Lo que hice fue limpiar todas el hardware de modo que quedara lo m&amp;aacute;s limpio posible, quitando restos de pintura, rotulador y alg&amp;uacute;n que otro resto de suciedad.&lt;/p&gt;
&lt;p&gt;Una vez finalizado todo el proceso, todo el hardware qued&amp;oacute; bastante limpio y saneado.&lt;/p&gt;
&lt;p&gt;La primera fase la repet&amp;iacute; unas cuantas veces.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#c0504d;"&gt;&lt;strong&gt;Fase de pintado&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;En la fase de pintado me he decantado por la utilizaci&amp;oacute;n de un spray de color blanco mate, en esmalte sint&amp;eacute;tico y con c&amp;oacute;digo de color 9010.&lt;/p&gt;
&lt;p&gt;Mi bote de pintura lo pod&amp;eacute;is encontrar &lt;a href="http://www.novasolspray.com/"&gt;en esta web&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Y &lt;a href="http://www.novasolspray.com/html/prod%20pinturas%20sintetica%20mate.html"&gt;m&amp;aacute;s concretamente aqu&amp;iacute;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;El objetivo, pintar el borde blanco que recubre a los pedales que es la parte que estaba ara&amp;ntilde;ada del uso.&lt;/p&gt;
&lt;p&gt;Para llevar acabo esta tarea, he puesto cinta adhesiva en la zona gris de los pedales y he cubierto los pedales para que a la hora de pintar con el spray no se pinten de blanco claro est&amp;aacute;.&lt;/p&gt;
&lt;p&gt;Despu&amp;eacute;s de una primera mano de pintura, el aspecto de esta parte era este:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://b0svjq.sn2.livefilestore.com/y1pgctVjL2E8vSptSf6P2PPtih85fUrmEmfwBFzjA2Y1ZI1Ok4IG34oK7atxpBvMDwimE8iDulw2Z0x4qeGo2MiqkJ6detaFJGJ/20130205_01.png?psid=1" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Sin embargo, le he dado hasta 4 manos de pintura con el spray con el fin de que la pintura refuerce m&amp;aacute;s su acoplamiento a la base de pl&amp;aacute;stico.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#c0504d;"&gt;&lt;strong&gt;Fase de fijaci&amp;oacute;n&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Sin embargo, el proceso no finaliza con la fase de pintado, as&amp;iacute; que se requiere dar el punto definitivo de fijaci&amp;oacute;n, algo que he dado con un spray de barniz acr&amp;iacute;lico satinado que me ha costado 2,5 &amp;euro; m&amp;aacute;s.&lt;/p&gt;
&lt;p&gt;En concreto, el que he usado es este:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://b0svjq.sn2.livefilestore.com/y1peBt96rhg92Jl_S7q2_FAByOsGkhaolJHWrnEJHuwji6ahMDHGtaShW2800Dr-hRL9q6vdxqiJsPpTIBURUMsgsKG2FrjKfU8/20130205_03.png?psid=1" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Se trata de un barniz satinado con c&amp;oacute;digo S199 que sino estoy equivocado, es el que &lt;a href="http://www.novasolspray.com/html/prod%20pinturas%20sintetica%20satinada.html"&gt;equivale a este en la web del fabricante&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Despu&amp;eacute;s de repetir la operaci&amp;oacute;n de barnizado sobre la superficie de dos a tres veces, el resultado es este:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://b0svjq.sn2.livefilestore.com/y1pz_UPEebTZ-KthcmIH8TtQGWA-NnhOjmGYMLDjrXVIg4enYayHsn192G7LPM6TlNuq_5f8YyqfXURpNbhAm8XsArrodEPC4L2/20130205_04.png?psid=1" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Realmente se aprecia poco en la imagen y aprecia mucho mejor en la realidad.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#c0504d;"&gt;&lt;strong&gt;El resultado final&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;De hecho, uno de los errores que se tienen a la hora de comprar este tipo de volantes (lo aviso para que a otros no les pase), es que las fotos que te env&amp;iacute;an los vendedores respecto a este producto enga&amp;ntilde;an con respecto a la realidad, y una cosa es la imagen que te env&amp;iacute;an y otra la de verdad, la que ves t&amp;uacute; con tus propios ojos que es cuando ves lo detalles.&lt;/p&gt;
&lt;p&gt;El vendedor no me envi&amp;oacute; ninguna foto trucada, pero l&amp;oacute;gicamente no se apreciaban bien los detalles del poco cuidado que se tuvo y el &lt;em&gt;flashazo&lt;/em&gt; no ayuda a detectar esos detalles (fallo m&amp;iacute;o).&lt;/p&gt;
&lt;p&gt;Tanto es as&amp;iacute;, que la imagen que me envi&amp;oacute; el vendedor de los pedales era esta:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://b0svjq.sn2.livefilestore.com/y1pjCKzykjs2TTwVSe4AHE3dxq8rpMpROKTQg-pqWjphvCf-yfNF7WdR7qkyAwEcoNyQW2I5JUjcMZLkLagSv1PLD3Al7QSDs7o/20130205_05.png?psid=1" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Y ah&amp;iacute; no se muestran ni las manchas ni churretes que ten&amp;iacute;a, ni los pintarrajos rojos y negros, ni los ara&amp;ntilde;azos. A simple vista parece que estaba todo ok, pero no era as&amp;iacute; (volvedme a llamar meticuloso).&lt;/p&gt;
&lt;p&gt;Pero nada que dos o tres pasadas de algod&amp;oacute;n con alcohol y toallitas de beb&amp;eacute; no quiten, pero claro&amp;hellip; siempre te llevas un poco de decepci&amp;oacute;n por no haber recibido toda la informaci&amp;oacute;n sobre el estado del producto.&lt;/p&gt;
&lt;p&gt;El caso es que ese es el antes, y aqu&amp;iacute; va el despu&amp;eacute;s de todo el proceso de limpiado y fijaci&amp;oacute;n:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://b0svjq.sn2.livefilestore.com/y1pxR_zWnE9_Vq-jPU530bfwh4lR6I4NK_xJds_nLCi7HNf2UzShWBOxG8pXWFpjIZGljKBZ8Wr7d_i_rFafA9TYzspMIVwVCY2/20130205_06.png?psid=1" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Como se puede apreciar, el aspecto es mucho m&amp;aacute;s vistoso.&lt;/p&gt;
&lt;p&gt;Un detalle principal del logo de Xbox 360 para que se vea algo de detalle del proceso finalizado:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://b0svjq.sn2.livefilestore.com/y1pX2X1ML0ObWf0e_kkDLkLc3rp6opvSHryGFIMbNXB_qchgiD3KVFCs5uNlCLtPl7GnRxnyppxLoEVwo0ujpYgRnEKfCH9hCM3/20130205_07.png?psid=1" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#c0504d;"&gt;&lt;strong&gt;Mejoras&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Sin embargo, creo que el proceso puede mejorarse.&lt;/p&gt;
&lt;p&gt;En mi caso no soy ning&amp;uacute;n experto en todo esto, y alguna motita de polvo se ha alojado a la pintura.&lt;/p&gt;
&lt;p&gt;La idea es hacer esto en un lugar seco y cerrado, pero yo lo he hecho en un lugar abierto y con viento, as&amp;iacute; que reconozco que no lo he hecho en las mejores condiciones. A&amp;uacute;n y as&amp;iacute;, no lo quiero para ninguna exposici&amp;oacute;n, y seguramente ensucie el soporte una vez apoye sobre &amp;eacute;l mis pezu&amp;ntilde;as.&lt;/p&gt;
&lt;p&gt;El resultado no obstante ha sido m&amp;aacute;s que satisfactorio, sin embargo, la base de barniz que le he aplicado no me termina de convencer, y si dejo el dedo apretado unos segundos se marca un poco la huella dactilar con el efecto de la presi&amp;oacute;n y el calor del dedo. Como estoy escribiendo esta entrada a las pocas horas de haber finalizado el proceso, es posible que le falte reposo o bien que necesite un tipo de barniz diferente.&lt;/p&gt;
&lt;p&gt;No obstante, la huella dactilar la he quitado f&amp;aacute;cilmente con un algod&amp;oacute;n humedecido muy muy poco en alcohol, pero sigo pensando en que el proceso necesita una mejora o simplemente tiempo. Eso lo ver&amp;eacute; en los pr&amp;oacute;ximos d&amp;iacute;as.&lt;/p&gt;
&lt;p&gt;Espero que le sirva a alguien mi experiencia.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=208484" width="1" height="1"&gt;</content><author><name>jorge</name><uri>http://geeks.ms/members/jorge/default.aspx</uri></author><category term="Xbox" scheme="http://geeks.ms/blogs/jorge/archive/tags/Xbox/default.aspx" /></entry><entry><title>Windows 8 wireframes o prototipar rápidamente nuestras aplicaciones</title><link rel="alternate" type="text/html" href="/blogs/jorge/archive/2013/02/03/windows-8-wireframes-o-prototipar-r-225-pidamente-nuestras-aplicaciones.aspx" /><id>/blogs/jorge/archive/2013/02/03/windows-8-wireframes-o-prototipar-r-225-pidamente-nuestras-aplicaciones.aspx</id><published>2013-02-03T18:00:00Z</published><updated>2013-02-03T18:00:00Z</updated><content type="html">&lt;p&gt;&lt;strong&gt;&lt;span style="color:#c0504d;"&gt;&lt;img src="http://cdn.designmodo.com/wp-content/uploads/2012/11/slide-07-common-controls-1.png" alt="" /&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="color:#c0504d;"&gt;Introducci&amp;oacute;n&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A la hora de dise&amp;ntilde;ar nuestras aplicaciones en Windows 8, es posible que nos encontremos con la necesidad de preparar una maqueta de estilos y formas respecto a nuestra aplicaci&amp;oacute;n. Lo que vulgarmente se denomina prototipo (en su fase inicial).&lt;/p&gt;
&lt;p&gt;Como todos sabemos, lo ideal es hacer un fake, pero muchas veces y para ganar tiempo, es preciso hacer o preparar unos wireframes o prototipos que compartiremos con nuestro equipo de trabajo (desarrollo + UX).&lt;/p&gt;
&lt;p&gt;Sin embargo, en muchas ocasiones se nos pide incluso m&amp;aacute;s flexibilidad y menos tiempo para hacer o preparar grandes florituras, es decir,&amp;hellip; hacernos una idea r&amp;aacute;pida de como va a ser nuestra aplicaci&amp;oacute;n. &lt;/p&gt;
&lt;p&gt;&amp;iquest;C&amp;oacute;mo salir adelante cuando los plazos aprietan, y se pide flexibilidad y rapidez en la toma de decisiones?.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#c0504d;"&gt;&lt;strong&gt;Wireframe templates para PowerPoint&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;S&amp;iacute;, no me he vuelto loco.&lt;/p&gt;
&lt;p&gt;Si se nos pide flexibilidad y rapidez a la hora de discutir con el cliente o con el equipo como podr&amp;iacute;a ser nuestra aplicaci&amp;oacute;n Windows 8, no lo dudemos&amp;hellip; hacerlo con el Notepad quedar&amp;aacute; m&amp;aacute;s cool, pero nos llevar&amp;aacute; mucho m&amp;aacute;s trabajo, y hacerlo con Visio y PowerPoint nos quedar&amp;aacute; muy vistoso, no ser&amp;aacute; tan friky pero nos llevar&amp;aacute; mucho menos tiempo.&lt;/p&gt;
&lt;p&gt;En este caso, vamos a utilizar PowerPoint, y para ello, unas plantillas gratuitas que generosamente nos ofrece &lt;a href="http://www.powermockup.com/"&gt;Andreas Wulf&lt;/a&gt; y &lt;a href="http://modernuiicons.com/"&gt;Austin Andrews&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Estas plantillas las podr&amp;aacute;s encontrar &lt;a href="http://designmodo.com/windows-8-wireframe/"&gt;en este enlace&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Espero que sean de utilidad.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=208470" width="1" height="1"&gt;</content><author><name>jorge</name><uri>http://geeks.ms/members/jorge/default.aspx</uri></author><category term="Windows 8" scheme="http://geeks.ms/blogs/jorge/archive/tags/Windows+8/default.aspx" /></entry><entry><title>Usando SQL Database Migration Wizard para pasar una base de datos de SQL Server a SQL Azure</title><link rel="alternate" type="text/html" href="/blogs/jorge/archive/2013/02/01/usando-sql-database-migration-wizard-para-pasar-una-base-de-datos-de-sql-server-a-sql-azure.aspx" /><id>/blogs/jorge/archive/2013/02/01/usando-sql-database-migration-wizard-para-pasar-una-base-de-datos-de-sql-server-a-sql-azure.aspx</id><published>2013-02-01T16:30:00Z</published><updated>2013-02-01T16:30:00Z</updated><content type="html">&lt;p&gt;&lt;strong&gt;&lt;span style="color:#c0504d;"&gt;Introducci&amp;oacute;n&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Cuando deseamos migrar una base de datos de SQL Server a SQL Azure, experimentaremos diferentes fases de sentimientos encontrados, y es que pasar estructuras de tablas, relaciones, datos maestros y otras partes, desde una base de datos SQL Server a SQL Azure no es tarea f&amp;aacute;cil.&lt;/p&gt;
&lt;p&gt;Sin embargo, tenemos una herramienta que nos va a facilitar enormemente las cosas para que esa transici&amp;oacute;n y esa carga sea lo menos pesada posible y s&amp;iacute; lo m&amp;aacute;s liviana y ligera posible.&lt;/p&gt;
&lt;p&gt;Esta herramienta es SQL Database MW o SQL Database Migration Wizard si se desea emplear el nombre largo de la misma.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="color:#c0504d;"&gt;&amp;iquest;Qu&amp;eacute; es SQL Database MW?&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Esta herramienta gratuita nos facilitar&amp;aacute; la tarea de migrar bases de datos en SQL Server 2005, 2008 y 2012 a SQL Azure.&lt;/p&gt;
&lt;p&gt;Existen dos versiones:&lt;/p&gt;
&lt;p&gt;SQL Database Migration Wizard v3.x.x que requiere SQL Server 2008 R2 SP1.&lt;/p&gt;
&lt;p&gt;SQL Database Migration Wizard v4.x.x que requiere SQL Server 2012.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="color:#c0504d;"&gt;&amp;iquest;D&amp;oacute;nde localizar SQL Database MW?&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Esta herramienta la podemos localizar en &lt;a href="http://sqlazuremw.codeplex.com/"&gt;codeplex&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#c0504d;"&gt;&lt;strong&gt;Ejecutando la herramienta&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Lo primero que tenemos que hacer, es descargar los binarios de la herramienta y descomprimir los archivos de la misma en una carpeta.&lt;/p&gt;
&lt;p&gt;Una vez hecho esto, ejecutaremos la aplicaci&amp;oacute;n (en mi caso, la versi&amp;oacute;n 3.9.9.1 y el fichero &lt;em&gt;SQLAzureMW.exe&lt;/em&gt;).&lt;/p&gt;
&lt;p&gt;La aplicaci&amp;oacute;n se mostrar&amp;aacute; en una ventana similar a la siguiente:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://1na2ja.sn2.livefilestore.com/y1pbbqLi43UQiIZ_fknkhiW3qiJ1J2waxMVCtv5pk0Jg7AK1I9w-yLUCNqrbOHLU--foVrTRSUNDCjPLJByLtk7I8ubpwi9c_Uj/20130201_01.png?psid=1" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;En nuestro caso, voy a migrar una tabla con datos de SQL Server a SQL Azure para lo cual, seleccionar&amp;eacute; la opci&amp;oacute;n de&lt;strong&gt; Analyze/Migrate&lt;/strong&gt; y en concreto, la primera opci&amp;oacute;n &lt;strong&gt;Database&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://1na2ja.sn2.livefilestore.com/y1pbbqLi43UQiLsYuk3T96DYPDMyEeAHdIhhAOkCq3HDBltlxQ3MEDzv1jLKonM7-wWMR0L5jXC20lANRakS5qS9KJfYcDPgiAh/20130201_02.png?psid=1" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;A continuaci&amp;oacute;n, pulsaremos el bot&amp;oacute;n &lt;strong&gt;Next&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Una vez hecho esto, aparecer&amp;aacute; una ventana para establecer la conexi&amp;oacute;n con la fuente origen de datos.&lt;/p&gt;
&lt;p&gt;Seleccionaremos el servidor y las caracter&amp;iacute;sticas de conexi&amp;oacute;n correspondientes.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://1na2ja.sn2.livefilestore.com/y1pw0CPFXmq6QJsqb7Gnw80kkMs7ZqLUaknn9zXvG7ps3lIXBCDwI4o2kXYGQHHko1TBRBMtm3ML5A-6_KA4m4XCP8oHkInvK9z/20130201_03.png?psid=1" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Como se puede apreciar, adicionalmente he decidido indicarle a la herramienta, que me muestre todas las bases de datos de dicha conexi&amp;oacute;n para indicarle la que quiero migrar.&lt;/p&gt;
&lt;p&gt;Otra opci&amp;oacute;n es seleccionar la opci&amp;oacute;n &lt;strong&gt;Specify Database&lt;/strong&gt; para indicarle el nombre concreto de la base de datos, pero la opci&amp;oacute;n &lt;strong&gt;Master DB&lt;/strong&gt; es la opci&amp;oacute;n m&amp;aacute;s c&amp;oacute;moda.&lt;/p&gt;
&lt;p&gt;Estableceremos la conexi&amp;oacute;n pulsando el bot&amp;oacute;n &lt;strong&gt;Connect&lt;/strong&gt; y aparecer&amp;aacute; una nueva ventana con el listado de todas las bases de datos.&lt;/p&gt;
&lt;p&gt;Seleccionaremos la que queremos migrar.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://1na2ja.sn2.livefilestore.com/y1pvga7svAKPkj7DeZO3Qe0_bBywsGiH4BpHFsvAYXQp7qj6kAyIS8kHxgY9BelI-ETRM4Jz0z229CzlNdtaoOTF92Rjw-7jJQL/20130201_04.png?psid=1" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Pulsaremos el bot&amp;oacute;n &lt;strong&gt;Next&lt;/strong&gt; para continuar.&lt;/p&gt;
&lt;p&gt;Aparecer&amp;aacute; una nueva ventana que nos permitir&amp;aacute; seleccionar las partes de objetos de SQL Server que queremos migrar.&lt;/p&gt;
&lt;p&gt;En principio y para mi prueba, he decidido seleccionar todos los objetos.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://1na2ja.sn2.livefilestore.com/y1pvga7svAKPki2sC78eeTUcRD9cX7RbPthWk69ozYYZsiukVdVZFefZRgqYd2-41zL0nQndVEkD3lzqkJRgADaC0sJGnBaW7u_/20130201_05.png?psid=1" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Una vez resuelto este punto, volveremos a pulsar el bot&amp;oacute;n &lt;strong&gt;Next&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Aparecer&amp;aacute; entonces, una nueva ventana con un resumen de los objetos seleccionados anteriormente.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://1na2ja.sn2.livefilestore.com/y1pvga7svAKPkgjOe1AxmLSsz97X-BAGNr3jYcQpHPP1LZlClCe1LKaBc_ogRjD-otcPjk9noyk6Quc6r3YXPzn64J6SfxrjmX9/20130201_06.png?psid=1" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Una vez m&amp;aacute;s, pulsaremos el bot&amp;oacute;n &lt;strong&gt;Next&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Aparecer&amp;aacute; una ventana de di&amp;aacute;logo que nos preguntar&amp;aacute; si deseamos crear el script o no.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://1na2ja.sn2.livefilestore.com/y1pxgwpjuI1xonZu5bQZPGK9rzxUitx-g9iHm4Nzj9F3Zfnpbq1O4Ziztj8fZk5NUWR7qJCjF4WnWMn97Zc4geBae9uGLIg9lqo/20130201_07.png?psid=1" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Pulsamos afirmativamente y la herramienta empezar&amp;aacute; a preparar el script por nosotros.&lt;/p&gt;
&lt;p&gt;Una vez finalice el proceso, podremos revisar el informe de generaci&amp;oacute;n del script y el script en s&amp;iacute;.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://1na2ja.sn2.livefilestore.com/y1p4WBTRpOxgwBY43UXongN3bk6bmnAivQsdovns0E-WRo3TMuEOZxropk99vY-n3DyZcyD-BK6zBesK8sNRLrj-NMEtLOz-ppJ/20130201_08.png?psid=1" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Si queremos, podemos guardar esta informaci&amp;oacute;n o pasar de ella como voy a hacer yo en esta demostraci&amp;oacute;n.&lt;/p&gt;
&lt;p&gt;Como todo el rato hasta ahora, volveremos a pulsar el bot&amp;oacute;n &lt;strong&gt;Next&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;En este momento, seleccionaremos la conexi&amp;oacute;n destino con nuestra base de datos SQL Azure y estableceremos la conexi&amp;oacute;n correspondiente al igual que hicimos para el origen de datos en SQL Server.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://1na2ja.sn2.livefilestore.com/y1p4WBTRpOxgwD2QsTOLpnO_lWI0zlJKglo5juB_zLL16DoAXsg3vfmw-X3i0Wy_Wv3Y9eOA5p32vLkzYKcsMIOxp3i9riTd4cf/20130201_09.png?psid=1" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Una vez que hemos indicado los datos de conexi&amp;oacute;n con SQL Azure correspondientes, haremos clic en el bot&amp;oacute;n &lt;strong&gt;Connect&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Si todo ha ido tal y como se espera, la aplicaci&amp;oacute;n nos mostrar&amp;aacute; un listado de las bases de datos de SQL Azure.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://1na2ja.sn2.livefilestore.com/y1pWVh-erylPVPi7bxu5wedkuNglxxMrmwvsWwCd3J7GpmGFkafV-ZaO30jq3-seEWjDqlMgtaPEGs3DajtQxIyPhRDs-WOR78S/20130201_10.png?psid=1" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;La base de datos ya la tengo creada y lo que voy a hacer es pasar las tablas de SQL Server a SQL Azure, as&amp;iacute; como sus datos, etc.&lt;/p&gt;
&lt;p&gt;Por lo tanto, una vez seleccionada la base de datos del listado anterior, haremos clic en el bot&amp;oacute;n &lt;strong&gt;Next&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Aparecer&amp;aacute; una ventana de notificaci&amp;oacute;n pregunt&amp;aacute;ndonos si queremos ejecutar el script contra el servidor de SQL destino (nuestro SQL Azure), a lo que responderemos afirmativamente.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://1na2ja.sn2.livefilestore.com/y1plPe3yy1bcHssrV0k8H1Lfc0fP5g8nl6myWm8iuV0v2H1EEwVdRFrKU9oKZs_u2VEGgjze-WsAws3quyCXoSNF5GiSH_7OHJb/20130201_11.png?psid=1" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;El proceso de migraci&amp;oacute;n dar&amp;aacute; comienzo y se empezar&amp;aacute;n a pasar datos.&lt;/p&gt;
&lt;p&gt;Si todo va bien, el proceso finalizar&amp;aacute; sin ning&amp;uacute;n error despu&amp;eacute;s de unos minutos.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://1na2ja.sn2.livefilestore.com/y1pbIVBEBAY5-FrVQqlijdiSmqy6MEQKK4W_SWL2vAeQW1cZzYQ401WJ2ctGxJiwdNSYCqoBcveOL12KkWPqUdt2oczye-HYTur/20130201_12.png?psid=1" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Ya solamente tenemos que hacer clic en el bot&amp;oacute;n &lt;strong&gt;Exit&lt;/strong&gt; para cerrar la aplicaci&amp;oacute;n.&lt;/p&gt;
&lt;p&gt;Como vemos, se trata de una herramienta muy sencilla de utilizar y que nos ahorra mucho tiempo y muchos pasos, asegur&amp;aacute;ndonos un proceso r&amp;aacute;pido, seguro y limpio.&lt;/p&gt;
&lt;p&gt;Si ahora abrimos SQL Server Management Studio por ejemplo e indicamos los par&amp;aacute;metros de conexi&amp;oacute;n (servidor, usuario y contrase&amp;ntilde;a), podremos probar que los datos han sido migrados correctamente y todo est&amp;aacute; seg&amp;uacute;n lo esperado.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=208457" width="1" height="1"&gt;</content><author><name>jorge</name><uri>http://geeks.ms/members/jorge/default.aspx</uri></author><category term="Windows Azure" scheme="http://geeks.ms/blogs/jorge/archive/tags/Windows+Azure/default.aspx" /></entry><entry><title>¿Fidelidad de los clientes con las empresas o fidelidad de las empresas con los clientes?</title><link rel="alternate" type="text/html" href="/blogs/jorge/archive/2013/01/30/191-fidelidad-de-los-clientes-con-las-empresas-o-fidelidad-de-las-empresas-con-los-clientes.aspx" /><id>/blogs/jorge/archive/2013/01/30/191-fidelidad-de-los-clientes-con-las-empresas-o-fidelidad-de-las-empresas-con-los-clientes.aspx</id><published>2013-01-30T18:00:00Z</published><updated>2013-01-30T18:00:00Z</updated><content type="html">&lt;p&gt;&lt;strong&gt;&lt;span style="color:#c0504d;"&gt;&lt;img height="319" width="600" src="http://eldevocionaldejesusrico.files.wordpress.com/2010/10/en-lo-poco-fuiste-fiel.jpg" alt="" /&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="color:#c0504d;"&gt;Introducci&amp;oacute;n&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;El hecho de que me haya animado a escribir esta entrada, es debido fundamentalmente a que en dos d&amp;iacute;as pr&amp;aacute;cticamente seguidos, he tenido la oportunidad de charlar con dos compa&amp;ntilde;eros distintos de trabajo sobre un tema concurrente en el tiempo:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;La fidelidad de los clientes en las compa&amp;ntilde;&amp;iacute;as en las que consumen bienes y servicios y lo que estas aportan a los clientes fieles.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="color:#c0504d;"&gt;Poni&amp;eacute;ndonos en situaci&amp;oacute;n&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Creo que de todos es sabido (y sino ya lo sabes a partir de ahora), que una de las primeras premisas que te explican en marketing es que hacer un cliente cuesta mucho esfuerzo y dinero, y perderlo muy muy poco. &lt;br /&gt;Sin embargo, cuando pierdes un cliente por insatisfacci&amp;oacute;n, enga&amp;ntilde;o o molestia, en un porcentaje que se acerca al 100%, ese cliente lo habr&amp;aacute;s perdido para siempre salvo contadas, raras y excepcionales ocasiones en las que regresa a ti nuevamente. &lt;br /&gt;Una de esas situaciones extraordinarias en las que un cliente insatisfecho regresa es que la competencia a la que se haya ido sea la &amp;uacute;nica existente en el mercado, e incluso peor que la empresa de la que se fue, algo que por desgracia ocurre en no pocas ocasiones.&lt;/p&gt;
&lt;p&gt;Un baremo que se estudia mucho en marketing para tomar el pulso de los clientes son los resultados del llamado an&amp;aacute;lisis de satisfacci&amp;oacute;n del cliente. &lt;br /&gt;Se trata de un baremo bastante &amp;uacute;til, s&amp;iacute;, pero muchas empresas lo miran por encima o no lo analizan con mayor profundidad y no entienden que dentro de la satisfacci&amp;oacute;n del cliente existen varios niveles diferentes, siendo el m&amp;aacute;s alto el de la satisfacci&amp;oacute;n completa del cliente, un valor muy dif&amp;iacute;cil de alcanzar realmente, ya que estamos hablando de la excelencia, algo a lo que se deber&amp;iacute;a tender como meta &amp;uacute;nica. &lt;br /&gt;Es precisamente en esa amplia horquilla en la que se mueve la satisfacci&amp;oacute;n del cliente a la que no se le presta siempre la misma atenci&amp;oacute;n y sobre la que muchos clientes deciden cambiar de empresa o compa&amp;ntilde;&amp;iacute;a.&lt;/p&gt;
&lt;p&gt;Pero esto no es extrapolable solamente al consumo, tambi&amp;eacute;n ocurre algo parecido con los propios empleados de una empresa y por eso muchos de ellos terminan cambiando de empleo.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="color:#c0504d;"&gt;Objetivos de una empresa&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Regresando al tema principal que nos ocupa, una empresa no es una ONG y se nutre de balances econ&amp;oacute;micos, beneficios, p&amp;eacute;rdidas, inversiones, etc, por lo que cada vez que hablamos de satisfacci&amp;oacute;n del cliente, debemos tener en cuenta dos v&amp;iacute;as fundamentales para aportar esos valores positivos a la compa&amp;ntilde;&amp;iacute;a.&lt;/p&gt;
&lt;p&gt;Una primera v&amp;iacute;a estar&amp;iacute;a formada por la consecuci&amp;oacute;n de nuevos clientes. Esto se consigue de muy diferentes maneras. &lt;br /&gt;Como dije antes, conseguir un nuevo cliente suele costar tiempo y dinero, pero algo que se obvia y que es fundamental igualmente es el boca a boca. Pero para todo ello, la imagen actual de marca y empresa es vital. &lt;br /&gt;La imagen de marca y la percepci&amp;oacute;n de los potenciales consumidores se puede lograr a base de esfuerzos como por ejemplo el establecimiento de canales de comunicaci&amp;oacute;n adecuados y m&amp;aacute;s efectivos, la mejora de la red de ventas, el posicionamiento de la marca, etc.&lt;/p&gt;
&lt;p&gt;Una segunda v&amp;iacute;a estar&amp;iacute;a formada por los clientes y consumidores actuales de la marca. &lt;br /&gt;Es indudable que un cliente actual es el que est&amp;aacute; consumiendo nuestros productos, por lo que esa inc&amp;oacute;gnita la podemos despejar centr&amp;aacute;ndonos &amp;uacute;nicamente en la inc&amp;oacute;gnita de lograr vender a ese cliente m&amp;aacute;s productos. &lt;br /&gt;Sin embargo, si un cliente actual no est&amp;aacute; completamente satisfecho y tratamos de venderle un producto, se puede producir un efecto contrario de rechazo decidiendo en ese mismo momento, cancelar nuestra relaci&amp;oacute;n.&lt;/p&gt;
&lt;p&gt;En todo caso, una empresa debe tener siempre presente que haga lo que haga va a perder clientes, porque nunca puedes satisfacer todas las demandas. &lt;br /&gt;El &amp;eacute;xito para una empresa es tener un ratio menor del 2% de p&amp;eacute;rdida de clientes. De esta manera, un 5% por ejemplo es normalmente una cantidad bastante grande de p&amp;eacute;rdidas y denotan un problema a medio plazo.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="color:#c0504d;"&gt;Objetivos de un cliente&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Un cliente por su parte puede ser de diferentes tipos.&lt;/p&gt;
&lt;p&gt;Existen los clientes que consumen un producto y no vuelven a tener contacto con la marca m&amp;aacute;s veces..., o si la vuelven a tener es despu&amp;eacute;s de much&amp;iacute;simo tiempo para repetir la operaci&amp;oacute;n. Son los clientes &lt;em&gt;Guadiana&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Tambi&amp;eacute;n tenemos a los clientes que despu&amp;eacute;s de consumir un producto y quedar satisfechos, vuelven a repetir la operaci&amp;oacute;n, o que incluso estando satisfechos y sin &amp;aacute;nimo de consumir al menos de momento m&amp;aacute;s que lo que ha consumido o tiene contratado, son tentados por la competencia y no tienen ninguna intenci&amp;oacute;n de cambiar porque est&amp;aacute;n vinculados sentimental o de alguna otra manera con la compa&amp;ntilde;&amp;iacute;a, marca, etc.&lt;/p&gt;
&lt;p&gt;En tercer lugar tenemos a los clientes insatisfechos que contin&amp;uacute;an consumiendo servicios o productos, m&amp;aacute;s por inercia que por otra causa especial. Son clientes denominados residuales.&lt;/p&gt;
&lt;p&gt;Finalmente, tenemos tambi&amp;eacute;n a los clientes que en un estado insatisfecho han decidido cambiar de empresa.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="color:#c0504d;"&gt;Y aqu&amp;iacute; estamos...&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Y despu&amp;eacute;s de todo lo comentado anteriormente (y me he ahorrado muchos detalles para no parecer esto una clase de marketing), viene la realidad. Al menos en Espa&amp;ntilde;a.&lt;/p&gt;
&lt;p&gt;Pregunta directa. &lt;br /&gt;&lt;em&gt;&amp;iquest;Porqu&amp;eacute; las empresas consideran o priorizan la contrataci&amp;oacute;n de nuevos clientes en lugar de potenciar la satisfacci&amp;oacute;n del actual cliente?.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Y es que tambi&amp;eacute;n es sabido que cuando un cliente consume un producto, se da por hecho que salvo que la caguemos, raramente va a cambiar y se va a ir con la competencia (&lt;span style="color:#ff0000;"&gt;&amp;iexcl;error!&lt;/span&gt;). &lt;br /&gt;Tambi&amp;eacute;n es frecuente el hecho de que muchas empresas se centren en hacer cartera de clientes y meterlos en su CRM para ense&amp;ntilde;arles a los inversores cuantos clientes se han hecho, eso s&amp;iacute;... a costa de gastar mucho dinero... perd&amp;oacute;n... a costa de tirar el dinero quer&amp;iacute;a decir (&lt;span style="color:#ff0000;"&gt;&amp;iexcl;error!&lt;/span&gt;). &lt;br /&gt;Tambi&amp;eacute;n es un mito pensar que el cliente lo ser&amp;aacute; para toda la vida... (&lt;span style="color:#ff0000;"&gt;&amp;iexcl;error y de los gordos!&lt;/span&gt;).&lt;/p&gt;
&lt;p&gt;Vivimos en un mundo globalizado, y por lo tanto, cada vez el consumidor posee mayores oportunidades. Un ejemplo de esto son las ventas por Internet. Hay productos como la luz, el agua o el tel&amp;eacute;fono que hoy d&amp;iacute;a no se pueden consumir por Internet, pero existen otros productos que s&amp;iacute;.&lt;/p&gt;
&lt;p&gt;Pero pongamos ejemplos reales a todo esto.&lt;/p&gt;
&lt;p&gt;El ejemplo m&amp;aacute;s t&amp;iacute;pico de todo lo comentado anteriormente lo tenemos con las empresas de telecomunicaciones en Espa&amp;ntilde;a. &lt;br /&gt;Desde la liberalizaci&amp;oacute;n de las telecomunicaciones en el a&amp;ntilde;o 1998, el marco comercial apenas ha cambiado. &lt;br /&gt;Este a&amp;ntilde;o 2013 se prev&amp;eacute; la liberalizaci&amp;oacute;n de la energ&amp;iacute;a principalmente y veremos que ocurre, pero mucho me temo que copiar&amp;aacute;n el mismo marco o modelo comercial de agresividad en el que se ha movido el de las telecomunicaciones y en el que lo m&amp;aacute;s importante es hacer clientes, y cuantos m&amp;aacute;s mejor, sin importar cuantos clientes actuales se pierden, as&amp;iacute; que los clientes estar&amp;aacute;n saltando de una compa&amp;ntilde;&amp;iacute;a a otra como si estuvi&amp;eacute;ramos salteando guisantes en una sart&amp;eacute;n.&lt;/p&gt;
&lt;p&gt;En telecomunicaciones hoy d&amp;iacute;a, un cliente de toda la vida de una operadora recibe menos beneficios que un cliente que decide hacer la portabilidad. Incluso ha habido personas que han estado pegando saltos de portabilidad en portabilidad en busca no de la mejor oferta, sino de sacar terminales de &amp;uacute;ltima generaci&amp;oacute;n al mejor precio (&lt;em&gt;aka gratis&lt;/em&gt;). &lt;br /&gt;Las empresas de telecomunicaciones que estaban &amp;aacute;vidas por hacer clientes, entraban en esa din&amp;aacute;mica porque comercial o estrat&amp;eacute;gicamente las interesaba, y as&amp;iacute; hemos estado en estos &amp;uacute;ltimos casi 15 a&amp;ntilde;os.&lt;/p&gt;
&lt;p&gt;Como ejemplo me citar&amp;eacute; a m&amp;iacute; mismo que estando en Telef&amp;oacute;nica (&lt;a href="http://es.wikipedia.org/wiki/MoviStar"&gt;Movistar&lt;/a&gt;) desde hace creo recordar algo m&amp;aacute;s de 15 a&amp;ntilde;os ya (que tiempos aquellos del &lt;a href="http://es.wikipedia.org/wiki/MoviLine"&gt;Moviline&lt;/a&gt;), no he recibido &lt;em&gt;&lt;span style="color:#c0504d;"&gt;&lt;strong&gt;NUNCA&lt;/strong&gt;&lt;/span&gt;&lt;/em&gt; ninguna oferta o regalo de un terminal de &amp;uacute;ltima generaci&amp;oacute;n. &lt;br /&gt;Sin embargo, si siendo cliente Movistar me voy a otra operadora y elijo la portabilidad, esa operadora s&amp;iacute; me regala ese terminal que a&amp;ntilde;oro tener si le prometo fidelidad durante 12, 18 &amp;oacute; 24 meses. &lt;br /&gt;Es decir, me presta mayor atenci&amp;oacute;n y mimos una nueva compa&amp;ntilde;&amp;iacute;a con la que nunca he hecho tratos que &lt;em&gt;&lt;strong&gt;&lt;span style="color:#c0504d;"&gt;mi&lt;/span&gt;&lt;/strong&gt;&lt;/em&gt; compa&amp;ntilde;&amp;iacute;a de toda la vida. &lt;span style="text-decoration:underline;"&gt;&lt;em&gt;&amp;iquest;Curioso?&lt;/em&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Y es que muchas compa&amp;ntilde;&amp;iacute;as se olvidan de una cosa. &lt;br /&gt;La primera y m&amp;aacute;s importante es que un cliente es M&amp;Aacute;S IMPORTANTE que un futuro cliente, y que un cliente contento y satisfecho es un potencial escaparate para animar a otros amigos o conocidos a entrar a formar parte del grupo de consumidores de una empresa. &lt;br /&gt;&amp;iquest;Qu&amp;eacute; creen que comentar&amp;eacute; en una reuni&amp;oacute;n informal cuando uno de mis amigos ense&amp;ntilde;e todo ilusionado y contento el nuevo terminal que ha obtenido gracias a la portabilidad que ha realizado desde el operador A al operador B?. &lt;br /&gt;Pues simple y llano... &amp;quot;&lt;em&gt;En Movistar son unos ratas&lt;/em&gt;&amp;quot;. &lt;br /&gt;A lo que otro amigo me dir&amp;aacute;... &amp;quot;&lt;em&gt;En &lt;/em&gt;&lt;a href="http://es.wikipedia.org/wiki/Vodafone_Espa%C3%B1a"&gt;&lt;em&gt;Vodafone&lt;/em&gt;&lt;/a&gt;&lt;em&gt; estamos igual&lt;/em&gt;&amp;quot;. &lt;br /&gt;Y otro dir&amp;aacute;... &amp;quot;&lt;em&gt;En &lt;/em&gt;&lt;a href="http://es.wikipedia.org/wiki/Amena"&gt;&lt;em&gt;Amena&lt;/em&gt;&lt;/a&gt;&lt;em&gt; no somos distintos&lt;/em&gt;&amp;quot;. &lt;br /&gt;Y finalmente otro m&amp;aacute;s dir&amp;aacute;... &amp;quot;&lt;em&gt;&amp;iexcl;Anda!, &amp;iquest;y qu&amp;eacute; os cre&amp;eacute;is que pasa en &lt;/em&gt;&lt;a href="http://es.wikipedia.org/wiki/Yoigo"&gt;&lt;em&gt;Yoigo&lt;/em&gt;&lt;/a&gt;&lt;em&gt;?&lt;/em&gt;&amp;quot;. &lt;br /&gt;Vamos... que s&amp;oacute;lo te queda una alternativa... hacer como tu amigo y portar tu n&amp;uacute;mero a otra compa&amp;ntilde;&amp;iacute;a y dejar la compa&amp;ntilde;&amp;iacute;a telef&amp;oacute;nica de toda la vida.&lt;/p&gt;
&lt;p&gt;Otro ejemplo. &lt;br /&gt;Una empresa que tiene seguros m&amp;eacute;dicos y que siendo cliente de ellos desde hace a&amp;ntilde;os, te invitan a salirte de la compa&amp;ntilde;&amp;iacute;a y cancelar el seguro para volver a contratarlo y poder as&amp;iacute; aprovechar una de las ofertas de promoci&amp;oacute;n que tienen para... &amp;iexcl;&amp;iexcl;&amp;iexcl;NUEVOS CLIENTES!!!. &lt;br /&gt;Vamos... que le importa un r&amp;aacute;bano que seas cliente actual de la compa&amp;ntilde;&amp;iacute;a, porque lo que quieren comercialmente es tener un contador que sume un +1 a &amp;quot;nuevos clientes&amp;quot;, aunque sea a costa de poner un -1 a clientes actuales, porque el inversor de turno no va a ver, prestar atenci&amp;oacute;n o contabilizar esos datos.&lt;/p&gt;
&lt;p&gt;Estos ejemplos los quiero compartir porque adem&amp;aacute;s de ser reales, dejan a las claras una triste afirmaci&amp;oacute;n.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;span style="text-decoration:underline;"&gt;Un cliente nuevo es mejor valorado que un cliente antiguo y fiel a la marca, cuando en realidad deber&amp;iacute;a ser al contrario.&lt;/span&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Ahora voy a poner un ejemplo te&amp;oacute;rico de actuaci&amp;oacute;n por parte de una empresa de telecomunicaciones que quiere romper el mercado preparando un modelo comercial moderno y diferente.&lt;/p&gt;
&lt;p&gt;Si por ejemplo, un cliente fiel recibe una prebenda cada... &amp;iquest;4 a&amp;ntilde;os por ejemplo?, &amp;iquest;cre&amp;eacute;is que ese cliente va a cambiarse de compa&amp;ntilde;&amp;iacute;a?. &lt;br /&gt;Pongo un ejemplo m&amp;aacute;s descriptivo a&amp;uacute;n. &lt;br /&gt;Si hoy sale &lt;a href="http://es.wikipedia.org/wiki/Windows_Phone"&gt;Windows Phone 8&lt;/a&gt; y soy un fan&amp;aacute;tico de dichos terminales y el operador de telecomunicaciones decide ofrecerme gratis un Nokia 820 con una permanencia de 24 meses y un Nokia 920 con una permanencia de 36 meses con consumo fijo, etc... &amp;iquest;cre&amp;eacute;is realmente que aceptar&amp;eacute; o rechazar&amp;eacute; la oferta?. &lt;br /&gt;Imaginad lo mismo para otros terminales tipo &lt;a href="http://es.wikipedia.org/wiki/IPhone"&gt;iPhone&lt;/a&gt;, &lt;a href="http://es.wikipedia.org/wiki/Android"&gt;Android&lt;/a&gt;, &lt;a href="http://es.wikipedia.org/wiki/BlackBerry"&gt;BlackBerry&lt;/a&gt;, etc...&lt;/p&gt;
&lt;p&gt;Ahora pensad que llego a esos 24 meses de permanencia por ejemplo y mi Nokia 820 se me queda obsoleto o simplemente me he cansado de &amp;eacute;l... &amp;iquest;que har&amp;iacute;a el consumidor?. &lt;br /&gt;Seguramente cambiar, pero a lo mejor puede acogerse a un servicio como los actuales puntos que tienen las operadoras para obtener una rebaja. &lt;br /&gt;Pero imaginemos nuevamente que el cliente est&amp;aacute; contento con el terminal y decide continuar us&amp;aacute;ndolo otros 24 meses m&amp;aacute;s (4 a&amp;ntilde;os ya), y el operador me llama sin yo decirle nada para decirme que han detectado que llevo 4 a&amp;ntilde;os usando el mismo terminal que me ofrecieron y que ahora me ofrece otro terminal nuevo modelo gratis si le ofrezco fidelidad nuevamente... &amp;iquest;que cre&amp;eacute;is que pasar&amp;iacute;a?.&lt;/p&gt;
&lt;p&gt;&amp;iquest;Y qu&amp;eacute; cre&amp;eacute;is que pasar&amp;iacute;a cuando me juntara con los otros colegas de profesi&amp;oacute;n, amigos y familia como hice antes para hablar estas cosas?. &lt;br /&gt;Indudablemente les dir&amp;iacute;a que utilizaran los servicios de mi operador de telecomunicaciones porque las ventajas son enormes, me cuidan, etc. &lt;br /&gt;&amp;iquest;Y qu&amp;eacute; cre&amp;eacute;is que la portabilidad les sale gratis a las compa&amp;ntilde;&amp;iacute;as de telecomunicaciones?. Pues no, da mucho dinero... de ah&amp;iacute; que est&amp;eacute;n jugando con este modelo de negocio sin pensar que es el chocolate del loro y que otros modelos les aporta mayores beneficios.&lt;/p&gt;
&lt;p&gt;&amp;iquest;Y que hay aqu&amp;iacute; en esta forma de actuar diferente realmente?. Pues varias cosas.&lt;/p&gt;
&lt;p&gt;Por un lado, se crea una dependencia y una estrecha relaci&amp;oacute;n casi personalizada entre empresa y cliente, y entre cliente y empresa. &lt;br /&gt;La fidelidad va en doble direcci&amp;oacute;n y no s&amp;oacute;lo como hasta ahora ocurre casi siempre, en la que es el cliente el que le puede ser fiel o no a la empresa. &lt;br /&gt;La satisfacci&amp;oacute;n del cliente aumenta. &lt;br /&gt;La empresa adem&amp;aacute;s recoge como canal indirecto una entrada de clientes debido a las recomendaciones y satisfacciones de los actuales clientes. &lt;br /&gt;El cliente se encuentra mimado y valorado. &lt;br /&gt;El cliente no se plantear&amp;aacute; ning&amp;uacute;n cambio si su grado de satisfacci&amp;oacute;n y servicio son &amp;oacute;ptimos. &lt;br /&gt;La empresa recoger&amp;aacute; unos ingresos fijos de acuerdo al contrato de fidelidad establecido, por lo que podr&amp;aacute; incluso hacer estudios de inversi&amp;oacute;n y contabilidad m&amp;aacute;s precisos.&lt;/p&gt;
&lt;p&gt;Me gustar&amp;iacute;a poner dos ejemplos o an&amp;eacute;cdotas m&amp;aacute;s que han salido a colaci&amp;oacute;n de comentar todo esto con algunos de mis compa&amp;ntilde;eros de trabajo.&lt;/p&gt;
&lt;p&gt;Mi primera impresora fue una &lt;a href="http://es.wikipedia.org/wiki/Anexo:Productos_Hewlett-Packard"&gt;HP Deskjet 510&lt;/a&gt; en blanco y negro. &lt;br /&gt;Me acuerdo perfectamente. &lt;br /&gt;Yo era un ignorante de todo el mundillo inform&amp;aacute;tico y alguien me dijo que era muy bueno registrar los productos por el soporte de las empresas. &lt;br /&gt;Como era eso, un ignorante... se me ocurri&amp;oacute; registrar en HP mi impresora enviando el formulario de registro a una direcci&amp;oacute;n de USA. &lt;br /&gt;Lo hice y me olvid&amp;eacute; de aquello... total... &amp;iquest;para qu&amp;eacute; servir&amp;aacute;?. &lt;br /&gt;De hecho, algunos conocidos me dijeron cuando lo coment&amp;eacute; que hab&amp;iacute;a perdido el dinero de los sellos y que no servir&amp;iacute;a para nada... &lt;br /&gt;Comenc&amp;eacute; mis estudios de inform&amp;aacute;tica y de repente viene un paquete a casa desde USA. &lt;br /&gt;Cuando lo abr&amp;iacute; me encontr&amp;eacute; un aparato met&amp;aacute;lico y pesado y una carta. &lt;br /&gt;La carta ped&amp;iacute;a disculpas por un fallo en la impresora e indicaba que como usuario y consumidor de dicha impresora, me enviaban dicho aparato para resolver los problemas detectados. &lt;br /&gt;El problema era muy simple. Cuando la bandeja de papel llegaba a tener como tres o cuatro hojas, la impresora no las enganchaba. &lt;br /&gt;El aparatoso soporte que me enviaban levantaba un poco las hojas para que los rodillos las pillara. As&amp;iacute; de simple. &lt;br /&gt;Lo cierto es que s&amp;iacute; hab&amp;iacute;a notado el fallo, pero lo solventaba a&amp;ntilde;adiendo m&amp;aacute;s papel. &lt;br /&gt;La verdad es que aquello hizo que recomendara la marca a todos mis conocidos.&lt;/p&gt;
&lt;p&gt;A&amp;ntilde;os despu&amp;eacute;s, adquir&amp;iacute; un &lt;a href="http://es.wikipedia.org/wiki/Citroen_C5"&gt;Citr&amp;ouml;en C5&lt;/a&gt;. &lt;br /&gt;Era un anti-citr&amp;ouml;en, no lo niego, pero ya sab&amp;eacute;is... calidad/precio... achuchado econ&amp;oacute;micamente,... etc. &lt;br /&gt;Lo adquir&amp;iacute; y al poco tiempo de usarlo detect&amp;eacute; un fallo de f&amp;aacute;brica que remit&amp;iacute; a Francia. &lt;br /&gt;Al cabo de los meses recib&amp;iacute; una carta que me indicaba que me acercara por un taller Citr&amp;ouml;en para resolver gratuitamente algunos problemas t&amp;eacute;cnicos detectados en el modelo. &lt;br /&gt;Cuando fui al taller y pregunt&amp;eacute;, me dijeron que las reparaciones eran de unos 1000 &amp;euro; por coche y que estaban llamados a hacerlas todos los modelos desde una fecha determinada. &lt;br /&gt;Que no eran fallos graves y que quien no quisiera realizar las reparaciones pod&amp;iacute;a circular sin problemas, pero que l&amp;oacute;gicamente me recomendaban hacerlas, a lo que acced&amp;iacute; como es l&amp;oacute;gico. &lt;br /&gt;Despu&amp;eacute;s de utilizar el veh&amp;iacute;culo durante algo m&amp;aacute;s de 8 a&amp;ntilde;os y de aquella an&amp;eacute;cdota... os lo pod&amp;eacute;is imaginar... me compr&amp;eacute; otro Citr&amp;ouml;en C5.&lt;/p&gt;
&lt;p&gt;Todo esto lo comento porque me duele enormemente ver como las empresas invierten (o tiran) una gran cantidad de dinero en hacer nuevos clientes ignorando a los que ya tiene, invit&amp;aacute;ndoles pr&amp;aacute;cticamente a ser clientes residuales o incluso a cambiar de marca, compa&amp;ntilde;&amp;iacute;a, empresa, etc.&lt;/p&gt;
&lt;p&gt;Y es que creo que es m&amp;aacute;s importante mantener a tus actuales clientes y potenciar esa relaci&amp;oacute;n empresa-cliente, cliente-empresa, que pensar &amp;uacute;nicamente en crear nuevos clientes. &lt;br /&gt;Nuestras ansias de crecer a veces, nos hace perder el foco de lo que importa,... y cuidado, que hay quienes se mueren de &amp;eacute;xito.&lt;/p&gt;
&lt;p&gt;&amp;iquest;Tienes alguna f&amp;oacute;rmula para defender el marco normal de actuaci&amp;oacute;n de las empresas para olvidar a los clientes actuales y fieles y atender mejor a los potenciales nuevos clientes?. &amp;iquest;Qu&amp;eacute; opinas?.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=208408" width="1" height="1"&gt;</content><author><name>jorge</name><uri>http://geeks.ms/members/jorge/default.aspx</uri></author><category term="Opini&amp;#243;n" scheme="http://geeks.ms/blogs/jorge/archive/tags/Opini_26002300_243_3B00_n/default.aspx" /></entry><entry><title>Usando Visual Studio, LINQPad 4 y NHibernate Profile (versión paso a paso)</title><link rel="alternate" type="text/html" href="/blogs/jorge/archive/2013/01/28/usando-visual-studio-linqpad-4-y-nhibernate-profile-versi-243-n-paso-a-paso.aspx" /><id>/blogs/jorge/archive/2013/01/28/usando-visual-studio-linqpad-4-y-nhibernate-profile-versi-243-n-paso-a-paso.aspx</id><published>2013-01-28T13:30:00Z</published><updated>2013-01-28T13:30:00Z</updated><content type="html">&lt;p&gt;&lt;b&gt;&lt;font color="#646b86"&gt;Introducción&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;La semana pasada, mi compañero de trabajo y sufrimientos, &lt;a href="http://geeks.ms/blogs/lruiz/"&gt;Luis Ruiz Pavón&lt;/a&gt;, escribió una &lt;a href="http://geeks.ms/blogs/lruiz/archive/2013/01/23/tips-linqpad-4-nhibernate-profiler.aspx"&gt;interesantísima entrada&lt;/a&gt; sobre cómo utilizar LINQPad 4 y NHibernate para probar consultas LINQ y resolver posibles problemas de rendimiento, cuellos de botella, etc., sin tener que hacer grandes alardes de programación… es decir, sin utilizar Visual Studio.&lt;/p&gt;  &lt;p&gt;En mi caso, voy a preparar una entrada variante y complementaria de la de Luis pero enfocándome en lo que sería un pequeño ejemplo paso a paso de cómo llevar a cabo esta tarea utilizando levemente Visual Studio para aquellos que se encuentren un poco perdidos en la utilización de LINQPad 4 y NHibernate Profiler tal y como apuntaba Luis.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;font color="#646b86"&gt;Preparando el modelo&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;Lo primero de todo, vamos a crear un proyecto de tipo &lt;em&gt;Class Library&lt;/em&gt; en C# por ejemplo, al que le he puesto el nombre de &lt;em&gt;&lt;strong&gt;NHibernateTest&lt;/strong&gt;&lt;/em&gt; y en el que agregaremos una clase de nombre &lt;em&gt;&lt;strong&gt;Exployee&lt;/strong&gt;&lt;/em&gt; y con los siguientes campos:&lt;/p&gt;  &lt;div class="csharpcode"&gt;   &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; NHibernateTest&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;    &lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Employee&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; Guid Id { get; set; }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Name { get; set; }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Surname { get; set; }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Address { get; set; }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; City { get; set; }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Country { get; set; }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;    } &lt;span class="rem"&gt;// Employee&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;} // NHibernateTest&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;A continuación, compilaremos nuestro proyecto para ver que todo está bien.&lt;/p&gt;

&lt;p&gt;Una vez hecho esto, &lt;em&gt;&lt;u&gt;nos olvidaremos ya de Visual Studio&lt;/u&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Pensemos por lo tanto, en que hemos preparado un proyecto con los objetos de dominio o similar.&lt;/p&gt;

&lt;p&gt;Sin embargo, nos gustaría poder “&lt;em&gt;jugar&lt;/em&gt;” con ellos introduciendo datos o haciendo algunas operaciones básicas o genéricas con &lt;em&gt;NHibernate&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Crear un proyecto de consola o similar es una alternativa, pero nos obligaría a abrir Visual Studio y trastear, cuando en realidad, lo que queremos, es hacer algo más ágil, rápido y sencillo.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;&lt;font color="#646b86"&gt;Preparando LINQPad 4&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Vamos a ejecutar por lo tanto &lt;em&gt;LINQPad 4&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Lo primero que haremos será modificar la propiedad &lt;em&gt;&lt;strong&gt;Language&lt;/strong&gt;&lt;/em&gt; a &lt;b&gt;C# Statements&lt;/b&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src="https://ptstda.sn2.livefilestore.com/y1p-KuaB2Kli3p6U0XBV1Z3ho37V94IuQt43nduoqmIE7BuFbdIVsXgk9Nl8iGqu-EMMnEGv_DOx-G5D5LUEQ_bEXXn8DnNSBlI/20130128_01.png?psid=1" alt="" /&gt;&lt;/p&gt;

&lt;p&gt;Una vez hecho esto, si queremos, podemos establecer una conexión con nuestra base de datos.&lt;/p&gt;

&lt;p&gt;En concreto, tengo una base de datos en &lt;strong&gt;SQL SERVER&lt;/strong&gt; a la que le he puesto el nombre de &lt;strong&gt;TESTS&lt;/strong&gt;, y que tiene una tabla de nombre &lt;strong&gt;&lt;em&gt;Employees&lt;/em&gt;&lt;/strong&gt; con los campos indicados en la clase de C# que vimos anteriormente:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://ptstda.sn2.livefilestore.com/y1pZ6FrTtbntOc_pHfkff164b6uvVMG7yq8y1rv_Rwaarjkl1RaYYit0fjoGYDGbKO7S4WgBJ8SAaHOux_V5LRNCPjfIahZY7ZV/20130128_02.png?psid=1" alt="" /&gt;&lt;/p&gt;

&lt;p&gt;Sólo de modo opcional y si quisiéramos establecer una conexión en &lt;em&gt;LINQPad 4&lt;/em&gt; con nuestra fuente de datos, haríamos clic en la opción &lt;strong&gt;&lt;em&gt;Add connection&lt;/em&gt;&lt;/strong&gt; de la aplicación:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://ptstda.sn2.livefilestore.com/y1p-KuaB2Kli3phTFSptxMy2VpaQvj6Xjh3oyy3M1fw6_Ot2HWOoQStagItGzj2q98QNDPJzX30P5__1a1HnBmNZYf46Iu9KEH9/20130128_03.png?psid=1" alt="" /&gt;&lt;/p&gt;

&lt;p&gt;Probaríamos la conexión y veremos que todo es correcto. Pero en este caso, este último paso lo vamos a obviar.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;&lt;font color="#646b86"&gt;Fichero de configuración de NHibernate en lugar de utilizar la conexión con LINQPad 4&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;En mi caso sin embargo, voy a tirar de ficheros de configuración.&lt;/p&gt;

&lt;p&gt;Así que para establecer la conexión con nuestra fuente de datos, voy a crear un archivo de configuración llamado &lt;strong&gt;sqlserver.hibernate.cfg.xml&lt;/strong&gt; dentro del cual he agregado la siguiente configuración:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&amp;lt;?xml version=&lt;span class="str"&gt;&amp;quot;1.0&amp;quot;&lt;/span&gt; encoding=&lt;span class="str"&gt;&amp;quot;utf-8&amp;quot;&lt;/span&gt; ?&amp;gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&amp;lt;configuration&amp;gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;  &amp;lt;configSections&amp;gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    &amp;lt;section name=&lt;span class="str"&gt;&amp;quot;hibernate-configuration&amp;quot;&lt;/span&gt; type=&lt;span class="str"&gt;&amp;quot;NHibernate.Cfg.ConfigurationSectionHandler, NHibernate&amp;quot;&lt;/span&gt;/&amp;gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;  &amp;lt;/configSections&amp;gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;  &amp;lt;hibernate-configuration xmlns=&lt;span class="str"&gt;&amp;quot;urn:nhibernate-configuration-2.2&amp;quot;&lt;/span&gt;&amp;gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;    &amp;lt;session-factory&amp;gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;      &amp;lt;property name=&lt;span class="str"&gt;&amp;quot;dialect&amp;quot;&lt;/span&gt;&amp;gt;NHibernate.Dialect.MsSql2008Dialect&amp;lt;/property&amp;gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;      &amp;lt;property name=&lt;span class="str"&gt;&amp;quot;connection.provider&amp;quot;&lt;/span&gt;&amp;gt;NHibernate.Connection.DriverConnectionProvider&amp;lt;/property&amp;gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;      &amp;lt;property name=&lt;span class="str"&gt;&amp;quot;connection.connection_string&amp;quot;&lt;/span&gt;&amp;gt;Data Source=P-JOSE8\MSSQLSERVER2012;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;      Initial Catalog=TESTS;Integrated Security=True&amp;lt;/property&amp;gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;    &amp;lt;/session-factory&amp;gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;  &amp;lt;/hibernate-configuration&amp;gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;&amp;lt;/configuration&amp;gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Recapitulando, hemos dejado preparado &lt;em&gt;LINQPad 4&lt;/em&gt; y hemos creado una biblioteca de clases en Visual Studio donde hemos creado nuestra clase &lt;strong&gt;&lt;em&gt;Employee&lt;/em&gt;&lt;/strong&gt; con sus campos.&lt;/p&gt;

&lt;p&gt;Tenemos una base de datos de prueba con una tabla &lt;strong&gt;&lt;em&gt;Employees&lt;/em&gt;&lt;/strong&gt; con los campos correspondientes, y por último, hemos creado un archivo de configuración de &lt;em&gt;NHibernate&lt;/em&gt; para establecer la conexión con nuestra fuente de datos.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;&lt;font color="#646b86"&gt;Creando el archivo de mapeo con la entidad Employee&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;El siguiente paso será el de preparar el archivo de mapeo de nuestra entidad &lt;strong&gt;&lt;em&gt;Employee&lt;/em&gt;&lt;/strong&gt; para que &lt;em&gt;NHibernate&lt;/em&gt; interprete correctamente sus campos y pueda trabajar con ella sin problemas.&lt;/p&gt;

&lt;p&gt;Existen otras formas de llevar a cabo esto, pero aquí y para probar todo, vamos a hacerlo así.&lt;/p&gt;

&lt;p&gt;El archivo de mapeo se llamará &lt;strong&gt;Employee.hbm.xml&lt;/strong&gt;, y su contenido queda de la siguiente manera:&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;


&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&amp;lt;?xml version=&lt;span class="str"&gt;&amp;quot;1.0&amp;quot;&lt;/span&gt; encoding=&lt;span class="str"&gt;&amp;quot;utf-8&amp;quot;&lt;/span&gt; ?&amp;gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&amp;lt;hibernate-mapping xmlns=&lt;span class="str"&gt;&amp;quot;urn:nhibernate-mapping-2.2&amp;quot;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;assembly=&lt;span class="str"&gt;&amp;quot;NHibernateTest&amp;quot;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt;=&lt;span class="str"&gt;&amp;quot;NHibernateTest&amp;quot;&lt;/span&gt;&amp;gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;  &amp;lt;&lt;span class="kwrd"&gt;class&lt;/span&gt; name=&lt;span class="str"&gt;&amp;quot;Employee&amp;quot;&lt;/span&gt; table=&lt;span class="str"&gt;&amp;quot;Employees&amp;quot;&lt;/span&gt;&amp;gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;    &amp;lt;id name=&lt;span class="str"&gt;&amp;quot;Id&amp;quot;&lt;/span&gt;&amp;gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;      &amp;lt;generator &lt;span class="kwrd"&gt;class&lt;/span&gt;=&lt;span class="str"&gt;&amp;quot;guid.comb&amp;quot;&lt;/span&gt; /&amp;gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;    &amp;lt;/id&amp;gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;    &amp;lt;property name=&lt;span class="str"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt; not-&lt;span class="kwrd"&gt;null&lt;/span&gt;=&lt;span class="str"&gt;&amp;quot;true&amp;quot;&lt;/span&gt; /&amp;gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;    &amp;lt;property name=&lt;span class="str"&gt;&amp;quot;Surname&amp;quot;&lt;/span&gt; /&amp;gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;    &amp;lt;property name=&lt;span class="str"&gt;&amp;quot;Address&amp;quot;&lt;/span&gt; /&amp;gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;    &amp;lt;property name=&lt;span class="str"&gt;&amp;quot;City&amp;quot;&lt;/span&gt; /&amp;gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;    &amp;lt;property name=&lt;span class="str"&gt;&amp;quot;Country&amp;quot;&lt;/span&gt; /&amp;gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;  &amp;lt;/&lt;span class="kwrd"&gt;class&lt;/span&gt;&amp;gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;&amp;lt;/hibernate-mapping&amp;gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;&lt;b&gt;&lt;font color="#646b86"&gt;Vuelta a LINQPad 4, agregando ensamblados y namespaces&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Para completar todo el proceso, vamos a agregar algunos ensamblados y namespaces a &lt;em&gt;LINQPad 4&lt;/em&gt; para que cuando agreguemos el código de ejecución, pueda localizar e interpretar las instrucciones de código que vamos a ejecutar de forma correcta.&lt;/p&gt;

&lt;p&gt;Lo primero que debemos tener en la herramienta &lt;strong&gt;&lt;em&gt;NHibernate Profiler&lt;/em&gt;&lt;/strong&gt; que nos va a permitir analizar las instrucciones que lanzamos contra &lt;em&gt;NHibernate&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Por otro lado, en &lt;em&gt;LINQPad 4&lt;/em&gt; vamos a pulsar la tecla &lt;strong&gt;F4&lt;/strong&gt; que nos permite abrir la ventana para agregar referencias, ensamblados y namespaces.&lt;/p&gt;

&lt;p&gt;Nos situaremos en la solapa&lt;strong&gt; Additional References&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Los ensamblados a agregar son estos cuatro:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;HibernatingRhinos.Profiler.Appender.dll&lt;/li&gt;

  &lt;li&gt;Iesi.Collections.dll&lt;/li&gt;

  &lt;li&gt;NHibernate.dll&lt;/li&gt;

  &lt;li&gt;NHibernateTest.dll&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dentro de la carpeta en la que tenemos nuestra herramienta de profiling encontraremos un ensamblado de nombre &lt;em&gt;HibernatingRhinos.Profiler.Appender.dll&lt;/em&gt; que deberemos agregar en las referencias adicionales de &lt;em&gt;LINQPad 4&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;También deberemos agregar las librerías &lt;em&gt;Iesi.Collections.dll&lt;/em&gt; y &lt;em&gt;NHibernate.dll&lt;/em&gt; que encontraremos en la carpeta de ensamblados de &lt;em&gt;NHibernate&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Y finalmente agregaremos el ensamblado que creamos con Visual Studio al principio del todo.&lt;/p&gt;

&lt;p&gt;&lt;img src="https://ptstda.sn2.livefilestore.com/y1pDRVfJ19iAt2FMplFSqCrBW1Cv13qNdovCKVHl7XtiQMW92WZwgoO25gsWiB1gHSCLFaC8cvUSSYvUWF5Ih44sSH8qG62XZIB/20130128_04.png?psid=1" alt="" /&gt;&lt;/p&gt;

&lt;p&gt;Para concluir, iremos a la solapa &lt;strong&gt;Additional Namespace Imports&lt;/strong&gt; y agregaremos tres namespaces:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;NHibernate&lt;/li&gt;

  &lt;li&gt;NHibernate.Cfg&lt;/li&gt;

  &lt;li&gt;NHibernateTest&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="https://ptstda.sn2.livefilestore.com/y1pDRVfJ19iAt1fsIc2DKzEJRxafC7A9id3bHQ-HAxPtkqRurTiDf3YCHcz566ncWx-wiQjeXLDLSKVEIrU_Ao_aiEwaTsfl76G/20130128_05.png?psid=1" alt="" /&gt;&lt;/p&gt;

&lt;p&gt;Bastará con poner cada uno de los nombres de los namespaces ahí uno debajo del anterior.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;LINQPad 4&lt;/em&gt; ya se encargará de hacer el correspondiente using por nosotros.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;&lt;font color="#646b86"&gt;Escribiendo el código a ejecutar en LINQPad 4&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Ya estamos prácticamente concluyendo.&lt;/p&gt;

&lt;p&gt;El último paso es escribir nuestro código y ejecutarlo.&lt;/p&gt;

&lt;p&gt;Para ello, vamos a escribir el siguiente código:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;HibernatingRhinos.Profiler.Appender.NHibernate.NHibernateProfiler.Initialize();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;ISessionFactory sessionFactory = &lt;span class="kwrd"&gt;new&lt;/span&gt; Configuration().&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;Configure(&lt;span class="str"&gt;@&amp;quot;C:\Temp\sqlserver.hibernate.cfg.xml&amp;quot;&lt;/span&gt;).&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;AddFile(&lt;span class="str"&gt;@&amp;quot;C:\Temp\Employee.hbm.xml&amp;quot;&lt;/span&gt;).BuildSessionFactory();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; (ISession session = sessionFactory.OpenSession())&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;        &lt;span class="kwrd"&gt;using&lt;/span&gt; (ITransaction transaction = session.BeginTransaction())&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;            Employee employee = &lt;span class="kwrd"&gt;new&lt;/span&gt; Employee();&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;            employee.Name = &lt;span class="str"&gt;&amp;quot;Pedrito&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;            employee.Surname = &lt;span class="str"&gt;&amp;quot;Gómez Sánchez&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;            employee.Address = &lt;span class="str"&gt;&amp;quot;Calle Mayor, 1&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;            employee.City = &lt;span class="str"&gt;&amp;quot;Burgos&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;            employee.Country = &lt;span class="str"&gt;&amp;quot;Spain&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;            session.Save(employee);&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;            transaction.Commit();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;            session.Close();&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;        }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;    }&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Este ejemplo, cargará el archivo de configuración de &lt;em&gt;NHibernate&lt;/em&gt; para establecer la conexión con &lt;em&gt;NHibernate&lt;/em&gt; y el archivo de mapeo de la entidad &lt;strong&gt;&lt;em&gt;Employee&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Finalmente agregaré un nuevo empleado a la base de datos con los datos que hemos agregado aquí.&lt;/p&gt;

&lt;p&gt;Podríamos haber hecho un bucle para agregar un conjunto de empleados a modo de ejemplo o cualquier otra cosa, pero sirva este ejemplo para mostrar cómo escribir datos en una tabla utilizando &lt;em&gt;NHibernate&lt;/em&gt; y sin apenas utilizar Visual Studio.&lt;/p&gt;

&lt;p&gt;El caso es que para ejecutar nuestro código, bastará con pulsar el botón de ejecución o pulsar la tecla &lt;strong&gt;F5&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Si la ejecución es correcta, veremos un mensaje en la parte inferior de la aplicación &lt;em&gt;LINQPad 4&lt;/em&gt; que indica algo así como &lt;em&gt;&lt;strong&gt;Query successful&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;&lt;font color="#646b86"&gt;Analizando NHibernate Profiler&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Adicionalmente y con ayuda del profiler, podemos obtener información valiosa a la hora de ejecutar nuestras instrucciones.&lt;/p&gt;

&lt;p&gt;&lt;img src="https://ptstda.sn2.livefilestore.com/y1pDRVfJ19iAt31DfpZKcJghP1yHvDbod2vYuRc7eV7nBRjfxPT9bKeV4T0z0hIBSZR_OlQgQOgcECY6a37Cr7k5EfXqCUa3YcF/20130128_06.png?psid=1" width="692" height="280" alt="" /&gt;&lt;/p&gt;

&lt;p&gt;Si comprobamos los datos en SQL Server, veremos que estos están correctamente persistidos.&lt;/p&gt;

&lt;p&gt;&lt;img src="https://ptstda.sn2.livefilestore.com/y1p-KuaB2Kli3ohZqeJQDXEkHASonRDzZUAT5BxqFb369zM29c3ldq34-bjRlSb8an-IIfzLIsa02j3ZxFRHQCL2QhozynbH2En/20130128_07.png?psid=1" alt="" /&gt;&lt;/p&gt;

&lt;p&gt;(&lt;em&gt;&lt;u&gt;Nota: también podemos ver los datos persistidos desde LINQPad 4 si hemos establecido previamente una conexión con el modelo de datos como se apuntaba al principio, lo cuál nos evitará incluso la tarea de irnos a SQL Server Management Studio&lt;/u&gt;&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;Tal y como decía Luis en su entrada, estas prácticas nos pueden ahorrar mucho tiempo y quebraderos de cabeza.&lt;/p&gt;

&lt;p&gt;Podemos crear y ejecutar instrucciones LINQ o podemos incluso probar determinados comportamientos y ejecuciones en nuestro código sin tener la necesidad de abrir Visual Studio para ello.&lt;/p&gt;

&lt;p&gt;Espero que le resulte de utilidad a más gente.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=208396" width="1" height="1"&gt;</content><author><name>jorge</name><uri>http://geeks.ms/members/jorge/default.aspx</uri></author><category term="Arquitectura" scheme="http://geeks.ms/blogs/jorge/archive/tags/Arquitectura/default.aspx" /><category term="C#" scheme="http://geeks.ms/blogs/jorge/archive/tags/C_2300_/default.aspx" /><category term=".NET Framework 4.0" scheme="http://geeks.ms/blogs/jorge/archive/tags/.NET+Framework+4.0/default.aspx" /><category term="Visual Studio 2010" scheme="http://geeks.ms/blogs/jorge/archive/tags/Visual+Studio+2010/default.aspx" /><category term="Microsoft .NET Framework 4.0" scheme="http://geeks.ms/blogs/jorge/archive/tags/Microsoft+.NET+Framework+4.0/default.aspx" /><category term="Visual Basic 2010" scheme="http://geeks.ms/blogs/jorge/archive/tags/Visual+Basic+2010/default.aspx" /><category term="Microsoft .NET Framework 4.5" scheme="http://geeks.ms/blogs/jorge/archive/tags/Microsoft+.NET+Framework+4.5/default.aspx" /><category term=".NET Framework 4.5" scheme="http://geeks.ms/blogs/jorge/archive/tags/.NET+Framework+4.5/default.aspx" /><category term="Visual Studio 2012" scheme="http://geeks.ms/blogs/jorge/archive/tags/Visual+Studio+2012/default.aspx" /></entry><entry><title>Publicado WCF Data Services v5.0 for OData V3 y WCF Data Services v5.2</title><link rel="alternate" type="text/html" href="/blogs/jorge/archive/2012/12/18/publicado-wcf-data-services-v5-0-for-odata-v3-y-wcf-data-services-v5-2.aspx" /><id>/blogs/jorge/archive/2012/12/18/publicado-wcf-data-services-v5-0-for-odata-v3-y-wcf-data-services-v5-2.aspx</id><published>2012-12-18T06:00:00Z</published><updated>2012-12-18T06:00:00Z</updated><content type="html">&lt;p&gt;&lt;img src="http://blogs.msdn.com/blogfiles/endpoint/WindowsLiveWriter/WCFDataServicesRIAServicesAlignmentQuest_9CA8/WcfOverviewDiagram_thumb_8.png" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Introducción&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Microsoft ha publicado una actualización de WCF Data Services v5.0, con el que podemos crear y consumir servicios de datos para la Web a través del protocolo OData (Open Data Protocol) versión 3.&lt;/p&gt;  &lt;p&gt;La idea es que entre otras cosas, podamos utilizar fácilmente los verbos HTTP para poder acceder y cambiar datos.&lt;/p&gt;  &lt;p&gt;Los requisitos de esta versión son Microsoft .NET Framework 4.0 Visual Studio 2010.&lt;/p&gt;  &lt;p&gt;Este paquete resuelve diferentes bugs al mismo tiempo que añade mejoras.&lt;/p&gt;  &lt;p&gt;Adicionalmente, Microsoft ha publicado igualmente una nueva versión de WCF Data Services, la versión 5.2 que añade mejoras y resuelve bugs y problemas. Esta nueva versión puede ser instalada en equipos con Microsoft .NET Framework 4.0 y Microsoft .NET Framework 4.5, así como en Visual Studio 2010 y Visual Studio 2012.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Recomendación&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Microsoft recomienda encarecidamente la instalación de la actualización en el caso de que ya utilices WCF Data Services en la middle-tier, especialmente para los usuarios de LightSwitch en Visual Studio 2012.&lt;/p&gt;  &lt;p&gt;Respecto a este último punto, recomiendo acceder a la &lt;a href="http://social.msdn.microsoft.com/Forums/en-US/lightswitch/thread/43aad573-f9f9-42d4-8413-141ba0d183e7"&gt;información que sobre ello ha publicado Beth Massi&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Descarga&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Podrás acceder a la descarga de la actualización de WCF Data Services v5.0 for OData V3 &lt;a href="http://www.microsoft.com/en-us/download/details.aspx?id=29306"&gt;en este enlace (5.3 Mb)&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;También puedes acceder a WCF Data Services v5.2 RTM Tools Installer, que utilizaremos para actualizar los paquetes NuGet referenciados por la plantilla de WCF Data Services a la versión v5.2.0, resolviendo además, algunos bugs detectados que tiraban abajo a Visual Studio en la generación de referencias a servicios contra modelos grandes. Se puede acceder a este otro paquete &lt;a href="http://www.microsoft.com/en-us/download/details.aspx?id=35840"&gt;en este enlace (10.4 Mb)&lt;/a&gt;. Los requisitos mínimos de esta herramienta son Microsoft .NET Framework 4.0 ó Microsoft .NET Framework 4.5, y Visual Studio 2010 ó Visual Studio 2012.&lt;/p&gt;  &lt;p&gt;Finalmente, agrego igualmente el &lt;a href="https://nuget.org/packages/Microsoft.Data.Services/5.2.0"&gt;enlace de NuGet de esta nueva versión 5.2&lt;/a&gt; y el enlace del &lt;a href="http://blogs.msdn.com/b/astoriateam/archive/2012/12/17/wcf-data-services-5-2-0-released.aspx"&gt;sitio oficial de Microsoft con la información de esta nueva versión 5.2&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Aprendizaje&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Si lo que quieres es saber un poco más sobre WCF Data Services, entonces &lt;a href="http://msdn.microsoft.com/es-es/library/cc668796.aspx"&gt;te recomiendo el siguiente tutorial&lt;/a&gt;.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=207831" width="1" height="1"&gt;</content><author><name>jorge</name><uri>http://geeks.ms/members/jorge/default.aspx</uri></author><category term="WCF" scheme="http://geeks.ms/blogs/jorge/archive/tags/WCF/default.aspx" /></entry><entry><title>Error 0x80048821 en la aplicación de SkyDrive para Xbox 360</title><link rel="alternate" type="text/html" href="/blogs/jorge/archive/2012/12/13/error-0x80048821-en-la-aplicaci-243-n-de-skydrive-para-xbox-360.aspx" /><id>/blogs/jorge/archive/2012/12/13/error-0x80048821-en-la-aplicaci-243-n-de-skydrive-para-xbox-360.aspx</id><published>2012-12-13T08:30:00Z</published><updated>2012-12-13T08:30:00Z</updated><content type="html">&lt;p&gt;&lt;strong&gt;&lt;img src="http://www.cdrinfo.com/images/uploaded/Skydrive_Xbox_app.jpg" alt="" /&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Introducción&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Microsoft ha liberado recientemente su aplicación &lt;em&gt;&lt;strong&gt;SkyDrive&lt;/strong&gt;&lt;/em&gt; para &lt;em&gt;Xbox 360&lt;/em&gt;.&lt;/p&gt;  &lt;p&gt;Con esta aplicación gratuita, podremos disfrutar, ver y compartir nuestras imágenes y videos de SkyDrive en nuestra consola.&lt;/p&gt;  &lt;p&gt;Para ello, basta con acudir al apartado de aplicaciones y la sección social, localizar SkyDrive e instalarla.&lt;/p&gt;  &lt;p&gt;La instalación se realiza en un par de minutos y estaremos preparados para poder utilizarla.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Error 0x80048821&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Sin embargo, nada más arrancar nuestra aplicación podemos tener dos escenarios.&lt;/p&gt;  &lt;p&gt;El primero y esperado es que todo funcione perfectamente.&lt;/p&gt;  &lt;p&gt;El segundo y no esperado, es que de un error… concretamente el error 0x80048821.&lt;/p&gt;  &lt;p&gt;He esperado un tiempo prudencial por si el error se debía a un problema de conexión pero nada de eso, así que me he puesto a buscar si a alguien más le había pasado y efectivamente, no soy el único.&lt;/p&gt;  &lt;p&gt;Por suerte, existe solución, o al menos, a algunos les ha funcionado.&lt;/p&gt;  &lt;p&gt;La solución puede ser encontrada &lt;a href="http://answers.microsoft.com/en-us/windowslive/forum/skydrive-signin/skydrive-on-xbox-sign-in-problems/2d6387d6-7104-4130-b4ff-e46c27f687a7"&gt;en este enlace&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Básicamente, la explicación de la misma es la siguiente (transcribo en inglés que es como está redactada dicha solución):&lt;/p&gt;  &lt;p&gt;&lt;em&gt;&lt;font style="background-color:#ffffff;"&gt;&lt;/font&gt;&lt;/em&gt;&lt;em&gt;&lt;font&gt;If you have changed the password on your Microsoft account since first signing in to your Xbox, you may get a sign in error code of 0x80048821. If so, you need to provide the new password. You can do this by pressing the Xbox Guide button on your controller, then select Chat &amp;amp; IM. Scroll to the right and select Sign In. Enter your Microsoft account password on the next screen. Once you are signed in, restart the app. &lt;/font&gt;&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;&lt;font&gt;&lt;font&gt;If this doesn’t work, or if you renamed your account with the release of Outlook.com, you may need to update your account information. To do this, go to Settings and select the “Profile” tile. Then select “Account Security,” then “Security Proofs” and enter your information. You will need to then restart the app. If this does not resolve sign in for you, please reply below&lt;/font&gt;.&lt;/font&gt;&lt;/em&gt;&lt;em&gt;&lt;font style="background-color:#dfce04;"&gt;&lt;/font&gt;&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;Espero que a alguien más le ayude en caso de encontrarse con este problema.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=207781" width="1" height="1"&gt;</content><author><name>jorge</name><uri>http://geeks.ms/members/jorge/default.aspx</uri></author><category term="Xbox" scheme="http://geeks.ms/blogs/jorge/archive/tags/Xbox/default.aspx" /></entry><entry><title>Error de bloqueo usando las plantillas de iconos en Visio 2013</title><link rel="alternate" type="text/html" href="/blogs/jorge/archive/2012/12/12/error-de-bloqueo-usando-las-plantillas-de-iconos-en-visio-2013.aspx" /><id>/blogs/jorge/archive/2012/12/12/error-de-bloqueo-usando-las-plantillas-de-iconos-en-visio-2013.aspx</id><published>2012-12-12T11:12:00Z</published><updated>2012-12-12T11:12:00Z</updated><content type="html">&lt;p&gt;&lt;img src="http://3.bp.blogspot.com/-PQbwhXZdHuk/UIijlypQksI/AAAAAAAAFIM/9owytc4lg_4/s1600/Microsoft-Visio-Professional-2013.png" width="87" height="87" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Introducción&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Me encuentro delante de mi Microsoft Visio 2013 recién instalado en mi Windows 8, e intentando hacer como otras muchas veces en versiones anteriores de Visio, un nuevo diagrama.&lt;/p&gt;  &lt;p&gt;Para ello, me nutriré como he hecho siempre, de un conjunto de plantillas de iconos o &lt;em&gt;stencils&lt;/em&gt; tal y como he hecho siempre cientos de veces antes.&lt;/p&gt;  &lt;p&gt;Sin embargo, cuando me pongo en disposición de agregar la plantilla de iconos, me encuentro con la siguiente ventana de error:&lt;/p&gt;  &lt;p&gt;&lt;img src="https://cscgrg.sn2.livefilestore.com/y1pKmGGgyL-NIM4TzXKhlh09dqvsljMXLKJo4oCNKfvqpWkuMAFjCccciun8mHV57dse8M02tWk_cR1pdN1PXR9GUTjL_lKB1mX/20121212_01.png?psid=1" width="640" height="246" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;Como podemos apreciar, las plantillas de iconos han sido bloqueadas por seguridad por Visio 2013.&lt;/p&gt;  &lt;p&gt;Indudablemente, lo primero que hacemos es ir a la información de Microsoft y a buscar por Internet alguna posible solución,… e incluso llegamos a pensar que igual deberíamos manipular en el registro de Windows algo, pero nada de nada.&lt;/p&gt;    &lt;p&gt;La solución no obstante es mucho más sencilla, y casi casi es lo que nos apunta en esta página.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;La solución&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Si acudimos a donde la ventana de mensaje anterior de Visio nos indica, observaremos una ventana como la que se indica a continuación:&lt;/p&gt;  &lt;p&gt;&lt;img src="https://fdn3fw.sn2.livefilestore.com/y1p7nF4VElKD5fplaf0qgnGC9KiwGjUlvkZqJLBOtVzjdi7U6FYcqWLYB89qvpLRmDx_-uiJ0aZF6BZPWI6K50u0ckrsFVXrhlG/20121212_02.png?psid=1" width="587" height="480" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;Lo llamativo del asunto no es solamente que podamos seleccionar o quitar la selección de los elementos indicados, sino que por un lado y siguiendo lo que la primera ventana nos indicaba, lo que aquí está seleccionado debería ser suficiente, pero ya hemos visto que no.&lt;/p&gt;  &lt;p&gt;Sin embargo, podemos prestar atención a la parte inferior de la ventana:&lt;/p&gt;  &lt;p&gt;&lt;img src="https://fdn3fw.sn2.livefilestore.com/y1pj-qiQdfJyThQNyIdLYr_l04mLCd5EWBxhrnB0C5p-R4ctVBRC-zhhfPcIWZvKuVW5amBTPYm53GNoWOi967SZ-abzjN-ZyIq/20121212_03.png?psid=1" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;En este punto, nos damos cuenta de que seleccionemos lo que seleccionemos arriba,… abajo nos deja seleccionar claramente una única opción “&lt;em&gt;Do not open selected file types&lt;/em&gt;”… ¡toma ya!.&lt;/p&gt;    &lt;p&gt;Es decir, que da igual lo que hagas, estás jodido… ¿o no?.&lt;/p&gt;  &lt;p&gt;Pues no… no estás jodido, hay una combinación de opciones que lo resuelve.&lt;/p&gt;  &lt;p&gt;Basta con quitar la selección de todos los elementos y una vez hecho esto, podremos agregar nuestras plantillas de iconos o &lt;em&gt;stencils&lt;/em&gt; a Visio 2013 y utilizarlos sin problemas.&lt;/p&gt;  &lt;p&gt;Espero que este pequeño truco ayude a más de uno.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=207774" width="1" height="1"&gt;</content><author><name>jorge</name><uri>http://geeks.ms/members/jorge/default.aspx</uri></author><category term="Office 2013" scheme="http://geeks.ms/blogs/jorge/archive/tags/Office+2013/default.aspx" /></entry><entry><title>StyleCop v4.7.42.0 disponible</title><link rel="alternate" type="text/html" href="/blogs/jorge/archive/2012/12/10/stylecop-v4-7-42-0-disponible.aspx" /><id>/blogs/jorge/archive/2012/12/10/stylecop-v4-7-42-0-disponible.aspx</id><published>2012-12-10T17:00:00Z</published><updated>2012-12-10T17:00:00Z</updated><content type="html">&lt;p&gt;&lt;img border="0" alt="" src="http://megakemp.files.wordpress.com/2009/03/stylecop.png" /&gt;&lt;/p&gt;  &lt;p&gt;Microsoft ha publicado el pasado mes de Noviembre a través de Codeplex una actualización de su herramienta StyleCop.&lt;/p&gt;  &lt;p&gt;En concreto, se trata de la versión 4.7.42.0.&lt;/p&gt;  &lt;p&gt;Podrás acceder a la descarga de esta nueva versión &lt;a href="http://stylecop.codeplex.com/downloads/get/323236"&gt;en este enlace (4.3 Mb)&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Para acceder a la información general sobre StyleCop v4.7, deberás hacer clic &lt;a href="http://stylecop.codeplex.com/releases/view/79972"&gt;en este otro enlace&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Recordad finalmente, para los que tengáis y utilicéis Twitter, que el equipo de trabajo de StyleCop, posee una cuenta en twitter en &lt;a href="https://twitter.com/stylecopdev"&gt;@stylecopdev&lt;/a&gt;.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=207753" width="1" height="1"&gt;</content><author><name>jorge</name><uri>http://geeks.ms/members/jorge/default.aspx</uri></author><category term="Arquitectura" scheme="http://geeks.ms/blogs/jorge/archive/tags/Arquitectura/default.aspx" /><category term=".NET Framework 4.0" scheme="http://geeks.ms/blogs/jorge/archive/tags/.NET+Framework+4.0/default.aspx" /><category term="Visual Studio 2010" scheme="http://geeks.ms/blogs/jorge/archive/tags/Visual+Studio+2010/default.aspx" /><category term=".NET Framework 4.5" scheme="http://geeks.ms/blogs/jorge/archive/tags/.NET+Framework+4.5/default.aspx" /><category term="Visual Studio 2012" scheme="http://geeks.ms/blogs/jorge/archive/tags/Visual+Studio+2012/default.aspx" /></entry><entry><title>Windows Azure Poster</title><link rel="alternate" type="text/html" href="/blogs/jorge/archive/2012/11/25/windows-azure-poster.aspx" /><id>/blogs/jorge/archive/2012/11/25/windows-azure-poster.aspx</id><published>2012-11-25T21:00:00Z</published><updated>2012-11-25T21:00:00Z</updated><content type="html">&lt;p&gt;&lt;img src="http://www.lucidworks.com/sites/default/files/windows-azure.jpg" width="155" height="90" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;Microsoft ha publicado un fichero en formato pdf, que representa un póster con características, servicios y usos comunes.&lt;/p&gt;  &lt;p&gt;El documento, proporciona una descripción de los servicios, separados por categoría.&lt;/p&gt;  &lt;p&gt;Así, se agrupan los detalles y características en servicios de aplicación, servicios de datos, sistema, red y almacenamiento.&lt;/p&gt;  &lt;p&gt;El póster puede ser impreso en un póster de 66 centímetros x 1 metro.&lt;/p&gt;  &lt;p&gt;El documento pdf puede ser descargado &lt;a href="http://www.microsoft.com/en-us/download/details.aspx?id=35473"&gt;desde este enlace (1.1 Mb)&lt;/a&gt;.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=207540" width="1" height="1"&gt;</content><author><name>jorge</name><uri>http://geeks.ms/members/jorge/default.aspx</uri></author><category term="Windows Azure" scheme="http://geeks.ms/blogs/jorge/archive/tags/Windows+Azure/default.aspx" /></entry><entry><title>Windows 8 UX Guidelines for Windows Store</title><link rel="alternate" type="text/html" href="/blogs/jorge/archive/2012/11/25/windows-8-ux-guidelines-for-windows-store.aspx" /><id>/blogs/jorge/archive/2012/11/25/windows-8-ux-guidelines-for-windows-store.aspx</id><published>2012-11-25T20:30:00Z</published><updated>2012-11-25T20:30:00Z</updated><content type="html">&lt;p&gt;&lt;img src="http://i.microsoft.com/global/ImageStore/PublishingImages/logos/56x56/windows_symbol_clr_56x56.png" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;Microsoft ha publicado un documento en formato pdf con las guías de diseño para aplicaciones Windows 8.&lt;/p&gt;  &lt;p&gt;La bondad de este documento es que contiene las guías de estilo y diseño que podemos consultar en la Web, con la facilidad de que podemos leerlo offline con una tableta o incluso imprimirlo.&lt;/p&gt;  &lt;p&gt;Estas guías deben cumplirse para poder diseñar aplicaciones Windows 8 y poder publicarlas en la Windows Store de Microsoft. Así que si estás pensando en desarrollar tus aplicaciones para Windows 8, deberías empezar a conocer este documento y lo que en él se explica.&lt;/p&gt;  &lt;p&gt;El documento tiene un tamaño de unos 3.5 Mb y puede ser descargado &lt;a href="http://www.microsoft.com/en-us/download/details.aspx?id=30704"&gt;desde este enlace&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Si queremos consultar estas guías en línea a través de la página Web, podemos hacerlo &lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh465424.aspx"&gt;a través de este otro enlace&lt;/a&gt;.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=207539" width="1" height="1"&gt;</content><author><name>jorge</name><uri>http://geeks.ms/members/jorge/default.aspx</uri></author><category term="Windows 8" scheme="http://geeks.ms/blogs/jorge/archive/tags/Windows+8/default.aspx" /></entry></feed>