<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://geeks.ms/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"><channel><title>Lucas Ontivero : Desarrollo</title><link>http://geeks.ms/blogs/lontivero/archive/tags/Desarrollo/default.aspx</link><description>Etiquetas: Desarrollo</description><dc:language /><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><item><title>Deberían los testers arreglar bugs–Parte I</title><link>http://geeks.ms/blogs/lontivero/archive/2012/11/15/deber-237-an-los-testers-arreglar-bugs-parte-i.aspx</link><pubDate>Thu, 15 Nov 2012 03:23:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:207429</guid><dc:creator>Lucas Ontivero</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/rsscomments.aspx?PostID=207429</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/commentapi.aspx?PostID=207429</wfw:comment><comments>http://geeks.ms/blogs/lontivero/archive/2012/11/15/deber-237-an-los-testers-arreglar-bugs-parte-i.aspx#comments</comments><description>&lt;p&gt;Esa es &lt;a href="http://sqa.stackexchange.com/questions/5194/should-tester-fix-bugs" target="_blank"&gt;la pregunta&lt;/a&gt; que lanzé en el sitio &lt;a href="http://sqa.stackexchange.com/" target="_blank"&gt;Software Quality Assurance and Testing&lt;/a&gt; de StackExchange.com en cuyas respuestas pude ver que existe cierto desacuerdo entre la comunidad de testers sobre ese tema y si bien yo tengo una idea clara al respecto, lo que en verdad quería conocer eran las argumentaciones de aquellos que piensan que sí deberían arreglar defectos (algunos defectos) y aquellos que piensan que no deberían para así hacer una síntesis. &lt;/p&gt;  &lt;p&gt;No obstante, al poco tiempo otro usuario inicia otro hilo en el que pregunta &lt;a href="http://sqa.stackexchange.com/questions/5097/what-are-the-main-role-and-responsibilities-of-a-tester" target="_blank"&gt;cuales son las principales responsabilidades de un tester&lt;/a&gt; en las que expone una pequeña lista de responsabilidades: &lt;/p&gt;  &lt;pre&gt;&lt;code&gt;1) Analyzing the Requirements from the client
2) Participating in preparing Test Plans
3) Preparing Test Scenarios,test cases
4) Defect Tracking
5) Preparing Suggestion Documents to improve the quality of the application
6) Communication with the Test Lead / Test Manager
7) Conducting Review Meetings within the Team&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Hay tantas cosas con las que no estoy de acuerdo con lo que leo en ese foro que voy a dejar plasmado aquí mi pensamiento. Para comenzar tengo que decir que para mi, la responsabilidad de todos los miembros de un equipo es exactamente la misma: contribuir tanto como sea posible al éxito del proyecto. Entonces, si bien las actividades, especialidades y orientaciones pueden ser distintas, la responsabilidad es la misma.&lt;/p&gt;

&lt;p&gt;Ahora bien, si aceptamos esto como válido deberíamos entonces definir qué es un proyecto exitoso y qué no lo es. Para todos aquellos medio entrado en años (de profesión) como yo de seguro les sonará el cuentito llamado OTOBOS que dice que un proyecto exitoso es un proyecto “on time, on budget, on scope” y la verdad es que en los tiempos del los modelos predictivos, en los que el SDLC era por lo general en cascada, mantener al proyecto a lo largo del tiempo on time, on budget y on scope era cosa de magos, se creía que la clave estaba en el *control*. Pues bien, puede que me equivoque pero voy a darles *mi* definición de lo que es un proyecto exitoso: &lt;/p&gt;

&lt;blockquote&gt;
  &lt;p align="center"&gt;&lt;em&gt;&lt;font color="#cccccc" size="4"&gt;“Un proyecto exitoso es aquel que nos otorga un alto retorno sobre la inversión a la vez que nos permite crear una relación de confianza con el cliente”&lt;/font&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p align="center"&gt;&lt;em&gt;&lt;font size="4"&gt;&lt;/font&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;La segunda parte de esta definición habla de la satisfacción del cliente, y puesto que lo que este recibe no es otra cosa que software, deberíamos aclarar qué es un software exitoso para el cliente. Veamos, nuestros clientes no nos encargan el desarrollo de una solución porque no se les ocurran mejores cosas en que despilfarrar el dinero, sino que lo invierten en una herramienta que les permita cumplir con sus metas de negocio. Ya sea optimizando o agilizando la gestión de la compañia, diferenciandose de la competencia, fidelizando clientes, brindando nuevos servicios online o alguna otra ventaja, las empresas *invierten* en software y esperan un retorno de esa inversión. Entonces:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p align="center"&gt;&lt;font color="#cccccc" size="4"&gt;&lt;em&gt;“Un software exitoso (para el cliente) es aquel que le permite cumplir con sus metas de negocios y por tal, le otorga el esperado retorno sobre la inversión” &lt;/em&gt;&lt;/font&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Y es que de eso se trata y siempre se ha tratado, de dinero. Por lo tanto, la responsabilidad de *todos los miembros del equipo* (sí, testers incluidos) es contribuir a este éxito. Y para esto hace falta mucho más que control y responsabilidades estrictas y predeterminadas.&lt;/p&gt;

&lt;p&gt;Continuará…&lt;/p&gt;

&lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:a842d013-bfb5-4c47-bb5b-12f95046a2ac" class="wlWriterEditableSmartContent"&gt;del.icio.us Tags: &lt;a href="http://del.icio.us/popular/software+testing" rel="tag"&gt;software testing&lt;/a&gt;,&lt;a href="http://del.icio.us/popular/bug+fixing" rel="tag"&gt;bug fixing&lt;/a&gt;,&lt;a href="http://del.icio.us/popular/testers+roles" rel="tag"&gt;testers roles&lt;/a&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=207429" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Project+Management/default.aspx">Project Management</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Gesti_26002300_243_3B00_n+de+proyectos/default.aspx">Gesti&amp;#243;n de proyectos</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Desarrollo/default.aspx">Desarrollo</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Conceptos/default.aspx">Conceptos</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Productividad/default.aspx">Productividad</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Testing/default.aspx">Testing</category></item><item><title>Lo que espero de un buen desarrollador</title><link>http://geeks.ms/blogs/lontivero/archive/2012/11/13/lo-que-espero-de-un-buen-desarrollador.aspx</link><pubDate>Tue, 13 Nov 2012 04:15:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:207397</guid><dc:creator>Lucas Ontivero</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/rsscomments.aspx?PostID=207397</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/commentapi.aspx?PostID=207397</wfw:comment><comments>http://geeks.ms/blogs/lontivero/archive/2012/11/13/lo-que-espero-de-un-buen-desarrollador.aspx#comments</comments><description>&lt;p&gt;El buen desarrollador, además de poseer conocimientos y experiencia superiores debe estar infectado por una pasión altamente contagiosa, de esa manera, tarde o temprano el equipo completo se verá contagiado en mayor o menor medida. Esto no es tan inusual, muchas veces nos encontramos con personas que se convierten en referentes no solo de sus equipos sino que también de otros equipos de la misma empresa y todos se benefician de sus conocimientos y su dedicación, especialmente la de enseñar, compartir conocimientos y experiencias… esas cosas que no se encuentran en los libros.&lt;/p&gt;  &lt;p&gt;La mayor contribución de estos desarrolladores no suele plasmarse tanto en su código sino en la capacidad de hacer de otros, mejores desarrolladores. Y es que como la experiencia no se adquiere de los libros sino de los errores (no solo propios), es este tipo de desarrolladores el que puede salvar a los menos experimentados de cometerlos. Por último, y para ampliar el punto anterior, otra cualidad necesaria para lograr esto es el conocimiento profundo de la história del software, sus personalidades, sus aportes, sus pensamientos, sus aciertos y errores.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=207397" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Misc/default.aspx">Misc</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Desarrollo/default.aspx">Desarrollo</category></item><item><title>Cómo fallar en el desarrollo – distinguiendo lo importante de lo accesorio</title><link>http://geeks.ms/blogs/lontivero/archive/2012/11/04/c-243-mo-fallar-en-el-desarrollo-distinguiendo-lo-importante-de-lo-accesorio.aspx</link><pubDate>Sun, 04 Nov 2012 03:38:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:207314</guid><dc:creator>Lucas Ontivero</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/rsscomments.aspx?PostID=207314</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/commentapi.aspx?PostID=207314</wfw:comment><comments>http://geeks.ms/blogs/lontivero/archive/2012/11/04/c-243-mo-fallar-en-el-desarrollo-distinguiendo-lo-importante-de-lo-accesorio.aspx#comments</comments><description> &lt;a href="http://martinfowler.com" target="_blank"&gt;Martin Fowler&lt;/a&gt;&lt;/a&gt; escribió un interesante artículo llamado &lt;a href="http://martinfowler.com/bliki/TransMediaApplication.html" target="_blank"&gt;TransMediaApplication&lt;/a&gt; en el cual explica un problema común que se presenta a la hora de desarrollar aplicaciones para distintos dispositivo. Creo que esta frase resume todo el artículo: &lt;i&gt;A common mistake is to think of different apps for different delivery devices.&lt;/i&gt;    &lt;p&gt;En mi experiencia este escenario no se presenta solo cuando se trata de aplicaciones que corren en distintos dispositivos sino que se presenta con mucha mayor frecuencia de lo que se cree. El caso es que lo que &lt;a href="http://martinfowler.com" target="_blank"&gt;Martin Fowler&lt;/a&gt; describe es un caso muy particular de un problema mayor: no comprender de que se trata en parte la arquitectura.&lt;/p&gt;  &lt;p&gt;Lo voy a explicar con un ejemplo. Imaginemos que una empresa de transporte de carga nos pide desarrollar un sistema de seguimiento de sus vehículos. Estos vehículos tienen rutas específicas por las que deben transitar y tienen además una velocidad máxima autorizada. Nuestro cliente quiere conocer la ubicación de cada uno de sus camiones y sus velocidades (entre otras miles de cosas) prácticamente en tiempo real o con una demora no mayor a 1 minuto. &lt;/p&gt;  &lt;p&gt;Para esto, cada vehículo tiene incorporado algún tipo de dispositivo móvil con GPS (o alguna variante). Nuestro cliente quiere visualizar la posición de sus vehículos en un mapa (en principio, mapas de google) y quiere poder hacerlo desde su dispositivo móvil.&lt;/p&gt;  &lt;p&gt;Ahora bien, si quien lee esto fuese el responsable del desarrollo de este sistema… ¿por donde comenzaría?. Muchas personas comienzan por interiorizarse sobre los distintos modelos de dispositivos móviles incorporados a los vehículos, comienzan a interiorizarse por los diferentes sistemas de coordenadas que manejan, por los distintos mecanismos de despacho de esas coordenadas, esto es, si tienen conexión a internet continua, si soportan mensajes SMS, si http, tcp o udp, por los servicios que soportan en cada uno de sus puertos, etc. Luego, continúan por estudiar las apis de google maps, los lenguajes en los que esas apis están disponibles y demás consideraciones sobre cómo trabajar con esos mapas. Por último posiblemente, querrán conocer desde que tipo de dispositivo móvil es que el cliente quiere poder consultar la información. &lt;/p&gt;  &lt;p&gt;Todo lo anterior está mal! No quiero decir que no deba hacerse ya que tarde o temprano conocer estas cosas será muy necesario, pero está mal porque denota una falta de análisis reflexivo sobre qué es lo que se debe desarrollar y sobre qué es lo que el cliente (negocio) necesita. Veamos, en la descripción del problema existen varios elementos que debemos notar y sobre los que tenemos que reflexionar, estos son: seguimiento, rutas, posición, velocidad, vehículo, dispositivo móvil, GPS y mapa. Existen otros elementos mencionados directa o indirectamente, pero quiero focalizarme solo estos. &lt;/p&gt;  &lt;p&gt;A estos elementos debemos agruparlos en dos categorías: esenciales y accidentales. Así, posición, ruta, velocidad y seguimiento son esenciales mientras que dispositivo móvil, GPS y mapa son accidentales. Vehículo, por su parte, es un sinsentido. Si bien por alguna razón, las descripciones de los problemas que nos proveen los clientes suelen abundar en elementos accidentales, es nuestra responsabilidad el identificarlos y catalogarlos como tales en primera instancia. &lt;/p&gt;  &lt;p&gt;El sistema a desarrollar debe, en principio, ser totalmente independiente de consideraciones superfluas como el protocolo de comunicación por medio del cual recibirá la posición de los vehículos. Si lo hace mediante TCP, UDP, por mensajes SMS o por correo twitter no es relevante en principio. Tampoco lo es la manera en que la información será presentada, ni si los clientes corren en dispositivos móviles o en PCs de escritorio, sobre un web browser o una aplicación nativa. Todas estas cosas deberán abordarse en su momento pero es importante comprender que se debe esperar a que llegue ese momento.&lt;/p&gt;  &lt;p&gt;¿Y mientras tanto qué? Bueno, mientras no llegue el momento de encarar los detalles debemos centrarnos en resolver el problema esencial: desarrollar el sistema de seguimiento. Esto es lo primero! &lt;/p&gt;  &lt;p&gt;En el software como en la vida, no distinguir lo importante de lo accesorio es el camino seguro al fracaso.&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:42e71fa7-62f5-445e-a1dc-832222a9323d" class="wlWriterEditableSmartContent"&gt;del.icio.us Tags: &lt;a href="http://del.icio.us/popular/software" rel="tag"&gt;software&lt;/a&gt;,&lt;a href="http://del.icio.us/popular/arquitectura" rel="tag"&gt;arquitectura&lt;/a&gt;,&lt;a href="http://del.icio.us/popular/desarrollo" rel="tag"&gt;desarrollo&lt;/a&gt;,&lt;a href="http://del.icio.us/popular/dise%c3%b1o" rel="tag"&gt;dise&amp;#241;o&lt;/a&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=207314" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Arquitectura/default.aspx">Arquitectura</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Dise_26002300_241_3B00_o/default.aspx">Dise&amp;#241;o</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Desarrollo/default.aspx">Desarrollo</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Conceptos/default.aspx">Conceptos</category></item><item><title>Design patterns in the test of time: VISITOR</title><link>http://geeks.ms/blogs/lontivero/archive/2012/10/30/design-patterns-in-the-test-of-time-visitor.aspx</link><pubDate>Tue, 30 Oct 2012 04:46:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:207265</guid><dc:creator>Lucas Ontivero</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/rsscomments.aspx?PostID=207265</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/commentapi.aspx?PostID=207265</wfw:comment><comments>http://geeks.ms/blogs/lontivero/archive/2012/10/30/design-patterns-in-the-test-of-time-visitor.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://ayende.com/blog/" target="_blank"&gt;@Ayende&lt;/a&gt; ha comenzado una &lt;a href="http://ayende.com/blog/tags/design-patterns-test-of-time" target="_blank"&gt;serie de post en lo que revisa algunos patrones de diseño&lt;/a&gt; (Go4) luego de transcurridos más de 18 años desde su formalización en el libro &lt;a href="http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612" target="_blank"&gt;Design Patterns: Elements of Reusable Object-Oriented Software&lt;/a&gt;.&amp;#160; Inspirado por esa serie, y por el hecho de que en mi última entrevista laboral me preguntaron sobre esto,&amp;#160; voy a presentar una revisión sobre el patrón visitor.&lt;/p&gt;  &lt;h1&gt;&amp;#160;&lt;/h1&gt;  &lt;h1&gt;Visitor en su forma clásica&lt;/h1&gt;  &lt;p&gt;La motivación detrás de este patrón es poder añadir funcionalidad a una estructura de datos sin necesidad de modificar las clases que conforman esa estructura. En otras palabras: separar las estructuras de datos de aquellos algoritmos que operan sobre ellas. Si vamos a la Wikipedia vamos a ver este diagrama:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://upload.wikimedia.org/wikipedia/commons/5/59/VisitorPatternUML.png" width="640" height="366" alt="" /&gt;    &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:cffd77cf-ec12-4d23-9593-d382195dca33" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/Design" rel="tag"&gt;Design&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Pattern" rel="tag"&gt;Pattern&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Visitor" rel="tag"&gt;Visitor&lt;/a&gt;&lt;/div&gt; &lt;/p&gt;  &lt;p&gt;Como se ve, tiene referencias cíclicas, es decir, todos los CarElements deben implementar un método accept que recibe una referencia a un CarElementVisitor y todo CarElementVisitor matiene referencias a todos los tipos que implementan la interface CarElement. Esto es porque C# (el diagrama usa java) no posibilida doble dispatch y así, mediante estas referencias cíclicas es cómo se logra simularla.&lt;/p&gt;  &lt;p&gt;Aparte del fuertísimo acoplamiento al que nos fuerza, tiene el inconveniente de ser un patrón que agrega bastante complejidad y que es poco legible debido a su “extraña” sintaxis. Así, si tuviésemos un AST y quisiésemos volverlo código mediante un visitor, nuestro código se vería así:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_1506DE1F.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_10CCE08D.png" width="401" height="31" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Pero si tratamos de seguir este código, y vamos directamente a la implementación de este método ‘Accept’ nos encontraremos con esto:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_16A78426.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_7B8EB517.png" width="401" height="74" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Y por último, si nos salteamos la abstracción IVisitor y vamos directamente a la implementación del método Visit del PrinterVisitor, nos encontramos con esto otro:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_0573A683.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_2AFD23E4.png" width="401" height="104" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Si no conoces el patrón, posiblemente no comprendas este código (y tengamos en cuenta que nos hemos salteado las abstracciones!). Pero el motivo más frecuente por el que no se entiende, si es ese el caso, es porque es complejo.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;Visitor alternativo&lt;/h1&gt;  &lt;p&gt;La propuesta que dejo no es mia, ni es nueva. Esta es una implementación muy popular en lenguajes dinámicos.&lt;/p&gt;  &lt;p&gt;Partamos del mismo supuesto: tenemos un AST al que queremos transformar en un string. Lo primero que podemos cambiar es la sintaxis confuza del visitor clásico mediante el uso de un Extension Method, como sigue:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_4F420866.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_161B0597.png" width="401" height="194" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Ahora veamos cómo se ven los nodos de este árbol:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_451D416E.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_5755E263.png" width="401" height="278" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Si bien aquí tenemos una interface INode la cual no luce muy bien, la simplicidad de los nodos es evidente ya que no estamos forzando a implementar ningún método extraño, me refiero al método ‘Accept’. Peo vamos a ver la implementación:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_680D6744.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_75AFFD7F.png" width="583" height="532" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Esta implementación es mucho menos compleja y legible, además de reducir notablemente el acoplamiento (los nodos no necesitan conocer al IVisitor ni implementar ningún método extra) lo que posibilita eliminar las referencias cíclicas. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Lucas Ontivero&lt;/strong&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=207265" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patterns/default.aspx">Patterns</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Arquitectura/default.aspx">Arquitectura</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Dise_26002300_241_3B00_o/default.aspx">Dise&amp;#241;o</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/.Net/default.aspx">.Net</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Languages/default.aspx">Languages</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patrones/default.aspx">Patrones</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Desarrollo/default.aspx">Desarrollo</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Conceptos/default.aspx">Conceptos</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Clean+Code/default.aspx">Clean Code</category></item><item><title>C# Closures y tipos anónimos a la Javascript</title><link>http://geeks.ms/blogs/lontivero/archive/2012/05/24/c-closures-y-tipos-an-243-nimos-a-la-javascript.aspx</link><pubDate>Thu, 24 May 2012 05:13:28 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:205199</guid><dc:creator>Lucas Ontivero</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/rsscomments.aspx?PostID=205199</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/commentapi.aspx?PostID=205199</wfw:comment><comments>http://geeks.ms/blogs/lontivero/archive/2012/05/24/c-closures-y-tipos-an-243-nimos-a-la-javascript.aspx#comments</comments><description>&lt;p&gt;Es C# realmente dinámico? Si hace Cuac es un pato, si hace lo mismo que un lenguaje dinámico es dinámico. Qué te dice este código:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_605E376E.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_57418620.png" width="586" height="590" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=205199" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patterns/default.aspx">Patterns</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Dise_26002300_241_3B00_o/default.aspx">Dise&amp;#241;o</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Languages/default.aspx">Languages</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patrones/default.aspx">Patrones</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Desarrollo/default.aspx">Desarrollo</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Conceptos/default.aspx">Conceptos</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>Nivelando para abajo</title><link>http://geeks.ms/blogs/lontivero/archive/2012/05/24/nivelando-para-abajo.aspx</link><pubDate>Thu, 24 May 2012 03:44:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:205197</guid><dc:creator>Lucas Ontivero</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/rsscomments.aspx?PostID=205197</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/commentapi.aspx?PostID=205197</wfw:comment><comments>http://geeks.ms/blogs/lontivero/archive/2012/05/24/nivelando-para-abajo.aspx#comments</comments><description>&lt;p&gt;Leía &lt;a href="http://geeks.ms/blogs/lruiz/archive/2012/05/22/pregunta-191-cu-225-l-es-la-salida-de-este-programa.aspx"&gt;este post de Luis Ruiz Pavon&lt;/a&gt; acerca del comportamiento de los closures en el que Luis anima a responder cual es la salida de un bloque de código en el que se devuelve un array de expresiones lambdas que referencian a la variable utilizada para iterar dicho array (closures) y entonces veo este comentario de &lt;a href="http://geeks.ms/user/Profile.aspx?UserID=5172"&gt;Eduard Tomàs i Avellana&lt;/a&gt;:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_31F5FFF4.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_5E5EE440.png" width="640" height="123" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;El link al que referencia Eduard pertenece al blog de Eric Lippert: &lt;a href="http://blogs.msdn.com/b/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspx"&gt;Closing over the loop variable considered harmful&lt;/a&gt;, una vieja entrada que había leído en su oportunidad pero que desestimé porque nunca pensé que llegara a tomarse la decisión de introducir un breaking change en el lenguaje para solucionar algo que &lt;strong&gt;NO ESTÁ ROTO&lt;/strong&gt;, repito,&lt;strong&gt; NO ESTÁ ROTO&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;Está claro que introducir este tipo de cambios no le gusta a nadie, y que por lo tanto debe de haberse meditado, y mucho. Pero ¿qué es lo que anima semejante cosa? Es decir, si vamos a romperle el código a muchos programadores es porque pensamos que es lo mejor para todos, ¿o no?&lt;/p&gt;  &lt;p&gt;Veamos, ¿quiénes pueden verse afectados? de seguro todos aquellos que entiendan lo que son los closures y comprendan el scope de las variables y, ¿quienes pueden verse beneficiados? pues todos aquellos que no entienden esto. Y es por eso que estoy en desacuerdo, porque lo que se intenta una vez más es hacer que el lenguaje sea el guardián de la correctitud del software y no el desarrollado.&lt;/p&gt;  &lt;p&gt;En mi experiencia, &lt;strong&gt;es absolutamente imposible defenderse de un desarrollador que no sabe lo que hace&lt;/strong&gt;. &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=205197" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Desarrollo/default.aspx">Desarrollo</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Conceptos/default.aspx">Conceptos</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>ECMA Harmony y la conquista del mundo</title><link>http://geeks.ms/blogs/lontivero/archive/2012/05/12/ecma-harmony-y-la-conquista-del-mundo.aspx</link><pubDate>Sun, 13 May 2012 00:13:45 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:204991</guid><dc:creator>Lucas Ontivero</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/rsscomments.aspx?PostID=204991</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/commentapi.aspx?PostID=204991</wfw:comment><comments>http://geeks.ms/blogs/lontivero/archive/2012/05/12/ecma-harmony-y-la-conquista-del-mundo.aspx#comments</comments><description>&lt;p&gt;Dicen que existe un plan para que javascript domine el mundo en los próximos años, y a decir verdad, y viendo las propuestas que se plasman en el draf del ECMA-262 sexta edición, creo que el plan aunque algo silencioso sigue a marcha firme.&lt;/p&gt;  &lt;p&gt;Quiero mostrar aquellas propuestas que a mi me resultan más interesantes:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Strings&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Lo bueno: se agregan métodos startsWith(), endsWith(), contains(), repeat(), toArray()&lt;/p&gt;  &lt;p&gt;Lo malo: la interpolación de strings no forma parte del draft actual, esta feature permitiría crear string de manera más natural, como por ejemplo:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_0CEAA143.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_41C780B3.png" width="540" height="66" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;en lugar de usar las formas actuales:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_6B5B4BE6.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_3ED21C00.png" width="640" height="38" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Destructuring&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Esta es una de mis preferidas y permitiría entre otras cosas que una función retorne más de un resultado:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_4F6A16EE.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_74F3944F.png" width="559" height="52" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Iterar las propiedades de los objetos de manera más natural:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_0181416C.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_1FEB8255.png" width="443" height="36" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;y quien sabe cuantas cosas más!&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Iterators&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;for-of para iterar sobre los valores de las propiedades en lugar de hacerlo sobre las propiedades es sí mismas.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_40AF453C.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_13B9E261.png" width="433" height="119" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Generators&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Esto nos tienen que resultar familiar a todos, solo hace falta ver el yield para darse cuenta de cómo funciona. Exactamente como se hace en .Net. Ahora podríamos por agregarle al prototype una función where, por ejemplo, para evaluar un predicado contra cada uno de los elementos del iterador y listo, tendremos linq en ECMAScript. (pero mejor ver Array comprehension)&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_0436D092.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_5BB7EE7D.png" width="272" height="176" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Lo mismo pero quizás más claro y conveniete puede realizarse con un Generator comprehension:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_071C0F78.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_690DDBB6.png" width="479" height="144" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Lambdas&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Aunque actualmente no forma parte del draft de la versión 6, la discusión está vida. No hay que explicar nada.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_4D88D9B3.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_17A3E499.png" width="228" height="22" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Array comprehension&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_6B86E7A7.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_1586E5D0.png" width="446" height="23" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;¿Quien no entiende esto? es un generator que retorna los cuadrados de los números pares de numbers.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Let&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Si bien la idea detrás de la sintaxis de javascript era parecerse a java, pocos lenguajes se parecen tan poco. El scope de las variables en javascript es la función y no el code block como en java. Let es justamente para limitar el scope al code block.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_5478666B.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_66E0B720.png" width="326" height="156" /&gt;&lt;/a&gt;&amp;#160;&lt;/p&gt;                          &lt;p&gt;Estas son solo unas pocas de las propuestas que se discuten actualmente y que me han gustado más. Otras más importantes quizás sean las de modularidad del lenguaje, pragmas y API, pero a mi me gustan las que tratan sobre la expresividad del lenguaje y la verdad es que con estas y otras propuestas tomadas de ruby y python, ECMAScript va a dar un lindo paso en su plan de conquista del mundo.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=204991" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Dise_26002300_241_3B00_o/default.aspx">Dise&amp;#241;o</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Languages/default.aspx">Languages</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Investigaciones/default.aspx">Investigaciones</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Desarrollo/default.aspx">Desarrollo</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Clean+Code/default.aspx">Clean Code</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/javascript/default.aspx">javascript</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/ECMAScript/default.aspx">ECMAScript</category></item><item><title>Infraestructura</title><link>http://geeks.ms/blogs/lontivero/archive/2012/04/17/infraestructura.aspx</link><pubDate>Tue, 17 Apr 2012 19:52:05 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:204516</guid><dc:creator>Lucas Ontivero</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/rsscomments.aspx?PostID=204516</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/commentapi.aspx?PostID=204516</wfw:comment><comments>http://geeks.ms/blogs/lontivero/archive/2012/04/17/infraestructura.aspx#comments</comments><description>&lt;p&gt;Por qué es necesario empujar tantos conceptos a la infaestructura como sea posible.&lt;/p&gt;  &lt;p&gt;&lt;object style="height:390px;width:640px;"&gt;&lt;param name="movie" value="http://www.youtube.com/v/9oSh2IZ88mU?version=3&amp;amp;feature=player_detailpage"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowScriptAccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/9oSh2IZ88mU?version=3&amp;amp;feature=player_detailpage" type="application/x-shockwave-flash" allowscriptaccess="always" width="640" height="360"&gt;&lt;/object&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=204516" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patterns/default.aspx">Patterns</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Arquitectura/default.aspx">Arquitectura</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Dise_26002300_241_3B00_o/default.aspx">Dise&amp;#241;o</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patrones/default.aspx">Patrones</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Desarrollo/default.aspx">Desarrollo</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Conceptos/default.aspx">Conceptos</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Refactoring/default.aspx">Refactoring</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Exceptions/default.aspx">Exceptions</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Clean+Code/default.aspx">Clean Code</category></item><item><title>Cómo crear un Compact Framework (I)</title><link>http://geeks.ms/blogs/lontivero/archive/2012/02/10/crear-un-compact-framework-i.aspx</link><pubDate>Fri, 10 Feb 2012 21:17:46 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:203297</guid><dc:creator>Lucas Ontivero</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/rsscomments.aspx?PostID=203297</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/commentapi.aspx?PostID=203297</wfw:comment><comments>http://geeks.ms/blogs/lontivero/archive/2012/02/10/crear-un-compact-framework-i.aspx#comments</comments><description>&lt;p&gt;Imaginemos los siguientes escenarios:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;tenemos un gran framework super completo del cual queremos obtener una versión más pequeña para correr en dispositivos móviles, y tenemos que quitar ciertas características que el dispositivo no soporta. Además la idea del concepto de “Compact” Framework también hace referencia al tamaño, por lo que queremos eliminar todo el código del las características no soportadas. &lt;/li&gt;    &lt;li&gt;queremos lanzar varias versiones de nuestra aplicación como Free Edition, Profesional Edition, Enterprise Edition, y no deseamos que en cada una de las ediciones solo vaya el código necesario para esa edición (y no todo). &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;¿Cómo lo hacemos?&lt;/p&gt;  &lt;p&gt;La idea que propongo, si bien no es original ya que tengo entendido que .Net Compact Framework se ha realizado con una técnica similar, es simplemente identificar en los assemblies todos aquellos fragmentos de código (IL) que se utilizan para implementar las características deseadas y una vez conocido esto, eliminar el resto. Es decir, eliminar todos los métodos, propiedades, campos, eventos, tipos y demás elementos que no tomen parte en la realización de las características que queremos.&lt;/p&gt;  &lt;p&gt;Por ejemplo:&lt;/p&gt;  &lt;p&gt;En un procesador de texto tenemos 2 features: Save y Print. Y la interacción como se ve abajo.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_33E2B149.png"&gt;&lt;img style="background-image:none;border-right-width:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_51D09970.png" width="688" height="298" /&gt;&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Del diagrama queda claro que no todas las funcionalidades hacen uso de todos los tipos ni de todos los métodos ni de todas las propiedades, etc. Entonces, si solo quisiésemos permitir guardar un documento, sería seguro eliminar los tipos DocumentReader y Printer, verdad?&lt;/p&gt;  &lt;p&gt;Esto es posible hacerlo reescribiendo los ensamblados con Mono.Cecil, solo hay que conocer algo de IL para hacer cosas sencillas aunque para hacerlo realmente bien hay que conocer IL a la perfección.&lt;/p&gt;  &lt;p&gt;Veamos el código del ejemplo del cual queremos eliminar la feature que permite imprimir es documento.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_716F4D6B.png"&gt;&lt;img style="background-image:none;border-right-width:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_00C2AF7B.png" width="370" height="325" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Ahora bien, antes de continuar quiero mostrar el resultado de como queda el assembly antes y después de ser procesado:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_59E4736D.png"&gt;&lt;img style="background-image:none;border-right-width:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_2346A25C.png" width="586" height="674" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Lo que se eliminó es la posibilidad de imprimir y por eso, en el assembly procesado no existe el método TargetClass.Print(), ni los field _reader y printer ya que estos solo eran usados por el método TargetClass.Print(). Los tipos Printer y DocumentReader también han sido eliminados ya que no eran usados por otro método más que el TargetClass.Print(). &lt;/p&gt;  &lt;p&gt;Por otra parte, todos los tipos, campos, propiedades y eventos que son utilizados por otras características, aún cuando sean utilizados además por el TargetClass.Print(), permanecen intactos. Para esto solo hace falta comprobar que la clase Document aún sigue allí (aunque modificada ya que la propiedad Title se ha quitado porque solo era relevante al imprimir).&lt;/p&gt;  &lt;p&gt;Bien, la idea entonces es que una vez que conocemos cuales son los métodos que implementan las features que deseamos mantener, la técnica consiste en seguir todas y cada una de las llamadas que ese método realiza. Luego, hacer lo mismo con cada uno de estos de manera recursiva hasta tener la lista de todos los métodos que participan en la realización de la características deseada. Abajo puede verse el mecanismo:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_75B55CCB.png"&gt;&lt;img style="background-image:none;border-right-width:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_0B4F9569.png" width="539" height="259" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Y con esto ya tenemos el listado de todos los métodos usados, ahora lo que hacemos es eliminar todos aquellos métodos que no se encuentren en la lista:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_611FE780.png"&gt;&lt;img style="background-image:none;border-right-width:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_17AD92C5.png" width="294" height="146" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Esto elimina todos los métodos no usados incluyendo getters, setters, los add y remove de los eventos. Por esta razón es que de seguro nos quedan propiedades sin gettes ni setters y que por lo tanto tenemos que eliminar para que el ensamblado nos quede funcional.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_6E09A1C4.png"&gt;&lt;img style="background-image:none;border-right-width:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_30993D3D.png" width="448" height="131" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Por último, si existen clases sin métodos, ni campos, ni propiedades ni eventos… la eliminamos también.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_43018DF2.png"&gt;&lt;img style="background-image:none;border-right-width:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_486FFE96.png" width="522" height="120" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Como esto es solo una prueba de concepto, quizás cambie muchas cosas en el código, voy a continuar con la explicación en la siguiente entrada.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=203297" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Arquitectura/default.aspx">Arquitectura</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/.Net/default.aspx">.Net</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Desarrollo/default.aspx">Desarrollo</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Conceptos/default.aspx">Conceptos</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Herramientas/default.aspx">Herramientas</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Mono.Cecil/default.aspx">Mono.Cecil</category></item><item><title>Patrón repetido en MVC. Mi propuesta</title><link>http://geeks.ms/blogs/lontivero/archive/2012/02/08/patr-243-n-repetido-en-mvc-mi-propuesta.aspx</link><pubDate>Wed, 08 Feb 2012 06:20:43 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:203251</guid><dc:creator>Lucas Ontivero</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/rsscomments.aspx?PostID=203251</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/commentapi.aspx?PostID=203251</wfw:comment><comments>http://geeks.ms/blogs/lontivero/archive/2012/02/08/patr-243-n-repetido-en-mvc-mi-propuesta.aspx#comments</comments><description>&lt;p&gt;Cuando usamos ASP.MVC uno de los patrones que debemos respetar es el de “Un modelo entra, un modelo sale” y otro muy común es el de validar el modelo y si este no es válido devolverle la misma vista al usuario para que corrija los datos de entrada. Por esto es común ver el siguiente patrón:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_6921C6C4.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_6A36AFE3.png" width="489" height="179" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;¿Qué está mal aquí? ¿Lo ves?&lt;/p&gt;  &lt;p&gt;Lo que está mal es que este patrón se repite en cada una de las acciones de cada uno de los controladores de cada una de las aplicaciones que hacemos con MVC Framework y eso huele muy pero muy mal (DRY).&lt;/p&gt;  &lt;p&gt;Este es el tipo de casos en los que puede ayudarnos AOP, y MVC framework hace un trabajo espectacular al posibilitarnos implementar AOP mediante filtros. Entonces mi idea es que esto debería hacerse así:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_47263E73.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_22D13424.png" width="462" height="115" /&gt;&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Ahora sí el método hace lo que tiene que hacer, ni más ni menos. Para esto (y solo para demostrar mi punto) he creado el atributo ModelValidationAttribute (necesita un mejor nombre!) como sigue:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_463DB2BC.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_1797840D.png" width="544" height="288" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Y esto funciona a la perfección! Ojo, no recomiendo usarlo sin antes hacer una buena implementación ya que le faltan cosas al ViewResult como TempData entre otras (y el OnActionExecuted vacio tiene un olorcito medio feo – pero no es culpa mia! ¿por qué el creador de la interface IActionFilter me obliga a incumplir el contrato? ¿No serán 2 interfaces distintas [LSP]?)&lt;/p&gt;  &lt;p&gt;Bueno, esto como les dije funciona a la perfección. La prueba:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_71257AF4.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_125570D1.png" width="440" height="80" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Saludos.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=203251" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patterns/default.aspx">Patterns</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Dise_26002300_241_3B00_o/default.aspx">Dise&amp;#241;o</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/.Net/default.aspx">.Net</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patrones/default.aspx">Patrones</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Desarrollo/default.aspx">Desarrollo</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Conceptos/default.aspx">Conceptos</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Refactoring/default.aspx">Refactoring</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Clean+Code/default.aspx">Clean Code</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/ASP.MVC/default.aspx">ASP.MVC</category></item><item><title>10 consejos para que no te crackeen tan fácil</title><link>http://geeks.ms/blogs/lontivero/archive/2012/02/05/10-consejos-para-que-no-te-crackeen-tan-f-225-cil.aspx</link><pubDate>Sun, 05 Feb 2012 18:10:33 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:203191</guid><dc:creator>Lucas Ontivero</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/rsscomments.aspx?PostID=203191</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/commentapi.aspx?PostID=203191</wfw:comment><comments>http://geeks.ms/blogs/lontivero/archive/2012/02/05/10-consejos-para-que-no-te-crackeen-tan-f-225-cil.aspx#comments</comments><description>&lt;p&gt;Crackear una aplicación tiene algo de arte y de ingenio pero crackear una aplicación .Net es demasiado sencillo para mi gusto, y representa un problema para la empresa o desarrollador que la comercializa y vive de mantener y mejorar el producto. Ya no vale eso de “total quien se va a dar cuenta”, eso no es válido para ninguna aplicación pero esto es aún peor cuando se trata de herramientas de desarrollo de software las cuales serán utilizadas por profesionales que conocen como pueden saltearse los sistemas de licencias.&lt;/p&gt;  &lt;p&gt;Hoy, con todas las herramientas de que disponemos en .Net (ILSpy y sus addins de debugging, Cecil, RegSpy, entre otros) saltearse estas validaciones es demasiado sencillo. Por eso quiero hacer algunas pocas recomendaciones que si bien no pueden por si solas detener a quien se lo proponga, por lo menos le dificultará un poco la tarea. Esto es importante desde mi punto de vista ya que si debo invertir una semana para crackear una aplicación quizás me convenga comprarla.&lt;/p&gt;  &lt;p&gt;Aquí van:&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;strong&gt;1. Firma los ensamblados&lt;/strong&gt;&lt;/font&gt;. Esto hará que no puedan reemplazarlo por otro o reescribirlo; caso contrario lo único que debe hacer alguien para saltearse las validaciones es reescribir algún método y listo. Para ilustrar esto veamos un ejemplo, imaginemos que tenemos una clase encargada de verificar la licencia del usuario llamada &lt;em&gt;&lt;strong&gt;LicenseChecker&lt;/strong&gt;&lt;/em&gt; la cual tiene un método &lt;strong&gt;&lt;em&gt;CheckLicense&lt;/em&gt;&lt;/strong&gt; que retorna TRUE si la licencia es válida y FALSE en caso contrario. En este caso, solo bastaría con reescribir el método insertándole un &lt;strong&gt;&lt;em&gt;return true. (ldc.i4.1 ret) &lt;/em&gt;&lt;/strong&gt;Abajo puede verse lo ridículamente sencillo que es lograr esto con Cecil.&lt;strong&gt;&lt;em&gt;&amp;#160;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_288F7750.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_2F9E8DFB.png" width="528" height="255" /&gt;&lt;/a&gt;    &lt;br /&gt;    &lt;br /&gt;Del mismo modo, no guardes información valiosa en constantes publicas ya que de la misma manera, se puede modificar sus valores. Por ejemplo, imagina que en una clase &lt;strong&gt;&lt;em&gt;LicenseConstants&lt;/em&gt;&lt;/strong&gt; tenemos un field llamado TrialDays con un valor de 30 que se asigna en el constructor estático en la instrucción nro. 10. en este caso, lo más sencillo será sobrescribir el assembly para asignarle un valor mayor y así extender el período de prueba tanto como queramos. El código sería así:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_71E18071.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_26522CED.png" width="509" height="226" /&gt;&lt;/a&gt;&lt;/p&gt;      &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;strong&gt;2. Nombres de identificadores&lt;/strong&gt;&lt;/font&gt;. Nada va a salvarte de ti mismo, si la clase que verifica la licencia se llama LicenseChecker, LicenseValidator o de alguna otra forma altamente sugestiva, cualquiera con medio dedo de frente comenzará por ahí. Simplemente buscará con Reflector o ILSpy la pablabra “License” y listo!    &lt;br /&gt;Recuerda que los ofuscadores no pueden cambiar los nombres de los identificadores que forman parte de la superficie pública porque de lo contrario el assembly quedaría inutilizable. Sabiendo esto, te darás cuenta que todo lo que suene altamente sugestivo no puede formar parte de la superficie pública.&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;strong&gt;3. Ofusca&lt;/strong&gt;&lt;/font&gt; los ensamblados como parte del proceso de Build. Si bien esto tiene pros y contras, con esto no solo dificultas un poco la tarea de examinar el código mediante Reflector, ILSpy u otros sino que además proteges un poco el código de copias ya que la mayoría de estas herramientas permiten extraer el código fuente en proyectos compilables. &lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;strong&gt;4. Strings&lt;/strong&gt;&lt;/font&gt;. Los strings con mensajes que se muestran en la UI referidos a temas de licencias deben estar encriptados de alguna manera. Por ejemplo, si alguien quisiera romper con el componente de validación de licencias y ve que en la UI dice “Enter License Number:”, lo primero que hará será buscar ese string en los assemblies y una vez que lo encuentre se fijará en donde se usa, y desde allí llegará a donde quiera.&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;strong&gt;5. Encriptación&lt;/strong&gt;&lt;/font&gt;. Encriptar datos no detendrá a nadie aunque sí hará más lento el proceso de cracking y quizás llegue a frustrar a la persona que intenta saltearse la licencia. Lo que hay que tener en cuenta es que no debe ser la clave pública fácil de encontrar. Otro punto aún más importante es que los métodos que encriptan y desencriptan no deben nunca estar en assemblies separados de donde se usan porque de lo contrario estos tendrán que ser públicos y con esto ya arruinamos todo. Es decir, nunca poner estos métodos en un assembly “Utils” con nombres tales como Encript y Decrypt y hacerlos públicos, de lo contrario, cualquiera creará un proyecto de consola, referenciará a ese assembly y buscará las en el registro aquellas claves creadas por la aplicación que se ven claramente como encriptadas. Es decir, aquellas que se ven como sigue “9L3a1IQLzZFOmlU/3GkYu5Dm1ijRA+”, todo el mundo sabe que ésta es una cadena que ha sido encriptada.&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;strong&gt;6. Registro de windows&lt;/strong&gt;&lt;/font&gt;. Ya sea que el código esté o no ofuscado, los strings con las claves del registro no deben reconocerse fácilmente. Si en alguna parte tenemos un string que comienza con “HKCU\Software\”, ya está! Si además ponemos públicos los algoritmos de desencriptación ni siquiera será necesario buscar la clave de desencriptación, solo será necesario hacer algo así:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_09F4C500.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_6175E2EB.png" width="442" height="71" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Luego modificamos el valor que obtuvimos por consola y lo encriptamos nuevamente (gracias a los métodos que nos brinda el mismo producto) y lo escribimos en el registro.&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;strong&gt;7. Períodos de prueba&lt;/strong&gt;&lt;/font&gt;. La mayoría de los productos permiten ser usados por un período de prueba, este es uno de los puntos más débiles de casi todos los productos que conozco ya que para lograrlo, por lo general deben guardar la información de activación, días de prueba o fecha de finalización en alguna parte de nuestros equipos (por lo general, en el registro de windows). Suele ser muy sencillo manipular las claves del registro para que ese período de evaluación se extienda ad infinitum. Recuerda que quien intenta saltearse la licencia, tiene el código a su disposición por lo que encontrará la manera de burlar el mecanismo.&lt;/p&gt;  &lt;p&gt;Ten en cuenta que puede espiarse la actividad que el sistema realiza en el registro al momento de aceptar la licencia de evaluación con lo que encontrar qué es lo que hay que modificar no es el problema sino el cómo hay que modificarla. Ahí es donde debe ponerse toda la inteligencia.&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;strong&gt;8. Datetime.Now&lt;/strong&gt;&lt;/font&gt;. Restringe al máximo el uso de Datetime.Now para checkear las diferencias de días que le quedan antes de que expire el período de evaluación, ya que este devuelve la fecha del sistema y esta es modificable por el usuario. Es decir, le damos al usuario una variable que él puede modificar a su antojo.&amp;#160; Por lo tanto verifica todos los casos posibles, piensa que el usuario puede cambiar la fecha del sistema al momento de la instalación, piensa en lo valores límites, piensa si la diferencia (DateTime.Now – InstallationDate) es positiva y si es negativa, piensa que lo más fácil para el que menos sabe será jugar con la fecha del sistema.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font size="2"&gt;9. Prueba&lt;/font&gt;&lt;/strong&gt;. Muchas empresas desarrollan sus sistemas de licencias y realizan pruebas funcionales sobre estas para comprobar su correcto funcionamiento. Esto es necesario pero es solo una prueba de caja negra; sobre estos sistemas deben realizarse pruebas de caja blanca y dedicar al menos un día de, al menos, uno de los mejores desarrolladores a probar si puede vulnerar el sistema.&lt;/p&gt;  &lt;p&gt;10. Dedicarle el esfuerzo y la inteligencia necesaria. Si no querés que las instrucciones de cómo vulnerar tu sistema se encuentren al otro día de realizado el release&amp;#160; accesibles en toda la internet, si no querés que los seriales estén por todos lados, si no querés perder ventas, entonces dedicale el tiempo, esfuerzo, inteligencia y recursos necesarios. Quizás te convenga contratar a un experto en el tema.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=203191" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lontivero/archive/tags/.Net/default.aspx">.Net</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Investigaciones/default.aspx">Investigaciones</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Desarrollo/default.aspx">Desarrollo</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Conceptos/default.aspx">Conceptos</category></item><item><title>Código libre de NULLs</title><link>http://geeks.ms/blogs/lontivero/archive/2012/02/02/c-243-digo-libre-de-nulls.aspx</link><pubDate>Thu, 02 Feb 2012 20:02:23 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:203159</guid><dc:creator>Lucas Ontivero</dc:creator><slash:comments>16</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/rsscomments.aspx?PostID=203159</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/commentapi.aspx?PostID=203159</wfw:comment><comments>http://geeks.ms/blogs/lontivero/archive/2012/02/02/c-243-digo-libre-de-nulls.aspx#comments</comments><description>&lt;p&gt;En este video explico los problemas que causan las referencias nulas en nuestro código y planteo cómo debemos crear un código libre de NULLs.&lt;/p&gt; &lt;object style="height:390px;width:640px;"&gt;&lt;param name="movie" value="http://www.youtube.com/v/vnO5whrfx9M?version=3&amp;amp;feature=player_detailpage"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowScriptAccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/vnO5whrfx9M?version=3&amp;amp;feature=player_detailpage" type="application/x-shockwave-flash" allowscriptaccess="always" width="640" height="360"&gt;&lt;/object&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=203159" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Dise_26002300_241_3B00_o/default.aspx">Dise&amp;#241;o</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Series/default.aspx">Series</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/.Net/default.aspx">.Net</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Languages/default.aspx">Languages</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Desarrollo/default.aspx">Desarrollo</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Conceptos/default.aspx">Conceptos</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Refactoring/default.aspx">Refactoring</category></item><item><title>Autodisciplina al hacer check in</title><link>http://geeks.ms/blogs/lontivero/archive/2012/01/27/autodisciplina-al-hacer-check-in.aspx</link><pubDate>Fri, 27 Jan 2012 16:22:23 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:203035</guid><dc:creator>Lucas Ontivero</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/rsscomments.aspx?PostID=203035</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/commentapi.aspx?PostID=203035</wfw:comment><comments>http://geeks.ms/blogs/lontivero/archive/2012/01/27/autodisciplina-al-hacer-check-in.aspx#comments</comments><description>&lt;p&gt;Cuando el build se rompe con demasiada frecuencia o permanece en ese estado por mucho tiempo, el equipo se ve impedido de avanzar cómodamente. Pero la razón principal por la que se rompen es sin dudas el descuido: no compilar antes de subir, no correr las pruebas antes de subir y no prestar la suficiente atención al mergear entre otras cosas. Esto es porque existe un exceso de confianza en los miembros del equipo.&lt;/p&gt;  &lt;p&gt;Para ayudar a mitigar esto, en mi equipo anterior creé este premio semanal con el que nos hemos divertido mucho y la verdad es que me ha dado un resultado enorme hasta el punto que debí quitarlo cuando lo empecé a ganar yo!&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_4D45DF4B.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_45535E4B.png" width="604" height="484" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Nota: usábamos CC.Net y SVN por lo que más que descansar en la herramienta, lo que logramos fue autodisciplica.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=203035" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Desarrollo/default.aspx">Desarrollo</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Conceptos/default.aspx">Conceptos</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Herramientas/default.aspx">Herramientas</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Productividad/default.aspx">Productividad</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Continuous+Integration/default.aspx">Continuous Integration</category></item><item><title>Difícil demostrar con números las ventajas de Pair Programming</title><link>http://geeks.ms/blogs/lontivero/archive/2012/01/27/dif-237-cil-demostrar-con-n-250-meros-las-ventajas-de-pair-programming.aspx</link><pubDate>Fri, 27 Jan 2012 05:29:31 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:203023</guid><dc:creator>Lucas Ontivero</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/rsscomments.aspx?PostID=203023</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/commentapi.aspx?PostID=203023</wfw:comment><comments>http://geeks.ms/blogs/lontivero/archive/2012/01/27/dif-237-cil-demostrar-con-n-250-meros-las-ventajas-de-pair-programming.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://elbruno.com/" target="_blank"&gt;ElBruno&lt;/a&gt; ha escrito un interesante artículo en su blog titulado “&lt;a href="http://geeks.ms/blogs/elbruno/archive/2012/01/26/alm-demostrando-con-n-250-meros-porqu-233-es-conveniente-realizar-pair-programming.aspx" target="_blank"&gt;[#ALM] DEMOSTRANDO CON NÚMEROS PORQUÉ ES CONVENIENTE REALIZAR PAIR PROGRAMMING&lt;/a&gt;” en el que, mediante lo que considero un ejercicio de razonamiento, intenta demostrar el incremento que esta práctica puede generar en la productividad de un equipo con una configuración ficticia, aunque bastante común, de 2 Devs. Srs. y 4 Devs. Jrs.&amp;#160; Recomiendo su lectura (y además, es condición necesaria para entender de que se habla en esta entrada).&lt;/p&gt;  &lt;p&gt;En primer lugar debo aclarar que todo intento por ayudar a difundir, y animar a implementar, esta y otras prácticas es de agradecer e imitar. Además, y solo para dejar explícita mi posición acerca de esta práctica (Pair Programming), debo decir que estoy absolutamente de acuerdo con ella, incrementa la calidad, los diseños, la comunicación y el conocimiento del equipo como pocas prácticas lo hacen. Y además es más sociable y divertido mientras que eleva el compromiso. &lt;/p&gt;  &lt;p&gt;Ahora, una vez aclarado esto, debo decir que a mi humilde entender &lt;a href="http://elbruno.com/" target="_blank"&gt;ElBruno&lt;/a&gt; no ha acertado en su enfoque. ¿Por qué? Veamos, para demostrar la hipótesis, utiliza el siguiente ejemplo: &lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_166C3BF5.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_420CE024.png" width="462" height="507" /&gt;&lt;/a&gt;&lt;/p&gt;      &lt;p&gt;El problema con la argumentación es que todo el modelo cierra cuando existe una cantidad de desarrolladores juniors los cuales no pueden completar su trabajo sin quitarles tiempo a los desarrolladores seniors, de esta forma y en este contexto parece que la propuesta es una buena idea para maximizar la productividad. Lo curioso es que según el ejemplo, la mejor solución sería eliminar esos 4 factores de &lt;strong&gt;anti-capacity&lt;/strong&gt; llamados juniors y así, con solo una fracción del costo, los 2 desarrolladores seniors podrían completar sus 2 unidades de trabajo diarias con lo que a la semana tendríamos 20 unidades de trabajo completas. Entonces, es la existencia de esos juniors la condición necesaria para que esto cierre.&lt;/p&gt;  &lt;p&gt;No obstante creo que aquí se cumple una gran verdad: poner más desarrolladores, poco experimentados, no incrementa la velocidad del equipo; y como este modelo concuerda con las experiencias de la vida misma, podemos pensar que no está muy lejos de ser correcto.&lt;/p&gt;  &lt;p&gt;Ahora, este mismo razonamiento no arroja los mismos resultados si el equipo tuviese otra configuración como por ejemplo si fuesen solamente 6 Devs. Srs. En este caso, si aplicamos el mismo razonamiento utilizado en el ejemplo, el resultado será que como nadie requiere ayuda de otro para terminar (o al menos idealmente), entonces tener a 2 Devs. Srs. en una misma máquina resultaría en una pérdida de la productividad.&lt;/p&gt;  &lt;p&gt;Como Pair Programming es exactamente para, entre otras muchas cosas, incrementar la calidad y con esto reducir los costos, creo que esta argumentación podría habilitar a aquellos quienes desconocen la práctica, detractores por ignorancia, a jugar con modelos similares concentrándose en la economía evidente (para ver “si les conviene” o “no les conviene”) ignorando la disminución del costo a largo plazo que esta logra. Quizás, como todo el ejemplo cierra gracias a estos 4 devs. juniors alguien podría argumentar que su equipo no necesita de esta práctica ya que el mismo se compone solo de devs. seniors. Así las cosas, este argumento es de doble filo!&lt;/p&gt;  &lt;p&gt;Otro motivo por el que este ejemplo no me parece el mejor es porque, en mi experiencia, Pair Programming funciona mucho mejor cuando ambos desarrolladores tienen conocimientos “equivalentes” y no tan bien cuando la diferencia de conocimientos es grande como entre un junior y un senior. En este último caso, el juniors casi siempre se limita a mirar (y en el mejor de los casos a aprender, que no es poco) pero difícilmente pueda darse la dinámica de cambiar con cierta frecuencia el teclado y los roles. &lt;/p&gt;  &lt;p&gt;Por desgracia esta práctica es quizás la menos utilizada y esto se debe entre otras cosas a que es difícil de demostrar de manera “teórica” lo que la hace no muy evidente. Otro problema es que en varios papers de señores científicos que publican en la IEEE y la ACM se menciona que esta incrementa el time to market en entre un 15-20% y por eso es también que se hace mucho más difícil de justificar. En el tiempo de los resultados rápidos pocos quieren invertir a largo plazo.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=203023" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Gesti_26002300_243_3B00_n+de+proyectos/default.aspx">Gesti&amp;#243;n de proyectos</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Desarrollo/default.aspx">Desarrollo</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Conceptos/default.aspx">Conceptos</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Productividad/default.aspx">Productividad</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Pair+Programming/default.aspx">Pair Programming</category></item><item><title>Refactoring–Extract Method para separar validaciones de operaciones</title><link>http://geeks.ms/blogs/lontivero/archive/2012/01/25/refactoring-extract-method-para-separar-validaciones-de-operaciones.aspx</link><pubDate>Wed, 25 Jan 2012 19:55:59 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:203002</guid><dc:creator>Lucas Ontivero</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/rsscomments.aspx?PostID=203002</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/commentapi.aspx?PostID=203002</wfw:comment><comments>http://geeks.ms/blogs/lontivero/archive/2012/01/25/refactoring-extract-method-para-separar-validaciones-de-operaciones.aspx#comments</comments><description>&lt;p&gt;Existen casos en los que es conveniente extraer un bloque de código en un nuevo método por razones de validaciones de entrada. Es decir, queremos sepaar el código de validaciones de entradas del código que realiza propiamente las operaciones con estas. En algunos casos esto además puede traernos algunos beneficios de performance. Esto es más claro en los métodos recursivos. Para ilustrar esto pongamos como ejemplo al clásico método que calcula el Factorial de N de manera recursiva:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_51537C78.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_2070C50D.png" width="500" height="118" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Aquí el problema está en que el parámetro ‘n’ se valida en cada llamada pero la realidad es que esto no debería ser así ya que si ‘n’ es válido en la primera llamada este va a serlo también en todas las sucesivas invocaciones que se hacen de manera recursiva. Por este motivo es conveniente separar las validaciones y extraer el cálculo del factorial para llevarlo a otro método como sigue:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_45FA426E.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_0EF03E68.png" width="507" height="197" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;No es la performance lo que interesa aquí sino la separación conceptual de las validaciones y las operaciones, el incremento de la performance es solo un producto derivado de haber hecho esto.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=203002" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patterns/default.aspx">Patterns</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Dise_26002300_241_3B00_o/default.aspx">Dise&amp;#241;o</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patrones/default.aspx">Patrones</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Desarrollo/default.aspx">Desarrollo</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Conceptos/default.aspx">Conceptos</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Refactoring/default.aspx">Refactoring</category></item><item><title>[Video] Serie sobre excepciones–El rol de las interfaces</title><link>http://geeks.ms/blogs/lontivero/archive/2012/01/24/video-serie-sobre-excepciones-el-rol-de-las-interfaces.aspx</link><pubDate>Tue, 24 Jan 2012 04:19:13 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:202944</guid><dc:creator>Lucas Ontivero</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/rsscomments.aspx?PostID=202944</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/commentapi.aspx?PostID=202944</wfw:comment><comments>http://geeks.ms/blogs/lontivero/archive/2012/01/24/video-serie-sobre-excepciones-el-rol-de-las-interfaces.aspx#comments</comments><description>&lt;p&gt;Esta es seguramente la última entrada sobre excepciones en la que explico el rol de la interfaces (con el usuario u otro tipo de clientes) en la captura, tratamiento y traducción de las excepciones.&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:ff1ef67d-621b-4132-88e1-34f01af68f68" class="wlWriterEditableSmartContent"&gt;&lt;div&gt;&lt;a href="http://www.youtube.com/watch?v=8mDyS91WuMY&amp;amp;feature=youtube_gdata_player" target="_new"&gt;&lt;img src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/video7a1d1fc217ee_5F00_4FA11921.jpg" style="border-style:none;" alt="" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=202944" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patterns/default.aspx">Patterns</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Arquitectura/default.aspx">Arquitectura</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Dise_26002300_241_3B00_o/default.aspx">Dise&amp;#241;o</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Series/default.aspx">Series</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patrones/default.aspx">Patrones</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Desarrollo/default.aspx">Desarrollo</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Conceptos/default.aspx">Conceptos</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Exceptions/default.aspx">Exceptions</category></item><item><title>Code Freeze–Explicando esta MALA práctica</title><link>http://geeks.ms/blogs/lontivero/archive/2012/01/23/code-freeze-explicando-esta-pr-225-ctica.aspx</link><pubDate>Mon, 23 Jan 2012 06:05:26 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:202929</guid><dc:creator>Lucas Ontivero</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/rsscomments.aspx?PostID=202929</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/commentapi.aspx?PostID=202929</wfw:comment><comments>http://geeks.ms/blogs/lontivero/archive/2012/01/23/code-freeze-explicando-esta-pr-225-ctica.aspx#comments</comments><description>&lt;p&gt;Hace un par de días una amigo preguntó por esta práctica en twitter por lo que decidí dar una brevísima explicación en este video.&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:40819724-58a1-4d65-8977-097cbad545ee" class="wlWriterEditableSmartContent"&gt;&lt;div&gt;&lt;a href="http://www.youtube.com/watch?v=sKh7x-LU30Y&amp;amp;feature=youtube_gdata_player" target="_new"&gt;&lt;img src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/video6802293669c7_5F00_506B5599.jpg" style="border-style:none;" alt="" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;  &lt;p&gt;&lt;font color="#ff0000"&gt;NOTA: a sugerencia de Rodrigo Corral he cambiado el título para que quede claro de entrada que en la inmensa mayoría de los casos esta es una mala práctica, cosa que entiendo he dejado bien claro en el video; aunque nunca se sabe. Creo además que la malas prácticas también necesitan ser explicadas ya que forman parte del vocabulario común y uno debe conocerlas.&lt;/font&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=202929" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Project+Management/default.aspx">Project Management</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Gesti_26002300_243_3B00_n+de+proyectos/default.aspx">Gesti&amp;#243;n de proyectos</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Desarrollo/default.aspx">Desarrollo</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Conceptos/default.aspx">Conceptos</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Gesti_F300_n+de+la+configuraci_F300_n/default.aspx">Gestión de la configuración</category></item><item><title>[Video] Serie sobre excepciones – Explicando ejemplo del MSDN</title><link>http://geeks.ms/blogs/lontivero/archive/2012/01/20/video-serie-sobre-excepciones-explicando-ejemplo-del-msdn.aspx</link><pubDate>Fri, 20 Jan 2012 06:00:07 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:202896</guid><dc:creator>Lucas Ontivero</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/rsscomments.aspx?PostID=202896</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/commentapi.aspx?PostID=202896</wfw:comment><comments>http://geeks.ms/blogs/lontivero/archive/2012/01/20/video-serie-sobre-excepciones-explicando-ejemplo-del-msdn.aspx#comments</comments><description>&lt;p&gt;En este video explico el por qué un ejemplo tomado del MSDN está mal y cómo debería de escribirse en cuanto a la manera en que trata las excepciones.&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:b242257b-e422-4cf5-8c30-8294f91240cd" class="wlWriterEditableSmartContent"&gt;&lt;div&gt;&lt;a href="http://www.youtube.com/watch?v=i8wxG5_7YTc&amp;amp;feature=youtube_gdata_player" target="_new"&gt;&lt;img src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/video48922cb81322_5F00_541E2E5B.jpg" style="border-style:none;" alt="" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=202896" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patterns/default.aspx">Patterns</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Series/default.aspx">Series</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/.Net/default.aspx">.Net</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Languages/default.aspx">Languages</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patrones/default.aspx">Patrones</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Desarrollo/default.aspx">Desarrollo</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Exceptions/default.aspx">Exceptions</category></item><item><title>Excepciones – Un caso sobre los ejemplos del MSDN</title><link>http://geeks.ms/blogs/lontivero/archive/2012/01/20/excepciones-una-caso-sobre-los-ejemplos-del-msdn.aspx</link><pubDate>Fri, 20 Jan 2012 05:25:31 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:202895</guid><dc:creator>Lucas Ontivero</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/rsscomments.aspx?PostID=202895</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/commentapi.aspx?PostID=202895</wfw:comment><comments>http://geeks.ms/blogs/lontivero/archive/2012/01/20/excepciones-una-caso-sobre-los-ejemplos-del-msdn.aspx#comments</comments><description>&lt;p&gt;Soy un convencido de que muchos de los malentendidos que existen en cuanto al manejo de excepciones en VB.Net y C# es por culpa de los malos ejemplos que siempre ha tenido el MSDN. Con solo invertir un par de segundos en google uno puede encontrar verdaderas aberraciones.. A modo de ejemplo solo pondré dos links y las capturas:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.net.dns.resolve(v=vs.110).aspx"&gt;http://msdn.microsoft.com/en-us/library/system.net.dns.resolve(v=vs.110).aspx&lt;/a&gt;&amp;#160; &lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_4C7BD4DA.png"&gt;&lt;img style="background-image:none;border-right-width:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_4DB047EC.png" width="457" height="366" /&gt;&lt;/a&gt;     &lt;br /&gt;Si Bien es cierto que los ejemplos han mejorado muchísimo, porque años antes eran un desastre, todavía siguen existiendo demasiados de estos ejemplos, ejemplos que son tomados por muchos desarrolladores como “bunas prácticas” ya que provienen de un sitio de la más alta confianza.     &lt;br /&gt;    &lt;br /&gt;Otro ejemplo: &lt;a href="http://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient(v=vs.110).aspx"&gt;http://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient(v=vs.110).aspx&lt;/a&gt;. Hay tantas cosas mal en este que da para pensar si estos ejemplos ayudan a los programadores o si por el contrario, los perjudica.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_028D275D.png"&gt;&lt;img style="background-image:none;border-right-width:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_7A192C38.png" width="477" height="707" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=202895" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patterns/default.aspx">Patterns</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Dise_26002300_241_3B00_o/default.aspx">Dise&amp;#241;o</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/.Net/default.aspx">.Net</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patrones/default.aspx">Patrones</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Desarrollo/default.aspx">Desarrollo</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Exceptions/default.aspx">Exceptions</category></item><item><title>Creando un sistema de indexación para nuestros datos no estructurados en Sql</title><link>http://geeks.ms/blogs/lontivero/archive/2012/01/11/creando-un-sistema-de-indexaci-243-n-para-nuestros-datos-no-estructurados-en-sql.aspx</link><pubDate>Wed, 11 Jan 2012 04:36:19 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:202697</guid><dc:creator>Lucas Ontivero</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/rsscomments.aspx?PostID=202697</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/commentapi.aspx?PostID=202697</wfw:comment><comments>http://geeks.ms/blogs/lontivero/archive/2012/01/11/creando-un-sistema-de-indexaci-243-n-para-nuestros-datos-no-estructurados-en-sql.aspx#comments</comments><description>&lt;h3&gt;Introducción&lt;/h3&gt;  &lt;p&gt;Existen ocasiones en las que almacenar y organizar nuestros datos en una estructura tabular puede no ser lo ideal, en las que por conveniencia queramos guardar un conjunto de datos fuertemente relacionados en un sencillo xml pero a la vez necesitemos muchas de las características propias de SQL.&lt;/p&gt;  &lt;p&gt;Si bien SQL Server nos permite guardar XML (con o sin esquema asociado) e indexarlo, estos índices son muchas veces demasiado grandes y algo lentos y, aunque funcionan obviamente muy bien, podríamos crear nuestro propio sistema de índices más livianos (y también indexar los xml no en tiempo real).&lt;/p&gt;  &lt;h3&gt;La idea&lt;/h3&gt;  &lt;p&gt;La idea es crear una delgadísima capa de acceso a datos que nos permita guardar documentos XMLs en la bases de datos utilizando procedimientos almacenados. Estos son básicamente 2: InsertDocument y UpdateDocumet. El objetivo es no solo insertar y actualizar los documentos sino también insertar y actualizar los índices que se hayan creado para los mismo.&lt;/p&gt;  &lt;h3&gt;Ejemplo&lt;/h3&gt;  &lt;p&gt;Imaginemos que deseamos guardar datos personales de personas, sus nombres, apellidos, datos de contacto, familiares y otros datos. Para ello usamos documentos XMLs como el que sigue:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_697ACDC4.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_73DB564A.png" width="326" height="224" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Lo primero es crear y registrar la tabla en donde se guardarán los documentos XMLs, para esto utilizamos un procedimiento almacenado: CreateForm y que recibe el nombre de la tabla a crear:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_77694B5A.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_4AE01B74.png" width="446" height="55" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Esto último crea una tabla y la registra dentro de la tabla Forms.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_5B781662.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_4C148E86.png" width="416" height="103" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_4FA28396.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_036A79E8.png" width="159" height="87" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;También queremos poder buscar dentro de estos documentos por Nombre, Edad y por el nombre del padre de las personas y por ello crearemos 3 indices mediante el procedimiento almacenado CreateIndex.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_2240EDC6.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_58626615.png" width="775" height="61" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Esto último crea 3 tablas, una por cada índice y las registra en la tabla de índices (Indexes). Para la creación del nombre de estas tablas se una como convención NombreTabla_XpathNodo_Idx. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_303F9129.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_4EA9D212.png" width="349" height="146" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_541842B6.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_0BDA610D.png" width="844" height="143" /&gt;&lt;/a&gt;&lt;/p&gt;              &lt;p&gt;Y ahora si, una vez creados y registrados tanto la tabla como los índices, podemos comenzar a insertar y actualizar documentos. Por ejemplo, para insertar el documento que veíamos al inicio solo debemos invocar al procedimiento&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_731B13FC.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_1040BC07.png" width="328" height="235" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Insertemos otro más:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_042EA606.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_2DC27139.png" width="257" height="167" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Veamos cómo quedan los índices luego de insertado este registro:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_1315D520.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_008D38D1.png" width="514" height="287" /&gt;&lt;/a&gt;&lt;/p&gt;      &lt;p&gt;Ahora podemos buscar los en las tablas de índices y obtener el/los id del/de los documento/s que contiene/n el valor buscado. ¿Pero que sucede si quisiera buscar por más de un valor/columna? Bueno, con estas tablas podemos crear una vista que las uniera mediante un join por DocumentId. Para eso utilizamos el procedimiento almacenado CreateSearchView como sigue:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_0657B69D.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_2BE133FE.png" width="471" height="53" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Lo que crea la vista Personas_SearchView la cual puede utilizarse para búsquedas. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_29580240.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_11711B1A.png" width="508" height="154" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Ahora bien, puesto que el indexado es algo caro, podríamos configurar un Job para que indexe los registros por las noches o lo haga por lotes pequeños de registros o de alguna otra forma que nos permita mover el costo de procesamiento a otro lado o a otro momento. Para ello existe el procedimiento almacenado UpdateIndex el cual recibe como parámetro el nombre del indice a actualizar.&lt;/p&gt;  &lt;h3&gt;Conclusión&lt;/h3&gt;  &lt;p&gt;Bien, esta es solo una idea que puede utilizarse en algunos escenarios en los que debamos (o queramos) utilizar SQL mientras que a la vez almacenamos nuestros datos como XMLs sin esquemas las cual puede brindarnos algunas de las características propias de las bases de datos NoSql.&lt;/p&gt;  &lt;p&gt;El código está &lt;a href="https://skydrive.live.com/redir.aspx?cid=375ae0ccd1af61ce&amp;amp;resid=375AE0CCD1AF61CE!678&amp;amp;parid=375AE0CCD1AF61CE!500" target="_blank"&gt;acá&lt;/a&gt;.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=202697" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Arquitectura/default.aspx">Arquitectura</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Dise_26002300_241_3B00_o/default.aspx">Dise&amp;#241;o</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Investigaciones/default.aspx">Investigaciones</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Desarrollo/default.aspx">Desarrollo</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Conceptos/default.aspx">Conceptos</category></item></channel></rss>