<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-25169098</atom:id><lastBuildDate>Wed, 08 Oct 2025 16:14:37 +0000</lastBuildDate><category>arquitectura</category><category>programador</category><category>abstract factory</category><category>cloud computing conferencias</category><category>diseño</category><category>fábrica</category><category>historia</category><category>homenaje</category><category>impresoras</category><category>interacción</category><category>metodologías</category><category>programación</category><category>software</category><category>tecnología</category><category>visual basic</category><title>enProduccion</title><description>un inconstante devaneo sobre el desarrollo de software, la tecnología y la vida misma.</description><link>http://enproduccion.blogspot.com/</link><managingEditor>noreply@blogger.com (Diego Cofré)</managingEditor><generator>Blogger</generator><openSearch:totalResults>10</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25169098.post-6679792178968313115</guid><pubDate>Wed, 19 Nov 2008 14:07:00 +0000</pubDate><atom:updated>2008-11-19T16:05:31.371-02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">cloud computing conferencias</category><title>PDC 08 en BA</title><description>&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOVu0SBkx5ExMYXuVZbY3zbeM-rxxQCSzipEXy5weolQqWoPEL39R3jzAIw7SrYmNbAPW7v_33j8H_4PC81P-eoC4K6oaOPHCQfF-_6jeSw3JTxfzc8gyj7E1k1diuy0oVkG9H/s1600-h/ms_cloud.jpg&quot;&gt;&lt;img style=&quot;float:left; margin:0 7px 7px 0;cursor:pointer; cursor:hand;width: 220px; height: 190px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOVu0SBkx5ExMYXuVZbY3zbeM-rxxQCSzipEXy5weolQqWoPEL39R3jzAIw7SrYmNbAPW7v_33j8H_4PC81P-eoC4K6oaOPHCQfF-_6jeSw3JTxfzc8gyj7E1k1diuy0oVkG9H/s320/ms_cloud.jpg&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5270428259486257042&quot; /&gt;&lt;/a&gt;&lt;div&gt;Ayer, la gente de Microsoft ofreció un interesante evento en Buenos Aires para contarnos a los desarrolladores porteños las novedades anunciadas hace dos semanas en el &lt;a href=&quot;http://www.microsoftpdc.com/&quot;&gt;Professional&lt;/a&gt;&lt;a href=&quot;http://www.microsoftpdc.com/&quot;&gt; &lt;/a&gt;&lt;a href=&quot;http://www.microsoftpdc.com/&quot;&gt;Developer&lt;/a&gt;&lt;a href=&quot;http://www.microsoftpdc.com/&quot;&gt;&#39;s &lt;/a&gt;&lt;a href=&quot;http://www.microsoftpdc.com/&quot;&gt;Conference&lt;/a&gt;&lt;a href=&quot;http://www.microsoftpdc.com/&quot;&gt;,&lt;/a&gt; realizado en Los Ángeles.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Con una buena selección de speakers -la mayoría de los cuales habían asistido al PDC original- las sesiones fueron interesantes, y cubrieron muy bien el abanico de cosas que están preparando los Microsofties.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;El tema que sobrevoló todo el encuentro es .... (fanfarrias)... &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight: bold;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-style: italic;&quot;&gt;computación en &lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight: bold;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-style: italic;&quot;&gt;la nube o cloud computing&lt;/span&gt;&lt;/span&gt;. Quizás algunos de ustedes ya hayan escuchado algo sobre este tema que, como su nombre lo indica, está un poco difuso (si me disculpan la asociación obvia). La idea general de &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-style: italic;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight: bold;&quot;&gt;la nube&lt;/span&gt;&lt;/span&gt; es ofrecer una plataforma omnipresente para la ejecución de aplicaciones y almacenamiento de datos. Así, los desarrolladores no tienen que preocuparse de cuestiones de infraestructura de bajo nivel (servidores, memoria, almacenamiento) y pueden concentrarse en resolver problemas concretos a través de aplicaciones y servicios que serán hosteados en algún lugar de la nube. Por otro lado, los usuarios de esas aplicaciones pueden disponer de ellas en cualquier dispositivo, ya sea una PC, laptop o cualquier tipo de dispositivo móvil.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;El puntapié inicial en esta tendencia lo dio Google, con sus ya clásicas &lt;a href=&quot;http://www.google.com/a/help/intl/es/business/applications.html&quot;&gt;Google Apps&lt;/a&gt;, Maps, Docs y demás. Pues bien, parece que el gigante de la gran M -si bien quizás no maneja el timón innovador de esta era- &lt;a href=&quot;http://www.paulgraham.com/microsoft.html&quot;&gt;no está muerto&lt;/a&gt; y va a dar pelea compitiendo con sus propias soluciones y plataformas.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;En este plan, Microsoft viene desenvolviendo su plataforma &lt;a href=&quot;http://www.microsoft.com/azure/default.mspx&quot;&gt;Windows Azure&lt;/a&gt;, que es, según definieron ayer, &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-style: italic;&quot;&gt;&quot;un sistema operativo en la nube&quot;&lt;/span&gt;. La solución Cloud Computing de Microsoft está soportada por un gran datacenter (en realidad varios) interconectados que respaldará una plataforma de servicios online para hostear y administrar aplicaciones y datos. Todo esto desarrollado sobre Windows Server y .Net y muy bien integrado con herramientas de desarrollo como Visual Studio, lo cual es una buena noticia para los desarrolladores de la galaxia MS (entre los cuales me cuento). Con esta plataforma, una empresa puede tener sus sistemas corriendo en Azure sin preocuparse por el hardware, datos, backups, actualizaciones de software base, alimentación ininterrumpida, etc, confiando todo esto a los amigos de Redmond. Una de las ventajas que mencionaban allí es la escalabilidad instantánea de las soluciones. Por ejemplo, un pequeño negocio que tiene un sitio modesto con pocas visitas diarias quiere ofrecer una promoción masiva, que seguramente impactará en la disponibilidad de su sitio. Si la solución estuviese hosteada sobre un servidor propio, la gente de IT debería prever esto y escalarla poniendo más hardware, balanceadores de carga, etc. En Windows Azure, esto se realiza indicando en un archivo de configuración cuantas instancias de la aplicación se correrán. Obviamente Microsoft cobrará por eso de acuerdo al tiempo en que usemos las múltiples instancias, pero será mucho más barato que comprar un servidor nuevo. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Se trata realmente de un cambio de mentalidad con respecto al software. Algo que nos tendremos que tomar el tiempo para digerir y ver como puede aplicarse a soluciones concretas. Lo cierto es que la tendencia parece venir bastante fuerte, vehiculizada por pesos pesados de la industria, como Google y Microsoft. Así es que mejor poner un ojo sobre estas tecnologías y estar preparados para lo que viene. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Pensar que cuando eramos chicos nos decían que estar en las nubes era algo malo. Ahora, por esas ironías de la vida, los que nos dedicamos al desarrollo tendremos que empezar a estar en la nube y ver que se cuece por allí. Veremos como se va perfilando todo esto. Sin dudas, en el horizonte del desarrollo algo esta cambiando. &lt;/div&gt;</description><link>http://enproduccion.blogspot.com/2008/11/pdc-08-en-ba.html</link><author>noreply@blogger.com (Diego Cofré)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOVu0SBkx5ExMYXuVZbY3zbeM-rxxQCSzipEXy5weolQqWoPEL39R3jzAIw7SrYmNbAPW7v_33j8H_4PC81P-eoC4K6oaOPHCQfF-_6jeSw3JTxfzc8gyj7E1k1diuy0oVkG9H/s72-c/ms_cloud.jpg" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25169098.post-4531525972818231942</guid><pubDate>Tue, 23 Sep 2008 19:39:00 +0000</pubDate><atom:updated>2008-09-23T19:16:24.425-03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">diseño</category><category domain="http://www.blogger.com/atom/ns#">interacción</category><title>Charla sobre diseño de interacción</title><description>&lt;div style=&quot;text-align: center;&quot;&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;http://farm1.static.flickr.com/210/511292992_5d363c556f.jpg&quot;&gt;&lt;img style=&quot;cursor:pointer; cursor:hand;width: 400px;&quot; src=&quot;http://farm1.static.flickr.com/210/511292992_5d363c556f.jpg&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Ayer, Diego Gonzalez de &lt;a href=&quot;http://www.lagash.com/&quot;&gt;Lagash Systems&lt;/a&gt; y el &lt;a href=&quot;http://www.mug.org.ar/&quot;&gt;MUG&lt;/a&gt;, ofrecieron un impecable &lt;a href=&quot;http://www.mug.org.ar/Eventos/3095.aspx&quot;&gt;seminario &lt;/a&gt;sobre un tema no muy difundido por estos pagos, el diseño de interfaces de usuario usables.&lt;br /&gt;&lt;br /&gt;Los programadores debemos admitir que tenemos algunas falencias a la hora de diseñar una interfaz de usuario bella, querible, usable, o por lo menos, poco odiable. Lo nuestro es mas bien la a reusabilidad, modelos, componentes, poco acoplamiento, patrones; conceptos que no tienen nada que ver con la belleza o la estética, o por lo menos no al nivel que un usuario espera ver en su pantalla. Por otro lado, las interfaces perpetradas por diseñadores gráficos, son visualmente impactantes, utilizan metáforas fotorrealistas, con animaciones y fuegos artificiales. Pero para el devenir diario de una aplicación son poco usables, ya que todos estos bonitos chirimbolos consumen un tiempo precioso en la operación del usuario, y no le agregan nada a su objetivo (que es &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight: bold;&quot;&gt;usar la aplicación para un determinado fin&lt;/span&gt;, no ver lo lindo que es su diseño). Entonces ¿Qué se espera de un buen diseño de interacción?&lt;br /&gt;&lt;br /&gt;En esta charla Diego nos ofreció algunas puntas para ir pensando en esto. Habló de la &lt;a href=&quot;http://www.google.com.ar/search?hl=es&amp;amp;q=ley+de+fitts&amp;amp;btnG=Buscar&amp;amp;meta=&quot;&gt;ley de Fits&lt;/a&gt;, que sirve para predecir cuánto tardará un usuario en lograr un objetivo en función de la distancia que tiene que recorrer con el mouse y el tamaño del objeto a apuntar. Esta ley explica, por ejemplo, porqué es más mucho fácil darle al menú de Macintosh que al de Windows. Porque el menú de la manzanita es &quot;infinito&quot; hacia arriba; por lo tanto no tenemos que preocuparnos por la dimensión vertical, es decir que vamos hacia arriba hasta que nos chocamos con el extremo de la pantalla y luego apuntamos sobre el eje X a nuestro objetivo.&lt;br /&gt;&lt;br /&gt;Otra ley interesante de la que se habló es la de &lt;a href=&quot;http://en.wikipedia.org/wiki/Hick&#39;s_law&quot;&gt;Hick-Hyman&lt;/a&gt;, que trata sobre el tiempo que una persona tarda en elegir entre una cantidad de opciones. Cómo esta variable se incrementa en un orden logarítmico -es decir que se incrementa en 1 cada vez que se duplican la cantidad de opciones- la conclusión sería que es más fácil seleccionar entre 30 opciones que agrupar estas 20 en tres grupos de 10, ya que esta última opción costaría dos elecciones, que lleva más tiempo que optar entre muchos elementos.&lt;br /&gt;&lt;br /&gt;Todos estos datos sirven para evaluar la usabilidad de una interfaz de usuario con la exactitud que nos da el cronómetro, cosa que en general no sucede y la discusión sobre una interfaz termina girando en torno de si me gusta o no me gusta.&lt;br /&gt;&lt;br /&gt;Algunos tips para aplicar al momento de bocetar un diseño de interacción:&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight: bold;&quot;&gt;1) Pensar en los tiempo&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight: bold;&quot;&gt;s.&lt;/span&gt; Todas las acciones de un usuario sobre la interfaz lleva un tiempo, darle a una tecla, apuntar y hacer clic con un mouse, pasar de manejar mouse a teclado o viceversa. Tratar de minimizar la cantidad de entradas de un usuario sobre la interfaz para alcanzar un objetivo, esto es, pensar en la mínima cantidad de información que la aplicación necesita a cada paso para hacer cada cosa, y pedir solo eso. En este plan, también conviene simplificar la interfaz al máximo y diseñarla de manera que las cosas que el usuario más usa queden más cerca, como marcando un caminito.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;2) Aplicar metáforas.&lt;/span&gt; Si se puede, trabajar con metáforas del mundo real que al usuario le permitan ubicarse en el contexto de la aplicación rápidamente. Por ejemplo, arrastrar y soltar es una metáfora mucho más poderosa que Ctrl+C y Ctrl+V. También se pueden utilizar metáforas visuales, por ejemplo, íconos que den la idea de lo que sucederá cuando se haga clic sobre él.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;3) Diseñar la aplicación de manera que sea lo menos intrusiva posible.&lt;/span&gt; Esto significa que el usuario pueda trabajar concentrado en su objetivo, recibiendo la menor cantidad posible de interrupciones de parte de la aplicación (o de parte nuestra). Por ejemplo, un cuadro de alerta que nos avisa que el archivo se grabó correctamente está de más, se supone que es lo que debe pasar y nadie espera lo contrario. A esto se le llama &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-style: italic;&quot;&gt;comportamiento no modal&lt;/span&gt;, porque la aplicación no impone el orden en que el usuario debe usarla, sino que deja a este que maneje el flujo de trabajo.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Por último, quisiera dejarles algunos links y recursos interesantes para los que quieran profundizar en este campo, que a decir verdad, ha sido poco explorado por nosotros, los desarrolladores:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;El inventor de las metáforas aplicadas al diseño de objetos es Donald Norman, que las expone magistralmente en &lt;a href=&quot;http://www.cuspide.com/isbn/8489569185&quot;&gt;&quot;La psicología de los objetos cotidianos&quot;&lt;/a&gt;. Verdaderamente este libro es un &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-style: italic; &quot;&gt;must read&lt;/span&gt; para todos los diseñadores de interacción y también para los iniciados en la disciplina del diseño industrial.&lt;/li&gt;&lt;li&gt;Por supuesto, el sitio del inefable Jacob Nielsen, &lt;a href=&quot;http://www.useit.com/&quot;&gt;UseIt&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Otro recurso interesante para mí es un librito muy entretenido del genial Joel Spolsky, llamado &quot;Diseño de interfaz de usuario para programadores&quot;. Hay una versión reducida online &lt;a href=&quot;http://www.joelonsoftware.com/uibook/chapters/fog0000000057.html&quot;&gt;en su sitio&lt;/a&gt;, y traducida al castellano &lt;a href=&quot;http://spanish.joelonsoftware.com/&quot;&gt;aquí&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Otro libro, &lt;a href=&quot;http://www.cuspide.com/isbn/9684444648&quot;&gt;&quot;Presos de la tecnología&quot;&lt;/a&gt; (una desafortunada traducción de &quot;The Inmates are running the assylum&quot;) del creador del Visual Basic, don Alan Cooper, plantea los problemas graves que puede traer un diseño de interacción poco usable. &lt;/li&gt;&lt;li&gt;Y por último, el libro fundacional de la disciplina: &lt;a href=&quot;http://www.cuspide.com/isbn/9702600383&quot;&gt;&quot;Diseño de Sistemas Interactivos&quot;&lt;/a&gt;, de Jef Raskin, el padre de la interfaz gráfica de Macintosh. Un poco denso quizás, pero ahí está la ciencia...&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Los saludo y espero que les haya resultado tan interesante como a mí.&lt;/div&gt;&lt;/div&gt;</description><link>http://enproduccion.blogspot.com/2008/09/charla-sobre-diseo-de-interaccin.html</link><author>noreply@blogger.com (Diego Cofré)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://farm1.static.flickr.com/210/511292992_5d363c556f_t.jpg" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25169098.post-1275122296957180385</guid><pubDate>Fri, 12 Sep 2008 23:38:00 +0000</pubDate><atom:updated>2008-09-12T21:09:30.893-03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">arquitectura</category><category domain="http://www.blogger.com/atom/ns#">fábrica</category><category domain="http://www.blogger.com/atom/ns#">metodologías</category><category domain="http://www.blogger.com/atom/ns#">software</category><title>¿Qué es una Fábrica de Software?</title><description>&lt;div style=&quot;text-align: center;&quot;&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiI5Jcm6GY2bt7ew4GxsM8_sWjJ1rwUvLBBNBS2lu_sQZfk5TWX2imNSoeEN0ezuYMTm1sKa1o343suWHnEpSUjHMbh4hEktN-32JPipw_8KWwasrN3xKiyRfxkQoozgnWZbpcA/s1600-h/factory_1912.jpg&quot;&gt;&lt;img style=&quot;cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiI5Jcm6GY2bt7ew4GxsM8_sWjJ1rwUvLBBNBS2lu_sQZfk5TWX2imNSoeEN0ezuYMTm1sKa1o343suWHnEpSUjHMbh4hEktN-32JPipw_8KWwasrN3xKiyRfxkQoozgnWZbpcA/s320/factory_1912.jpg&quot; alt=&quot;Fábrica de relojes (circa 1912)&quot; id=&quot;BLOGGER_PHOTO_ID_5245289016084976914&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;A veces, la repetición de un término produce una sensación de familiaridad con la expresión, aunque no sepamos exactamente qué significa. Algo así sucede actualmente con el concepto de “Fábricas de Software” o “Software Factories” (SF en adelante). Hoy estas empresas son omnipresentes; en Google se encuentran de a cientos de miles. Las hay de todos los tamaños, con 4 empleados o 5000, locales o globales, para clientes corporativos o pequeñas empresas. Lo que muchas veces uno no termina de entender es ¿Qué define a una factoría de software? O mejor dicho ¿Qué la diferencia de una empresa productora de software? ¿Existe tal diferencia, o, como ha sucedido con tantos viejos términos, viene a desbancar el anticuado “empresa de software”, como “verdum” reemplaza a ensalada?&lt;br /&gt;&lt;br /&gt;En una primera aproximación, la diferencia entre un “taller de software” o “software shop” y una SF suena sutil, pero veremos que no lo es. El taller de software es una empresa (grande o chica, no importa) dedicada a la construcción de software en forma “artesanal” ¿Porqué decimos artesanal? El término Fábrica de Software remite directamente a la forma de producción que propone la revolución industrial. Hagamos un poco de historia. En el siglo XVIII se produce un movimiento histórico llamado revolución industrial que consistió básicamente en un cambio de los métodos de producción. Antes de esta revolución existían grandes talleres, donde trabajaban maestros artesanos que poseían el saber para construir un objeto -por ejemplo una silla- de principio a fin. El artesano cortaba la madera, le daba forma, la ensamblaba, ponía el tapizado, etcétera, hasta que la silla estaba terminada. Este manufactura, como podrán imaginarse, era lenta y cara; por eso casi todos los objetos previos a la revolución industrial son objetos de lujo, que sólo podían ser adquiridos por miembros de la nobleza (¿les suena algo en relación al software artesanal?).  Hilando mas fino, el proceso que tiene lugar durante la revolución industrial es el estudio del saber a los artesanos, su sistematización y su aplicación a los mecanismos de producción disponibles en la época (líneas de producción, máquinas a vapor). Este proceso permite que las sillas puedan construirse en masa y así abaratar costos y garantizar un proceso repetible ¿Cómo se aplica esta idea a la construcción de software? Básicamente, se trata del mismo concepto: un taller de software produce aplicaciones en forma única, ensamblándolas de principio a fin. Las aplicaciones pueden estar hechas a medida (específicas para un cliente) o en forma de productos, lo distintivo es que entre los productos existe un alto nivel de aislamiento, no existe la “línea de producción”. Si bien los equipos que trabajan en cada proyecto pueden compartir gente, prácticas y hasta algunos componentes, ésta metodología no se encuentra institucionalizada. Así, las iniciativas de reutilización reducen a esfuerzos individuales que casi no influyen en la producción como un todo. En general, este tipo de proyectos dependen de la pericia y la buena voluntad de la gente que los componen, de la misma manera, en el artesanado, una buena silla dependía del individuo que la había construido. Un buen equipo garantiza que el proyecto estará dentro de ciertos estándares de calidad, incluso sin una estructura que los respalde. En el taller se trabaja “ad-hoc”, es decir, para cada proyecto particular. El nivel de reutilización, en el mejor de los casos, es bajo y depende de que la gente del equipo conozca y adapte componentes usados con anterioridad. Entonces surge nuevamente la pregunta ¿Qué es y cómo se construye una fábrica de software?&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;font-size:130%;&quot; &gt;El tamaño no importa&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Para decirlo brevemente, una SF no se define por su tamaño pero sí por la escala a la que apunta cuando diseña sus productos. Así como una fábrica de autos, la SF basa su operación en líneas automatizadas de producción que le permiten ahorrar en términos de costo por producto ¿Cómo hace esto una SF? Una fábrica de software &lt;span style=&quot;font-weight: bold; font-style: italic;&quot;&gt;construye líneas de producción de software&lt;/span&gt;. Y éstas, a su vez, engendrarán varios sistemas que responderán a lo que esa línea fue diseñada para crear. Así, la apertura de un proyecto nuevo no implica cada vez empezar de cero, porque existe una cantidad de conocimiento que ya ha sido capturado en la línea y se puede volcar sistemáticamente  a la resolución del problema. De esta manera, el team de desarrollo puede enfocarse estrictamente en la problemática particular de esa solución, ya que los aspectos genéricos (por ejemplo: la interfaz gráfica, cuestiones de autenticación y seguridad, persistencia de datos) ya fueron previstos y resueltos por la línea de producción. Imaginen, por ejemplo, que una empresa automotriz cada vez que proyecta un nuevo auto tenga que volver a desarrollar cada uno de sus componentes. De nuevo hacer un motor desde el plano, un carburador desde cero, paneles, vidrios, frenos, etc. Literalmente estaría reinventando la rueda en cada nuevo producto. Los autos tardarían años en ser desarrollados y tendrían innumerables fallas (probablemente más que ahora). Además, valdrían millones de dólares, ya que la inversión para desarrollar cada modelo desde la nada sería descomunal.&lt;br /&gt;&lt;br /&gt;En la SF lo que cambia es el &lt;span style=&quot;font-weight: bold; font-style: italic;&quot;&gt;ámbito de la solución a la que se apunta&lt;/span&gt;. Esto implica que se diseñará, no una solución específica a un problema (por ejemplo, para manejar la contabilidad de la rotisería “El pollo bonito”)  sino una solución más amplia, aplicable a un espectro de productos. Esto implica pensar en generalizaciones del tipo ¿Qué características pueden compartir &lt;span style=&quot;font-weight: bold; font-style: italic;&quot;&gt;todos &lt;/span&gt;los sistemas de gestión contable? Esto es una característica importante de una línea de producción, resolver problemas generales de un tipo de software, &lt;span style=&quot;font-weight: bold; font-style: italic;&quot;&gt;elevando así  el nivel de abstracción&lt;/span&gt; de la solución. La otra característica fundamental, es establecer abundantes puntos de extensión en nuestra línea. Si bien la SF, efectivamente va a estar preparada para resolver problemas, también va a dejar “cabos sueltos”, es decir, mecanismos de personalización de la solución, ya que es muy probable que los productos necesiten modificar los comportamientos por defecto que la línea previó ¿Y esto como se hace? Un mecanismo muy utilizado es construir un potente framework extensible, un tema que fue tratado por un &lt;a href=&quot;http://diegumzone.spaces.live.com/Blog/cns%211AD5096D63670065%211118.entry&quot;&gt;excelente artículo&lt;/a&gt; de Diego Dagum. Vayan, léanlo, yo los espero acá (…).&lt;br /&gt;&lt;br /&gt;Para ir cerrando, armar una SF implica tomar una serie de decisiones sobre arquitecturas, modelos, prácticas y procesos a seguir con el objetivo de aplicarlos a la construcción, no de uno, sino de varios paquetes de software. Cuanto más mejor, así el retorno por la inversión se agranda. En este artículo quise reunir algunas reflexiones iniciáticas sobre las SF, para entender un poco más profundamente para qué sirven, cómo funcionan, y despejar un poco la niebla que los departamentos de marketing suelen echar sobre temas técnicos. En un próximo artículo comentaré algunas impresiones sobre la visión de Greenfield y Short (arquitectos de Microsoft), expuesta en su libro: &lt;a href=&quot;http://www.amazon.com/Software-Factories-Assembling-Applications-Frameworks/dp/0471202843/ref=pd_bbs_sr_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1221263278&amp;amp;sr=8-1&quot;&gt;Software Factories Assembling Applicacions with Patterns Models, Frameworks, and Tools&lt;/a&gt;. Estos muchachos van a fondo con esta visión y nos muestran la punta del ovillo para plasmar en resultados estos jóvenes conceptos.</description><link>http://enproduccion.blogspot.com/2008/09/qu-es-una-fbrica-de-software.html</link><author>noreply@blogger.com (Diego Cofré)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiI5Jcm6GY2bt7ew4GxsM8_sWjJ1rwUvLBBNBS2lu_sQZfk5TWX2imNSoeEN0ezuYMTm1sKa1o343suWHnEpSUjHMbh4hEktN-32JPipw_8KWwasrN3xKiyRfxkQoozgnWZbpcA/s72-c/factory_1912.jpg" height="72" width="72"/><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25169098.post-1369917573080511020</guid><pubDate>Thu, 11 Sep 2008 15:10:00 +0000</pubDate><atom:updated>2008-09-11T16:46:51.241-03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">homenaje</category><category domain="http://www.blogger.com/atom/ns#">programador</category><title>Feliz día programadores</title><description>&lt;div style=&quot;text-align: center;&quot;&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;http://www.programmerday.info&quot;&gt;&lt;img style=&quot;cursor: pointer; width: 378px; height: 141px;&quot; src=&quot;http://www.programmerday.info/images/header.jpg&quot; alt=&quot;&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;Mañana, 12 de Septiembre de 2008 se celebra en todo el mundo el día del programador. ¡Epa! ¡Pero el año pasado fue el 13! Así es, porque el día del programador es el día número 256 del año. Y este año -como fue bisiesto- el calendario lo marca un día antes,  es decir el 12 y no el 13. ¿Capisce? Bueno, es el día del programador, no podía ser tan simple ;-)&lt;br /&gt;&lt;br /&gt;Entonces, en el día 256, 2^8, 0xFF + 1 o 1111 1111 -según la representación más les guste- levanto mi copa y brindo por todos nosotros, abnegados artesanos del código, que día a día, con paciencia, detalle y una pizca de obsesión,  construimos este apasionante mundo de bits, los sistemas de computación.&lt;br /&gt;&lt;br /&gt;¡Felicidades, y buen código!</description><link>http://enproduccion.blogspot.com/2008/09/feliz-da-programadores.html</link><author>noreply@blogger.com (Diego Cofré)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25169098.post-115340987874809583</guid><pubDate>Thu, 20 Jul 2006 15:33:00 +0000</pubDate><atom:updated>2006-07-20T12:50:56.660-03:00</atom:updated><title>Documentos por favor</title><description>Hace unos días tuve la mala idea de perder mi portadocumentos. Cédula de identidad, tarjeta del banco, carnet de obra social, registro de conductor, y otras que ya no quiero ni recordar... El perjuicio por semejante ocurrencia obviamente es enorme y se traduce en mucho tiempo, una cantidad de plata y la vergüenza de tener que asumir frente a dos docenas de personas que uno es un estúpido que no sabe cuidar sus cosas. Aunque, siendo honestos, no es raro que un ser humano pase en algún momento por la experiencia de perder algo, perdemos las cosas todo el tiempo. Pues bien, en el caso de que ese algo sea el portadocumentos el resultado es devastador pero ¿podría ser evitable?&lt;br /&gt;&lt;br /&gt;Hoy la tecnología está en condiciones de brindar una respuesta efectiva y confiable para la cuestión de la información de identificación de una persona real. ¿Cuál es la finalidad última de un documento de identidad? Como su nombre lo indica, identificar a la persona. Creo que hoy en día es factible construir un gran sistema completamente automatizado para la identificación de personas, y brindaría algunos beneficios impensados ¿En qué consistiría este sistema? Dicho simplemente, se trataría de una gran base de datos global donde cada persona tendría un registro y le permitiría identificarse ante las autoridades además de llevar una especie de base de datos personal. ¿Qué necesitamos para implementarlo? En principio, sus dos pilares fundamentales serían: una red de información global, disponible en todo momento y con fácil acceso; y en segundo lugar, una forma automatizada de identificar unívocamente a un ser humano. El primer pilar ya está resuelto, se podría utilizar la red Internet, con algún protocolo seguro que permita la circulación de los datos fuera del alcance de personas malintencionadas. La aplicación de fuertes políticas de seguridad para este sistema es esencial, y dada su importancia está plenamente justificada. El segundo punto sería una forma de leer y almacenar un identificador único para cada persona, sería como una especie de extracción en tiempo real de un ADN digital que funcionaría como única prueba de identidad. Los esfuerzos de la tecnología en ese sentido están también bastante encaminados y ya existen sistemas que pueden identificar a las personas por medio de la huella digital o de la lectura del iris; sobrarán unos cinco años de investigación y desarrollo para que estos sistemas puedan pulirse y abaratarse, y para que puedan estar disponibles masivamente (por ejemplo, respecto de la lectura de la huella digital, un pequeño inconveniente que se debe resolver es el problema de la falsificación. No es que sea fácil falsificar un dedo pero sí lo es obtener un dedo desprovisto de dueño… por eso, junto con la lectura de la huella digital se deberán desarrollar mecanismos para que solo sean reconocidos dedos que pertenezcan a una mano, y la mano a un cuerpo).&lt;br /&gt;&lt;br /&gt;En Argentina, hace algunos años, se ha implementado un Código Bancario Único (CBU) que permite unificar toda la información bancaria de cada persona real bajo un mismo registro. El sistema que estoy proponiendo, llevaría explota esta idea y la lleva al resto de los aspectos de la información de una persona. El &lt;em&gt;&quot;Sistema Global de Documentación Digital&quot;&lt;/em&gt; podría almacenar toda la información disponible y pública acerca de una persona. No solo los datos de sus cuentas bancarias estarían registrados y disponibles, también su historia de crédito, su prontuario, su situación impositiva, probablemente su historia clínica podría estar disponible en el caso de que la persona sufra un ataque, los médicos que lo atiendan podrían disponer de esa información para establecer rápidamente el mejor tratamiento. Muchos pensarán que esto sería un abuso por parte del Estado y que mucha de la información no debería estar disponible, y tienen razón. La implementación de un sistema de esta naturaleza debe ir precedida de una profunda discusión acerca de qué tipo de información sobre una persona puede ser de acceso público, y qué información debe estar disponible sólo para algunas instituciones de la sociedad. Así,  por ejemplo, en un operativo policial se podría acceder a la historia delictiva de una persona. Y por último, podría haber otra parte de la información personal que fuera accedida solo en forma condicional, por orden de un juez, ante una circunstancia especial o por expresa autorización de la persona. Por otro lado, y siguiendo los lineamientos que se expusieron en nuestra constitución, por la aplicación del habeas data, toda persona debería tener acceso instantáneo a cualquier información que se haya almacenado sobre él mismo, aunque probablemente, no tenga derecho para modificarla (por ejemplo, si se trata de hechos históricos sobre su vida que se encuentran debidamente documentados). La cuestión de que esto sea ahora posible no habilita su aplicación automática porque una tecnología como ésta puede tener profundas implicancias sociales, y son los actores de la sociedad y no los tecnólogos, los responsables por su aplicación.&lt;br /&gt;&lt;br /&gt;Un sistema de estas características, además de evitarnos lo desagradable de perder y tener que renovar todos los documentos, permitiría simplificar muchas situaciones cotidianas. Por ejemplo, nadie ya nos pediría un documento para nada, bastaría con mirar una camarita, o apoyar el pulgar en un sensor para que automáticamente se produzca la identificación. Este sistema estaría disponible en todos lados, y para todas las instituciones o comercios que requieran nuestra identificación. En el aeropuerto, en el cajero automático, en las dependencias públicas, etc. Además, a partir de allí se podría hacer realidad el dinero electrónico. Uno podría identificarse con el pulgar en un comercio, de manera que se autorice a este a debitar un importe de mi cuenta y así comprar sin necesidad de llevar la plata y ni siquiera una tarjeta magnética. Por último, como aplicación adicional, cada uno tendría la posibilidad de almacenar información personal y privada, que solo pueda ser accedida por nuestros dispositivos de información y que nos permita tener una especie de &quot;personalidad digital&quot; que configure nuestros aparatos para trabajar como nos gusta, o que lleve un perfil de nuestras preferencias y nos acerque aquella información que nos interesa, etc. Las aplicaciones para este sistema son muchísimas y provocarían un salto innovativo en la administración de la información personal.&lt;br /&gt;&lt;br /&gt;La creación de semejante archivo de datos personales de una sociedad cambiaría sensiblemente la relación entre los ciudadanos y las instituciones, otorgándole al Estado una función nueva: ser gestor y protector de los datos personales de sus ciudadanos, una función que resultará primordial y que integrará al Estado en el núcleo de la sociedad. Además, modificará nuestra relación con las máquinas, porque una vez más la información se pondrá al servicio de la persona, permitiéndonos que pensemos en cosas más creativas e importantes que, por ejemplo ¿dónde habré dejado el maldito portadocumentos?</description><link>http://enproduccion.blogspot.com/2006/07/documentos-por-favor.html</link><author>noreply@blogger.com (Diego Cofré)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25169098.post-115098756714611501</guid><pubDate>Thu, 22 Jun 2006 14:44:00 +0000</pubDate><atom:updated>2006-07-20T12:57:22.923-03:00</atom:updated><title>Estar On Line</title><description>Cuando se creó la Internet, allá por la década de 1980, uno de sus objetivos fue establecer una red permanente a través de amplios territorios. De esta manera se podía hacer circular la información en forma confiable e instantánea a lo largo y ancho del planeta. Es decir que se buscó desterritorializar la información, convertirla en &quot;global&quot;. Sin embargo, no se pudo lograr este objetivo verdaderamente. ¿Por qué? Porque si bien es cierto que la información está disponible &quot;en cualquier parte, en cualquier momento&quot;, honestamente no lo está para nosotros, los seres humanos. En realidad, la información estuvo disponible para un aparato grande y pesado, y atado a una cantidad de recursos como ser electricidad teléfono, etc. Difícilmente un hombre pueda congeniar con la personalidad de ese aparato, las personas somos seres movedizos, curiosos, y definitivamente no nos convence estar atados a la información.&lt;br /&gt;&lt;br /&gt;Para que se pudiera cumplir el sueño de la información disponible siempre y en todo lugar hizo falta un poco más de innovación tecnológica, específicamente la construcción de computadoras portátiles (de falda, de mano, de bolsillo) y una tecnología de comunicación sin cables que permita &quot;atarlas&quot; pero conservando la libertad de movimiento. La realización de la primera de estas innovaciones vendrían a ser las laptop y las handhelds, de las cuales la última en este momento representa la tecnología más novedosa y dinámica y es la que se postula para lo que será la computación móvil de los próximos años. Para la segunda función, hoy se perfila muy bien la  tecnología &quot;Wi-Fi&quot;, un método de comunicaciones inalámbricas que se ha convertido prácticamente en un estándar a partir del año 2001.&lt;br /&gt; &lt;br /&gt;La palabra &quot;Wi-Fi&quot; es un acrónimo de Wireless Fidelity (fidelidad inalámbrica) y consiste básicamente en una red de computadoras similar a las viejas LAN pero ahora sin cables y con la posibilidad de moverse de un lado a otro sin perder conexión. Técnicamente, esto se logra a través de los llamados Access Point (puntos de acceso), que trabajan en la banda de radio de los 2,4ghz. Cuando un dispositivo entra en el area de cobertura del aparato, también llamado Hot Spot, si pasa las barreras de seguridad, éste queda habilitado para usar los servicios que el hot spot provea. Además, varios Acces Point pueden instalarse de manera contigua para ampliar el alcance del hot spot, y así el usuario podría ir desplazándose y pasando de mano sin perder la conexión, algo similar a la forma en que funciona la telefonía celular.&lt;br /&gt;&lt;br /&gt;Como es fácil deducir, las implicancias de esta invención son prácticamente revolucionarias. Porque no solamente se trata de una tecnología que permitirá suprimir los cables en instalaciones de red en casa o la oficina, sino que hace posible la implementación de redes públicas, donde se ofrecerán los servicios de comunicación a cualquiera que se encuentre dentro del hot spot. Además, le arrebata el monopolio que ejerció la PC sobre Internet, a partir de aquí cualquier aparato que esté en un hot spot podrá disponer de servicios de red, y por cualquier aparato nos referimos a autos, tostadoras, heladeras, teléfonos, relojes, etc; una nueva generación de &quot;bichos inteligentes&quot; que ahora se convierten en posibles. Se prevé que de aquí a unos años existan ciudades y hasta autopistas y caminos que se encuentren completamente cubiertos por esta tecnología, haciendo de la internet una plataforma cada vez más omnipresente. El abaratamiento de esta tecnología durante el año 2003 hizo que aparezcan millares de hot spots públicos y privados en todo el mundo. En Estados Unidos durante el año 2001 comenzaron a aparecer los primeros hot spots en aeropuertos y hoteles. Actualmente es la región que concentra la mayor cantidad de puntos de acceso: cadenas de comidas como Mc Donalds o cafés como Starbucks ya ofrecen a sus clientes la posibilidad de conectarse mientras se encuentran dentro de sus locales como un servicio adicional. También existe un proyecto de cubrir toda la ciudad de Nueva York con la que sería la red Wi-Fi más grande del mundo.&lt;br /&gt;&lt;br /&gt;En Argentina también hay algunas experiencias en el tema, aunque más aislados. Una de las más significativas, consiste en la conexión de toda la zona balnearia de las Grutas (cerca de Puerto Madryn) para ofrecer servicio de internet a los visitantes en forma libre y gratuita. En Buenos Aires  disponemos de algunos hot spots instalados en hoteles (NH, República, Intercontinental, Savoy, Elevage), universidades (UCA, UCES) y algunos cafés y restaurants (Museo Renault, Mondo Spaghetti, Spell). Sin duda en los próximos meses veremos crecer hotspots como hongos.&lt;br /&gt;&lt;br /&gt;Hoy ya podemos imaginar como será este mundo donde la información estará disponible siempre y en todo lugar, finalmente podremos contar con esa red de redes global y permanente. La internet con cables nos acercaba un poco la biblioteca, lo que antes estaba fuera de nuestro alcance, ahora lo ponía un poco mas cerca, pero todavía debíamos tomarnos la molestia de ir hacia la máquina, prenderla, conectarnos y poner en marcha el motor de búsqueda. La red global inalámbrica no solo nos permite tener la biblioteca en el bolsillo todo el tiempo sino que hace posible que la información que nos interesa viaje hasta nosotros y que nos encuentre. Ahora la biblioteca nos chista, nos toca el hombro y nos desafía a que le hagamos un lugar en nuestra vida.&lt;br /&gt;&lt;br /&gt;Recursos: &lt;a href=&quot;http://www.wirelessargentina.net.ar&quot;&gt;Wireless Argentina&lt;/a&gt;</description><link>http://enproduccion.blogspot.com/2006/06/estar-on-line.html</link><author>noreply@blogger.com (Diego Cofré)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25169098.post-114668829734446001</guid><pubDate>Wed, 03 May 2006 20:13:00 +0000</pubDate><atom:updated>2008-09-15T14:39:59.633-03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">abstract factory</category><category domain="http://www.blogger.com/atom/ns#">arquitectura</category><category domain="http://www.blogger.com/atom/ns#">impresoras</category><category domain="http://www.blogger.com/atom/ns#">programación</category><category domain="http://www.blogger.com/atom/ns#">visual basic</category><title>Implementar drivers de impresora en Visual Basic 2005</title><description>&lt;p&gt;Muchas veces en nuestras aplicaciones tenemos la necesidad de utilizar impresoras no estándar como por ejemplo, impresoras de tickets o controladores fiscales. Estos simpáticos aparatos frecuentemente son incompatibles entre sí, lo cual para nosotros significa escribir código que maneje cada modelo individualmente. En sistemas comerciales, donde el soporte para distintos modelos de una misma entidad (en este caso la impresora) es un imperativo, la situación se nos complica un poco.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;Una solución posible sería guardar en una variable el tipo de impresora que el usuario ha configurado, y en el momento de imprimir dibujar un gran Select Case, que según la impresora, invoque a una u otra rutina cuyo código implementará la lógica particular de cada periférico. Esta solución, además de ser horrible, tiene un problema muy concreto: no es escalable. Cuando el sistema crezca, probablemente la lista de impresoras soportadas también se extienda y nuestro Select Case, junto con las rutinas a las que llama, se convertirán en monstruos inmantenibles. Algo así, por ejemplo:&lt;/p&gt;&lt;pre&gt;&lt;span style=&quot;font-family:Georgia,serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Private&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Sub&lt;/span&gt; ImprimirALaViejaUsanza(&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;ByVal&lt;/span&gt; Texto &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;As&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;String&lt;/span&gt;)&lt;br /&gt;     &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Select&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Case&lt;/span&gt; mTipoImpresora&lt;br /&gt;         &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Case&lt;/span&gt; &lt;span style=&quot;color: rgb(178, 34, 34);&quot;&gt;&quot;Impresora1&quot;&lt;/span&gt;&lt;br /&gt;             ImprimirEnImpresora1(Texto)&lt;br /&gt;         &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Case&lt;/span&gt; &lt;span style=&quot;color: rgb(178, 34, 34);&quot;&gt;&quot;Impresora2&quot;&lt;/span&gt;&lt;br /&gt;             ImprimirEnImpresora2(Texto)&lt;br /&gt;         &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Case&lt;/span&gt; &lt;span style=&quot;color: rgb(178, 34, 34);&quot;&gt;&quot;Impresora3&quot;&lt;/span&gt;&lt;br /&gt;             ImprimirEnImpresora3(Texto)&lt;br /&gt;         &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Case&lt;/span&gt; &lt;span style=&quot;color: rgb(178, 34, 34);&quot;&gt;&quot;Impresora4&quot;&lt;/span&gt;&lt;br /&gt;             ImprimirEnImpresora4(Texto)&lt;br /&gt;         &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Case&lt;/span&gt; &lt;span style=&quot;color: rgb(178, 34, 34);&quot;&gt;&quot;Impresora5&quot;&lt;/span&gt;&lt;br /&gt;             ImprimirEnImpresora5(Texto)&lt;br /&gt;         &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Case&lt;/span&gt; &lt;span style=&quot;color: rgb(178, 34, 34);&quot;&gt;&quot;Impresora6&quot;&lt;/span&gt;&lt;br /&gt;             ImprimirEnImpresora6(Texto)&lt;br /&gt;         &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Case&lt;/span&gt; &lt;span style=&quot;color: rgb(178, 34, 34);&quot;&gt;&quot;Impresora7&quot;&lt;/span&gt;&lt;br /&gt;             ImprimirEnImpresora7(Texto)&lt;br /&gt;         &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Case&lt;/span&gt; &lt;span style=&quot;color: rgb(178, 34, 34);&quot;&gt;&quot;Impresora8&quot;&lt;/span&gt;&lt;br /&gt;             ImprimirEnImpresora8(Texto)&lt;br /&gt;         &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Case&lt;/span&gt; &lt;span style=&quot;color: rgb(178, 34, 34);&quot;&gt;&quot;Impresora9&quot;&lt;/span&gt;&lt;br /&gt;             ImprimirEnImpresora9(Texto)&lt;br /&gt;     &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;End&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Select&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;End&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Sub&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;En los tiempos de la programación estructurada ésta era la única opción para manejar distintas periféricos, pero hoy existen formas mucho más elegantes, que pueden prevenir la esquizofrenia por lectura de código spaghetti. Por eso, para los iniciados en las artes de la programación orientada a objetos mostraremos otra solución utilizando polimorfismo por herencia. &lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-weight: bold;font-size:130%;&quot; &gt;A trabajar&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Para mostrar el ejemplo, construiremos una pequeña aplicación tipo Notepad, que solamente tendrá funcionalidad para imprimir y seleccionar impresora. Para que todo quede prolijito, pondremos la interfaz de usuario en un proyecto tipo “WinForms” al cual llamaremos DriversFront, y la lógica de manejo de impresoras en un proyecto aparte de tipo “librería de clases”, el cual titularemos DriversBack. El proyecto DriversFront tendrá una referencia al proyecto DriversBack, para utilizar los servicios y las clases contenidas en él.&lt;br /&gt;&lt;br /&gt;Una vez que tenemos el esqueleto de la solución, comenzaremos a trabajar sobre la arquitectura. La idea es diseñar un objeto impresora genérico que tenga la funcionalidad de base que requeriremos a nuestros drivers. En nuestro caso, implementaremos tres métodos: Abrir(), Cerrar() e Imprimir(Texto), este último requerirá como parámetro el texto a ser impreso. Para nuestro ejemplo, el código sería así:&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Public&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;MustInherit&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Class&lt;/span&gt; ImpresoraBase&lt;br /&gt;  &lt;span style=&quot;color: rgb(0, 128, 0);&quot;&gt;&#39;&#39;&#39; &lt;summary&gt;&lt;/summary&gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color: rgb(0, 128, 0);&quot;&gt;&#39;&#39;&#39; Abre e inicializa los recursos que utilizará la impresora&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color: rgb(0, 128, 0);&quot;&gt;&#39;&#39;&#39; &lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Public&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;MustOverride&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Sub&lt;/span&gt; Abrir()&lt;br /&gt;  &lt;span style=&quot;color: rgb(0, 128, 0);&quot;&gt;&#39;&#39;&#39; &lt;summary&gt;&lt;/summary&gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color: rgb(0, 128, 0);&quot;&gt;&#39;&#39;&#39; Imprime el texto enviado como parámetro&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color: rgb(0, 128, 0);&quot;&gt;&#39;&#39;&#39; &lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Public&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;MustOverride&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Sub&lt;/span&gt; Imprimir(&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;ByVal&lt;/span&gt; Texto &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;As&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;String&lt;/span&gt;)&lt;br /&gt;  &lt;span style=&quot;color: rgb(0, 128, 0);&quot;&gt;&#39;&#39;&#39; &lt;summary&gt;&lt;/summary&gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color: rgb(0, 128, 0);&quot;&gt;&#39;&#39;&#39; Cierra y libera los recursos de la impresora&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color: rgb(0, 128, 0);&quot;&gt;&#39;&#39;&#39; &lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Public&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;MustOverride&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Sub&lt;/span&gt; Cerrar()&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;End&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Class&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;¿Simple no? Esta es nuestra clase base, su modificador MustInherit determina que no puede ser instanciada directamente sino que deberá ser extendida. A expensas de simplificar el ejemplo la redujimos a sólo tres métodos, una clase del mundo real probablemente ostentaría algunas propiedades, campos e incluso podríamos escribir métodos para que sean “vistos” solamente por sus clases hijas (protected). Como decía, de esta clase derivaremos otras que se ocuparán del manejo de cada impresora particular. Entonces, para una impresora de tipo X corresponderá una clase ImpresoraX que heredará de ImpresoraBase y que obligatoriamente (gracias al MustOverride) deberá escribir código para los métodos Abrir, Imprimir y Cerrar. Veamos la realización de una impresora virtual que escribirá la salida en un archivo de texto:&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Public&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Class&lt;/span&gt; ImpresoraArchivo&lt;br /&gt;  &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Inherits&lt;/span&gt; ImpresoraBase&lt;br /&gt;  &lt;span style=&quot;color: rgb(0, 128, 0);&quot;&gt;&#39;este campo es el archivo que utilizaremos para imprimir&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Dim&lt;/span&gt; strArchivo &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;As&lt;/span&gt; IO.StreamWriter&lt;br /&gt;  &lt;span style=&quot;color: rgb(0, 128, 0);&quot;&gt;&#39;nombre del archivo de salida&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Const&lt;/span&gt; NOMBREARCHIVOSALIDA &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;As&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;String&lt;/span&gt; = &lt;span style=&quot;color: rgb(178, 34, 34);&quot;&gt;&quot;ImpresionArchivo.txt&quot;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Public&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Overrides&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Sub&lt;/span&gt; Abrir()&lt;br /&gt;      &lt;span style=&quot;color: rgb(0, 128, 0);&quot;&gt;&#39;abrimos el archivo&lt;/span&gt;&lt;br /&gt;      strArchivo = &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;New&lt;/span&gt; IO.StreamWriter(&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;String&lt;/span&gt;.Format(&lt;span style=&quot;color: rgb(178, 34, 34);&quot;&gt;&quot;{0}{1}&quot;&lt;/span&gt;, ObtenerDirectorioDeEjecucion, NOMBREARCHIVOSALIDA), &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;True&lt;/span&gt;)&lt;br /&gt;  &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;End&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Sub&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Public&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Overrides&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Sub&lt;/span&gt; Cerrar()&lt;br /&gt;      strArchivo.WriteLine()&lt;br /&gt;      strArchivo.WriteLine(&lt;span style=&quot;color: rgb(178, 34, 34);&quot;&gt;&quot;__________________&quot;&lt;/span&gt;)&lt;br /&gt;      strArchivo.Close()&lt;br /&gt;  &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;End&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Sub&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Public&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Overrides&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Sub&lt;/span&gt; Imprimir(&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;ByVal&lt;/span&gt; Texto &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;As&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;String&lt;/span&gt;)&lt;br /&gt;      strArchivo.Write(Texto)&lt;br /&gt;      strArchivo.Flush()&lt;br /&gt;  &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;End&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Sub&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Private&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Function&lt;/span&gt; ObtenerDirectorioDeEjecucion() &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;As&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;String&lt;/span&gt;&lt;br /&gt;      &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Dim&lt;/span&gt; DirEjecucion &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;As&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;String&lt;/span&gt; = &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;My&lt;/span&gt;.Application.Info.DirectoryPath&lt;br /&gt;      &lt;span style=&quot;color: rgb(0, 128, 0);&quot;&gt;&#39;si no termina en contrabarra, la agregamos&lt;/span&gt;&lt;br /&gt;      &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;If&lt;/span&gt; DirEjecucion.EndsWith(&lt;span style=&quot;color: rgb(178, 34, 34);&quot;&gt;&quot;\&quot;&lt;/span&gt;) &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Then&lt;/span&gt;&lt;br /&gt;          &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Return&lt;/span&gt; DirEjecucion&lt;br /&gt;      &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Else&lt;/span&gt;&lt;br /&gt;          &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Return&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;String&lt;/span&gt;.Format(&lt;span style=&quot;color: rgb(178, 34, 34);&quot;&gt;&quot;{0}\&quot;&lt;/span&gt;, DirEjecucion)&lt;br /&gt;      &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;End&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;If&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;End&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Function&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;End&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Class&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;img alt=&quot;Diagrama de clases&quot; src=&quot;http://photos1.blogger.com/blogger/2403/2624/320/DiagramaClases.jpg&quot; /&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;font-size:85%;&quot; &gt;&lt;strong&gt;Aquí vemos la estructura de herencia de nuestros drivers. Las tres clases derivadas implementan Abrir, Cerrar e Imprimir, aunque también pueden contener otros métodos, campos y propiedades.&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Lo que vemos aquí, señoras y señores, es el fruto de la herencia. La clase ImpresoraArchivo es un vástago de ImpresoraBase, que para no ser desheredado ha debido implementar los métodos Abrir(), Cerrar() e Imprimir(Texto), pero con derecho a utilizar su propia y particular manera. En este caso, la impresora en realidad abre un archivo en el disco y escribe la salida en él. En una aplicación real quizás este driver no serviría de mucho, (salvo para hacer pruebas de impresión sin gastar papel) pero ahora veremos que lo realmente valioso del ejemplo es la arquitectura usada, que permite a cada hijo manejarse de manera independiente, utilizando su propia lógica -que puede ser muy distinta a la de sus “hermanos”- para realizar la tarea. Observen que la clase hija puede también incorporar funcionalidad adicional, por ejemplo ImpresoraArchivo tiene un método privado adicional –ObtenerDirectorioDeEjecucion()- por el cual dilucida el path de ejecución del sistema. Las clases hijas tienen la obligación de implementar ciertos caracteres que mandan sus padres, pero nada les impide desarrollar nuevos métodos, campos y propiedades, incluso pueden ampliar la interfaz con métodos y propiedades públicas (aunque, como veremos más adelante, esto no nos servirá de mucho en este tipo de arquitectura).&lt;br /&gt;Volviendo al ejemplo, hemos desarrollado tres drivers: una impresora virtual a archivo, otra impresora virtual a pantalla (el cual abre un WinForm y escribe en él la salida de la impresora, inútil pero didáctico) y un tercero que sería el hermano vago ya que no hace nada. En realidad este último se comporta como impresora nula, y lo utilizaremos para el caso en que el usuario decida trabajar sin impresora.&lt;br /&gt;&lt;br /&gt;Como vemos, la implementación de cada driver puede manejarse fácilmente, sólo es cuestión de heredar del padre correcto (evitemos la comparación con la vida real), y escribir la funcionalidad deseada en la plantilla. La cuestión a resolver ahora es cómo imprimiremos en nuestra impresora. Aquí echaremos manos a la magia de los objetos. El truco es utilizar Polimorfismo, de esta manera nuestra aplicación declarará un objeto de tipo ImpresoraBase, pero en el momento de ser instanciado su lugar será tomado por uno de sus hijos. Esto lo veremos en un momento, ahora déjenme mostrarles cómo usaremos nuestra impresora:&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;   &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Private&lt;/span&gt; mImpresoraSeleccionada &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;As&lt;/span&gt; DriversBack.ImpresoraBase&lt;br /&gt;&lt;br /&gt;  &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Private&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Sub&lt;/span&gt; mnuImprimir_Click(&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;ByVal&lt;/span&gt; sender &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;As&lt;/span&gt; System.Object, &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;ByVal&lt;/span&gt; e &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;As&lt;/span&gt; System.EventArgs) &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Handles&lt;/span&gt; mnuImprimir.Click&lt;br /&gt;      &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;If&lt;/span&gt; mImpresoraSeleccionada &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;IsNot&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Nothing&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Then&lt;/span&gt;&lt;br /&gt;          &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Try&lt;/span&gt;&lt;br /&gt;              mImpresoraSeleccionada.Abrir()&lt;br /&gt;              mImpresoraSeleccionada.Imprimir(TextBox1.Text)&lt;br /&gt;          &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Catch&lt;/span&gt; ex &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;As&lt;/span&gt; Exception&lt;br /&gt;              MessageBox.Show(&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;String&lt;/span&gt;.Format(&lt;span style=&quot;color: rgb(178, 34, 34);&quot;&gt;&quot;Se produjo un error al imprimir: {0}&quot;&lt;/span&gt;, ex.Message), &lt;span style=&quot;color: rgb(178, 34, 34);&quot;&gt;&quot;Error&quot;&lt;/span&gt;, MessageBoxButtons.OK, MessageBoxIcon.Error)&lt;br /&gt;          &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Finally&lt;/span&gt;&lt;br /&gt;              mImpresoraSeleccionada.Cerrar()&lt;br /&gt;          &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;End&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Try&lt;/span&gt;&lt;br /&gt;      &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Else&lt;/span&gt;&lt;br /&gt;          MessageBox.Show(&lt;span style=&quot;color: rgb(178, 34, 34);&quot;&gt;&quot;Para imprimir primero seleccione una impresora.&quot;&lt;/span&gt;, &lt;span style=&quot;color: rgb(178, 34, 34);&quot;&gt;&quot;Atención&quot;&lt;/span&gt;, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)&lt;br /&gt;      &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;End&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;If&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;End&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Sub&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;&lt;/span&gt;Simplemente, llamamos al método Abrir() de nuestro objeto ImpresoraBase declarado en la primera línea, imprimimos el texto con Imprimir(TextBox1.Text) y la cerramos en el Finally con Cerrar(). S-I-M-P-L-E. La belleza de este método es que, sin importar si el sistema soporta una impresora o un centenar, la rutina se mantiene inmutable ya que generalmente los cambios se harán en la implementación de cada driver. Probablemente, el interior del método Abrir() para una impresora determinada es un infierno; puede ser necesario abrir puertos, chequear configuración, si está activa, tiene papel o está en error. Para imprimir, algunas impresoras de tickets usan lenguajes propietarios; entonces en el método Imprimir(Texto) de esas impresoras deberemos traducir el texto al lenguaje de cada engendro particular. No obstante, desde el punto de vista del consumidor de la clase, el llamador sabe que lo único que tiene que hacer para imprimir un texto es invocar el método que tan responsablemente los hijos de ImpresoraBase se han comprometido a resolver, de una manera o de otra.&lt;br /&gt;&lt;br /&gt;La belleza de este método es que, sin importar si el sistema soporta una impresora o un centenar, la rutina se mantiene inmutable ya que generalmente los cambios se harán en la implementación de cada driver.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;font-size:130%;&quot; &gt;El patrón&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Lo único que nos queda por resolver es la forma de instanciar la clase. Es decir, cómo haremos para que, en tiempo de ejecución se pueda utilizar una impresora u otra de acuerdo a las necesidades de cada usuario. Para ello utilizaremos una clase adicional llamada, no caprichosamente, ImpresoraFactory. ¿Porqué le pusimos este nombre? Porque en realidad, lo que estamos haciendo aquí corresponde a un patrón de arquitectura, más específicamente el apodado Simple Factory (ver recuadro). En el contexto de este patrón, la responsabilidad de la clase Factory es proveer servicios para instanciar la clase correspondiente en tiempo de ejecución. Ésta puede publicar algún tipo de matriz o colección de claves cuyos elementos se usarán en el método de creación para instanciar el objeto. En nuestro ejemplo, así quedaría nuestra clase ImpresoraFactory.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Public&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Class&lt;/span&gt; ImpresoraFactory&lt;br /&gt;  &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Private&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Shared&lt;/span&gt; mTiposDeImpresora &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;As&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;String&lt;/span&gt;() = {&lt;span style=&quot;color: rgb(178, 34, 34);&quot;&gt;&quot;Impresora Virtual a archivo&quot;&lt;/span&gt;, &lt;span style=&quot;color: rgb(178, 34, 34);&quot;&gt;&quot;Impresora Virtual a pantalla&quot;&lt;/span&gt;, &lt;span style=&quot;color: rgb(178, 34, 34);&quot;&gt;&quot;Sin impresora&quot;&lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;  &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Public&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Shared&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;ReadOnly&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Property&lt;/span&gt; TiposDeImpresora()&lt;br /&gt;      &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Get&lt;/span&gt;&lt;br /&gt;          &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Return&lt;/span&gt; mTiposDeImpresora&lt;br /&gt;      &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;End&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Get&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;End&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Property&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Public&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Function&lt;/span&gt; InstanciarImpresora(&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;ByVal&lt;/span&gt; TipoDeImpresora &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;As&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;String&lt;/span&gt;) &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;As&lt;/span&gt; ImpresoraBase&lt;br /&gt;      &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Select&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Case&lt;/span&gt; TipoDeImpresora&lt;br /&gt;          &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Case&lt;/span&gt; mTiposDeImpresora(0)&lt;br /&gt;              &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Return&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;New&lt;/span&gt; ImpresoraArchivo&lt;br /&gt;          &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Case&lt;/span&gt; mTiposDeImpresora(1)&lt;br /&gt;              &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Return&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;New&lt;/span&gt; ImpresoraPantalla&lt;br /&gt;          &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Case&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Else&lt;/span&gt;&lt;br /&gt;              &lt;span style=&quot;color: rgb(0, 128, 0);&quot;&gt;&#39;no se ha configurado ninguna impresora&lt;/span&gt;&lt;br /&gt;              &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Return&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;New&lt;/span&gt; ImpresoraNula&lt;br /&gt;      &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;End&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Select&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;End&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Function&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;End&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Class&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;Como decíamos, la propiedad TiposDeImpresora nos devuelve una matriz que representa todas las impresoras disponibles. Con el método InstanciarImpresora(TipoDeImpresora) obtenemos a cambio de uno de los elementos del array, un objeto hijo de ImpresoraBase, que como vimos, tiene todo lo necesario para que podamos imprimir. Desde el consumidor de la clase el código para crear el objeto se vería así:&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;   &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Private&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Sub&lt;/span&gt; mnuConfig_Click(&lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;ByVal&lt;/span&gt; sender &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;As&lt;/span&gt; System.Object, &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;ByVal&lt;/span&gt; e &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;As&lt;/span&gt; System.EventArgs) &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Handles&lt;/span&gt; mnuConfig.Click&lt;br /&gt;      &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Dim&lt;/span&gt; fconf &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;As&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;New&lt;/span&gt; frmSeleccionarImpresora&lt;br /&gt;      fconf.ShowDialog()&lt;br /&gt;&lt;br /&gt;      &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Dim&lt;/span&gt; ImprFactory &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;As&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;New&lt;/span&gt; DriversBack.ImpresoraFactory&lt;br /&gt;      mImpresoraSeleccionada = ImprFactory.InstanciarImpresora(fconf.ImpresoraSeleccionada)&lt;br /&gt;  &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;End&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 0, 255);&quot;&gt;Sub&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;Resumiendo, en el momento de llamar a InstanciarImpresora(TipoDeImpresora), le pasaremos como parámetro el String correspondiente a la impresora que ha seleccionado el usuario y este nos devolverá la impresora indicada. Esta será la única clase que tendremos que modificar en el caso de agregar más impresoras -además de obviamente construir la clase hija que la manejará- poniendo más valores en el arreglo de strings, y reconociendo el tipo de impresora pedido para la instanciación. Con el tiempo, el código de InstanciarImpresora(TipoDeImpresora) podría crecer, pero es el único lugar donde tendríamos que manejarnos con delicadeza. Si lo comparamos con el escenario inicial, donde para cada tipo de impresora debíamos escribir funciones distintas, creo que hemos dado un salto cualitativo.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size:130%;&quot;&gt;Para terminar&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;En este artículo hemos visto una forma de utilizar la herencia para hacer más claro y manejable el código de manejo de impresoras en nuestras aplicaciones. No obstante, esta arquitectura puede utilizarse para cualquier tipo de periféricos. Por ejemplo, podría adaptarse para manejar controladoras fiscales. En este caso la clase base debería ser un poco más compleja ya que se necesitarían AbrirTicketFiscal, AgregarItem, AgregarPago, etc; sin embargo, el patrón sería el mismo (y justamente ahí está la razón de ser de los patrones). Otros destinos podrían ser: servicios de validación de transacciones, autorizaciones de tarjetas de crédito on-line o internas, salidas a displays de caracteres, etc. Siempre es deseable que este tipo de funcionalidad sea implementada con drivers, ya que aunque en el presente nuestro sistema trabaje con un solo tipo de aparato, nunca sabemos cuando podría requerir soporte otras marcas o modelos y lo mejor es, como un buen boy-scout, estar siempre listo ;-)&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://www.elguille.info/colabora/NET2006/diegocofre_drivers.htm&quot;&gt;Para ver el artículo publicado en la página del Guille y bajar el ejemplo, hacé click aquí&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;SOBRE PATRONES DE ARQUITECTURA&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Extraído de la arquitectura clásica, en arquitectura de software un patrón: “describe un problema que ocurre una y otra vez en nuestro entorno, y además, describe el núcleo de la solución a ese problema, de tal manera, que podemos usar esa solución un millón de veces más en el tiempo, sin que tenga que ser la misma cada vez”. La esencia de los patrones es su reutilización y el rápido reconocimiento de una solución a un problema típico, de esta manera se ahorra tiempo “reinventando la rueda”, y se puede manejar un corpus de conocimiento compartido entre los desarrolladores.&lt;br /&gt;El patrón utilizado en esta nota suele llamarse Simple Factory y es considerado una simplificación de Abstract Factory y Factory Method, sin embargo los tres comparten la misma base conceptual. Se trata de un patrón de creación, cuyo objetivo es producir objetos cuyos tipos no se pueden prever hasta el momento de la ejecución. Su particularidad consiste en una clase (generalmente llamada Factory) en la cual se define un método (el Factory Method) a través del cuál se crean instancias de otras clases.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;</description><link>http://enproduccion.blogspot.com/2006/05/implementar-drivers-de-impresora-en.html</link><author>noreply@blogger.com (Diego Cofré)</author><thr:total>3</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25169098.post-114582673281694623</guid><pubDate>Sun, 23 Apr 2006 21:09:00 +0000</pubDate><atom:updated>2006-04-23T18:12:12.820-03:00</atom:updated><title>¡La pasión pibe, la pasión!</title><description>Tengo jóvenes 32 años, pero últimamente siento que me convertí un poco en mi tía Pocha, con los ruleros y todo, diciendo algo así como: “Ay... ¡Qué juventud perdida!” ¿Por qué dice eso, señora? “y... ya no estudian, no leen, se la pasan todo el día vagueando, tomando cerveza y fumando droga”. Bueno, tía, tranquila. No se me emocione que le sube la presión. En realidad, mi preocupación con respecto a la media de pibes de 15 a 24 años actuales pasa por algo mucho más básico; a saber: &lt;em&gt;son total, absoluta y tristemente desapasionados&lt;/em&gt;. Por supuesto, no son todos, pero son tantos que ya han sobrepasado la masa crítica para ser considerada una característica de su generación.&lt;br /&gt;&lt;br /&gt;¿Piensan que exagero? ¿Ustedes tuvieron últimamente charlas con chicos o chicas de esta franja etaria? Bueno, traten de indagar en algo que los apasione, esas cosas que a la gente de todas las épocas los llevó a desvelarse por un sueño, una fiebre incontrolable, algo que no los deje dormir, que los llene de alegría o de ira o de envidia... ¡O de algo! Pues no hay... no hay pasión, lisa y llanamente. Pregunten, hagan la prueba si se animan  ¿Qué te gusta hacer? ¿Ehhhhh? Verán como se dibuja una gran nada en sus rostros.... pasmoso y triste, sí.&lt;br /&gt;&lt;br /&gt;Las razones son difíciles de rastrear, podríamos especular con la época en que vivimos. Tanta crisis, guerras absurdas, malestar de la cultura, malos pronósticos para el futuro, la ecología, el petróleo, el terrorismo. También podría ser nuestra sufrida región tercermundista, y dentro de ella nuestro país lleno de recetas imposibles que siempre terminan en desastre, políticos corruptos y oportunidades para irse al tacho en cualquier momento. Podría ser todo eso, pero lo dudo. A los jóvenes de los sesenta tampoco les tocó vivir en el paraíso, sin embargo, para bien o para mal, eran apasionados por lo que hacían y por lo que creían. Hasta el punto que algunos con una ingenuidad supina se les ocurrió que era bueno quitar y ofrecer la vida por ello, desatando olas de apasionada violencia que por supuesto terminó en terror. Ok, la pasión nublo un poco todo por ahí, pero es innegable que había pasión; y esa pasión movilizaba a la gente a hacer cosas, aunque a veces fueran increíblemente estúpidas.&lt;br /&gt;&lt;br /&gt;Hoy parece que la pasión está pasada de moda. Nos pasamos el día consumiendo pasivamente información, sin pensar, sin tamizar y sin cuestionar nada. A lo sumo un: “que barbaridad!” (y ahí está de nuevo la tía Pocha). ¿Será este el rol de la gente del futuro? Meros consumidores, ya no solo de bienes materiales sino también de información procesada. La radio, la tele, los jueguitos, y las pelis están tan presentes en el imaginario popular que llegan a dictar cómo se debe pensar, cómo se debe actuar, y por supuesto, a que peronista debemos votar en la próxima elección. Si es así, finalmente los terrores de los autores de la década del cincuenta  -que imaginaban el mundo del futuro dominado por grandes corporaciones que imponían su modo de pensar y sentir al resto de la sociedad- se van haciendo realidad, al menos en parte. Lo cual no solo es preocupante, es prácticamente catastrófico para una especie como la humana, que ha llegado hasta este momento histórico movida por la curiosidad, una forma de pasión que nos lleva a preguntarnos más, a conocer el mundo que nos rodea, a arriesgarlo todo por algo que probablemente nos mate, pero la pasión es simplemente incontrolable. En el fondo, eso es lo que nos ha definido como ser humano.&lt;br /&gt;&lt;br /&gt;Hoy los grandes sueños, si es que los hay, es “ser famoso”. Lo cuál no tiene nada de malo pero la pregunta del millón es ¿Cómo? ¿Haciendo qué? “Y... yo toco la guitarra...”, dice uno mientras elige un emoticón de guitarrita en el Messenger (“uhh... alta viola”). ¡Buenísimo, encontramos un apasionado! Pero... ¿y la guitarra? “se me rompió hace un año, la tengo que llevar a arreglar” Uff, casi... Nos vamos, conteniendo el impulso de decirle algo hiriente que probablemente tampoco le importe. Pareciera que la esperanza, si es que queda alguna, es ser famoso pero al estilo “reality-show”. Una fama gratuita, vacía, y por la cual no hay que dar nada a cambio. También efímera y sin sentido, pero eso no importa; la fantasía es ser famoso y nada más. Pero muchachos, tengo una mala noticia: la fama cuesta. La fama cuesta trabajo, tiempo, angustia, miedo y muchas ganas. Todos “los famosos”, en cualquier especialidad, han puesto una ardorosa, casi enfermiza pasión en lo que hicieron. Los músicos se han colgado un instrumento durante horas y han ensayado hasta que les salieron callos, los científicos se quedaron días sin dormir para hacer un experimento o para dar con una fórmula huidiza, los actores han caminado y tocado puertas hasta el hartazgo, han llorado y reído explorando sus emociones más profundas para transmitir eso en sus obras. Tomemos el ejemplo de Guillermo Vilas. Este campeón de tenis argentino de la década del 70, comenzaba su día de entrenamiento haciendo un círculo de tiza en la pared y le pegaba con la pelotita hasta que lo borraba... como se pueden imaginar, no era nada fácil, pero así es cómo una persona normal, con algo de talento y bastante pasión, se convierte en un campeón. Muchas veces el sacrificio los ha llevado ha dejar familia, amigos, o incluso a poner en juego su vida o su equilibrio psicológico arrebatados por la obsesión de lograr la perfección o de ser el mejor. Sería bueno que a cada pibe, antes de anotarse en “Sea el próximo ñato de la Tele”, le dieran un resumen de las vidas de los grandes artistas, músicos, científicos o empresarios que han llegado a la fama. Ninguno de ellos pensó nunca en internarse dos meses en un estudio de televisión; todos tenían cosas mucho más apasionantes para hacer.&lt;br /&gt; Es difícil imaginar a la humanidad sin pasión. Yendo y viniendo apesadumbradamente de su trabajo a la casa, o al boliche, o a donde sea con la misma cara de poker. Supongo que algo pasará que los hará despertar de esta siesta. Porque transitar por la existencia renunciando a lo que nos hace humanos, renunciando a la voluntad de algún día cumplir los sueños aunque sean una quimera, es simplemente desperdiciar la vida. Y esa, creo, es una de las tragedias de nuestros tiempos.</description><link>http://enproduccion.blogspot.com/2006/04/la-pasin-pibe-la-pasin.html</link><author>noreply@blogger.com (Diego Cofré)</author><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25169098.post-114463404089434929</guid><pubDate>Mon, 10 Apr 2006 01:51:00 +0000</pubDate><atom:updated>2008-09-15T14:11:37.158-03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">programador</category><title>Los talentos del programador</title><description>&lt;div style=&quot;text-align: center;&quot;&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDisnFWBGuRaXfMOBSBfkg1GU2q7mTNFlPhluE0VUp3z4XS2HqXabs98mNL6jTNJfiFu0pKOGfLFtfYpbOzsDDc9OCt6iZ80KYtlJy9aI0qkN9s1nd2al4DKRFW4Omjbw4I2Sf/s1600-h/programmer.jpg&quot;&gt;&lt;img style=&quot;cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDisnFWBGuRaXfMOBSBfkg1GU2q7mTNFlPhluE0VUp3z4XS2HqXabs98mNL6jTNJfiFu0pKOGfLFtfYpbOzsDDc9OCt6iZ80KYtlJy9aI0qkN9s1nd2al4DKRFW4Omjbw4I2Sf/s320/programmer.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5246296824562866402&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;En muchos artículos y libros se ha dilucidado sobre las aptitudes que se requieren para ser un buen desarrollador de software. Está claro que haber pasado por una carrera de sistemas, si bien garantiza una cantidad de conocimientos técnicos elementales, no habilita al alumno para ser programador. Tampoco el dominio de una herramienta de programación hace a un desarrollador &lt;strong&gt;&lt;em&gt;realmente bueno&lt;/em&gt;&lt;/strong&gt;, y por esto me refiero a alguien que se le pueda confiar el diseño y la codificación de un sistema que reúna las características de calidad de un software comercial (léase un producto que se pueda vender sin recibir cartas documento por similar cantidad de copias vendidas). Volveremos sobre esto después, sólo déjenme agregar aquí que estamos frente a un caso donde, cómo dice el proverbio, &lt;strong&gt;&lt;em&gt;el hábito no hace al monje&lt;/em&gt;&lt;/strong&gt;. Entonces ¿cómo podemos reconocer quién tiene pasta de programador? ¿Cuáles son las características que nos permiten predecir que alguien puede convertirse en un desarrollador brillante, independientemente de su grado actual de expertise? Son preguntas interesantes para cualquiera que guste de contratar brillantes jóvenes sin experiencia y convertirlos en profesionales de sistemas (y mientras eso sucede, ahorrarse varios miles de pesos, por supuesto).&lt;br /&gt;&lt;br /&gt;Los que saben del tema parecen coincidir que cierta habilidad para la matemática ayuda al pequeño saltamontes que aspira convertirse en programador. Creo que por ahí va la cosa, pero en realidad es un poco más complejo. La matemática y otras ciencias relacionadas, como la geometría, permiten estudiar los fenómenos naturales haciendo una abstracción del mundo real. Son, como suele decirse, un modelo, o sea, una representación simplificada de un universo complejo. El modelo hace un recorte, toma una cantidad de características distintivas de lo que se quiere representar y las pasa al modelo, con sus cualidades y relaciones entre ellas. De alguna manera, el modelo intenta crear un universo en miniatura. Así, cuando decimos “un modelo a escala de una locomotora”, nos referimos a una locomotora reconstruida con idéntico aspecto, sus partes móviles y algunos de sus complejos mecanismos, pero en una escala mas pequeña y manejable, y la mayor parte de las veces más barata (¿vieron lo que valen esos jugetitos? ). Por eso se dice que el aprendiz de programador debe por lo menos sentirse cómodo con cierto nivel de matemática. Y se ve que los creadores de las currículas de las carreras de sistemas piensan eso, y por eso han puesto en ellas una cantidad de matemática que haría sentir un ignorante al mismo Einstein. Pero en realidad, lo esencial en la caja de herramientas intelectuales del programador es la capacidad de abstracción, o más precisamente, la capacidad de realizar modelos del mundo real.&lt;br /&gt;&lt;br /&gt;La actividad de un programador de cierto nivel (el que veíamos arriba) esta llena de modelos. Cuando realizamos software, por ejemplo, para gestionar cierto proceso de un negocio, nos enfrentamos a un desafío de modelización. ¿Cómo pasaríamos a un ambiente informático la gestión de un hotel? Bien, estudiaríamos los procesos más importantes donde nuestro software debería asistir, y después haríamos un modelo informático que representara cada uno de esos procesos. Uno de ellos, sin dudas, sería el check in, y aquí buscaríamos una forma de representar el conserje del hotel, el pasajero, la habitación que ocupará, etc. Todo este trabajo de abstracción, que luego será llamado por el vulgo “la pantalla de check-in”, es en realidad un modelo del proceso traducido al software. Aquí creo, y no en la cantidad de siglas del mundo IT que maneje, está la habilidad esencial de un desarrollador. Algunos discutirán conmigo que en realidad eso es el trabajo del analista, del ingeniero, del arquitecto. Ok, ok.... La realidad es que todos, por más que sean el último escalón de la cadena del desarrollo, tendrán que hacer algo de modelización en algún momento, sobre todo si se dedican a producir sistemas para usuarios finales. La falta del talento para inventar modelos del mundo real hace programadores mediocres, sólo capaces resolver pequeños problemas copiando y pegando código de la ayuda al sistema. He visto profesionales bien preparados, muy hábiles en el manejo del lenguaje, y con un asombroso dominio de APIs, pero que al momento de modelizar un proceso se balanceaban frente al monitor como los peregrinos frente al muro de los lamentos, angustiados, agarrándose la cabeza viendo como sus propios frankesteins se volvían contra ellos. Porque los programadores que no pueden crear buenos modelos, lamentablemente, los crean igual, pero pésimos. Un modelo pésimo es un modelo incomprensible, con partes rejuntadas de cualquier lado, no se entienden y son prácticamente inmodificables. Probablemente uno de estos programadores, en la buena intención de hacer un modelo informático de un barrilete, programe un complicadísimo tacómetro. ¿Para qué? Solo Dios sabe, pero la cuestión es que para modificar el largo de la cola debemos setear el tacómetro a un valor decimal que duplique la altura actual, de lo contrario el barrilete se pintará enteramente de fucsia.... (?) Sí, es delirante, lo sé, pero sucede. Es simplemente un programador que no supo modelizar un barrilete. La programación orientada a objetos ayuda a que los modelos sean más naturales, si queremos modelizar automotores, hacemos un objeto que tenga ruedas y puertas y después heredamos de él autos, camionetas y bla, bla (ya todos conocemos los ejemplos de herencia de los libros). El modelo orientado a objetos ayuda, sí; pero si nos toca construir un modelo un poco más complejo que el de los ejemplos de los libros (que casi siempre son autos y animales, no se por que) y no tenemos esta habilidad para la abstracción de la que estamos hablando... muchacho, estás perdido.&lt;br /&gt;&lt;br /&gt;Por eso, mi pequeño saltamontes, si el pájaro canta pero no vuela, quiere decir que el modelo falla, porque los pájaros &lt;strong&gt;&lt;em&gt;cantan y vuelan&lt;/em&gt;&lt;/strong&gt;. Y para los que no gusten de conclusiones zen, la línea final sería que la destreza fundamental de un buen programador es la capacidad de abstraer y construir pequeños mundos de bits que funcionen y mantengan cierta afinidad con los procesos que representan. A eso, por supuesto, debemos agregarle, como decía Clemente, un cacho de cultura: en este caso un profundo conocimiento de los frameworks y herramientas que utilizaremos para programar. Y ya que estamos enumerando, tampoco vienen mal el sacrificio, la curiosidad y un poquito de comportamiento obsesivo y perfeccionismo. Pero, mi pequeño saltamontes, si programas alas en un pez, ruedas en la pizza o juanetes en un sombrero... mi pequeño saltamontes, quizás tienes un gran futuro como creativo publicitario.</description><link>http://enproduccion.blogspot.com/2006/04/los-talentos-del-programador.html</link><author>noreply@blogger.com (Diego Cofré)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDisnFWBGuRaXfMOBSBfkg1GU2q7mTNFlPhluE0VUp3z4XS2HqXabs98mNL6jTNJfiFu0pKOGfLFtfYpbOzsDDc9OCt6iZ80KYtlJy9aI0qkN9s1nd2al4DKRFW4Omjbw4I2Sf/s72-c/programmer.jpg" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25169098.post-114386246081310746</guid><pubDate>Sat, 01 Apr 2006 03:32:00 +0000</pubDate><atom:updated>2008-09-15T14:16:48.312-03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">historia</category><category domain="http://www.blogger.com/atom/ns#">tecnología</category><title>La historia de un garrotazo</title><description>&lt;div style=&quot;text-align: center;&quot;&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgD8lhZV7z2YDcWJTIWBvUq5CHM5jmQxcCqx4T6ZN-PJNODZLID73nx7MwHMB_bd9scHnR-1KsxKIum_SHMFrk81mNZD22hGzfG-8A9OjoCYGGnEelKZLuwOH0MpfBp4RAmD3Af/s1600-h/ape_2.jpg&quot;&gt;&lt;img style=&quot;cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgD8lhZV7z2YDcWJTIWBvUq5CHM5jmQxcCqx4T6ZN-PJNODZLID73nx7MwHMB_bd9scHnR-1KsxKIum_SHMFrk81mNZD22hGzfG-8A9OjoCYGGnEelKZLuwOH0MpfBp4RAmD3Af/s400/ape_2.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5246298198208766770&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;En &quot;2001: Una odisea del espacio&quot;, se puede ver una escena donde un espécimen a mitad de camino entre simio y hombre descubre que un hueso puede servir para romperle la crisma a un congénere de una tribu vecina. Y mediante este &quot;truco&quot; pudo dominar el sólo a todo un grupo hostil. Este relato es ficcional, pero es de esperarse que un acontecimiento de esta naturaleza pudo haber inaugurado la larga historia de las invenciones humanas, que es ni más ni menos que la historia de la tecnología.&lt;br /&gt;En la actualidad, la tecnología -también llamada &quot;esos aparatitos modernos&quot;- ha mutado un poco en su significado. Ya no usamos el concepto para hablar de las invenciones que han alzado poco a poco la tan mentada civilización, sino que nos relacionamos con ella de manera apasionada. La amamos o la odiamos, o adoptamos una pose apática, pero nunca nos resulta indiferente. Todos nosotros, en mayor o menor medida, tenemos algunas ideas sobre lo que es la tecnología, lo bueno y lo malo que nos ha traído y lo que deberíamos hacer para sacarle algún provecho o evitar ser destruidos. Y todo hombre moderno, sin excepción, está relacionado con la tecnología de alguna forma: por un lado están los amantes de los aparatitos, jóvenes o adultos que se enganchan con cuanto engendro electrónico salga al mercado, sea éste un nuevo celular con botoncitos &quot;inteligentes programados en puro JAVA&quot;, una PC que cabe en el arreglo de una muela o la nueva versión de ludo-matic que se juega con un casquito de realidad virtual. Por otro lado - y en franca oposición con este personaje- están los detractores de la tecnología: gente que rehuye la PC &quot;salvo para mandar mails&quot; por miedo a que la radiación le derrita una supuesta glándula de la sensibilidad humana. En medio de estos dos casos extremos nos encontramos la mayoría de nosotros: gente común y corriente que, muchas veces sin ser completamente conscientes, dependemos en gran medida de la tecnología para realizar nuestras tareas cotidianas.&lt;br /&gt;Por eso, y antes de seguir reflexionando sobre nuestros aparatitos queridos, trataremos de dilucidar a qué nos referimos cuando decimos tecnología, definiéndola y ubicándola en el lugar que se merece, sin confianzas excesivas ni miedos injustificados.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Tecnología = Tekné + logos&lt;/strong&gt;&lt;br /&gt;Recuerdo una definición de escuela primaria que dice que la tecnología es &quot;la aplicación práctica de los principios de la ciencia&quot;. Es una definición simple y efectiva, que permite captar el papel y el proceso tecnológico en una sociedad. Pero a mi entender es un poco limitada y, como veremos, no expresa el significado verdadero del vocablo. En lo personal prefiero definir tecnología como &quot;cualquier técnica, método, proceso, herramienta o aparato que permita ampliar las capacidades humanas para controlar y comprender el entorno material&quot;. Tomando esta definición, existen pocas cosas en nuestro mundo cotidiano que sean &quot;no-tecnología&quot;. Si asumimos que la tecnología puede pensarse como el saber de la humanidad expresado por medio de sus herramientas, sus procesos y su modo de vida en el mundo, ciertamente podemos afirmar que la tecnología está presente en casi todos los objetos de nuestro entorno. Pensemos en algo que no contenga tecnología. ¿Difícil, no? Pienso en un hipotético paisaje natural, absolutamente virgen y poblado solamente por animales y plantas... pero ¿cómo llegamos hasta allí? Como diría el maestro zen: Si existe un paraje virgen, pero nadie está ahí para observarlo ¿el paraje realmente existe? Sospecho que no...&lt;br /&gt;Mejor admitamos que la tecnología no es lo que se ve en las películas. La verdad es que estamos rodeados de tecnología, nuestra cotidaneidad está teñida de estos ingenios que -con un poco de suerte y maña- pueden hacer nuestra vida un poco más productiva. Pero ¿cuál es el origen del término? ¿De donde surge el vocablo tecnología? Al principio decíamos que el hombre primitivo inventó el arma y ese fue el principio de la carrera tecnológica; pero en verdad, debemos admitir que el concepto de tecnología, tal como lo conocemos ahora, es una creación bastante moderna, de la era industrial para ser más precisos. La palabra tecnología es un &quot;remix&quot; moderno de dos palabras griegas: tekné, y logos. Para los griegos, la tekné es lo que hoy llamaríamos oficio (o &quot;arte&quot; en el sentido de una habilidad para la construcción de cosas, algo que se realiza artesanalmente y generalmente con las manos). El &quot;logos&quot; griego es parecido a nuestro concepto de ciencia; a veces se traduce como “palabra” pero en realidad significa algo mas: es el conocimiento, el saber sistemático y organizado, lo que se puede expresar con fórmulas y enunciados. Lo curioso de esta fusion es que los dos conceptos primigenios son decididamente antagónicos: el &quot;saber&quot; manual, práctico, el saber-hacer que era esencialmente misterioso para ellos (lo cual en parte explica la fama de inútil que se le atribuye al filósofo griego promedio). A diferencia de este, el logos es el saber enunciable, que puede ser explicada, sistematizada, pensada y organizada, el saber que implica la tekné es inenunciable, completamente vivencial y lo único que podía hacerse para alcanzarlo era abandonarse a la pura experiencia.&lt;br /&gt;Alrededor de 1750, se produce una gran transformación en nuestra sociedad, una transformación que alcanza incluso al concepto mismo de saber, porque para que lo que después se conoció como revolución industrial fuera posible, fue indispensable que se pudieran diseccionar las &quot;artes&quot;, los &quot;oficios&quot;, las &quot;teknés&quot; y se las pudiera explicar y sistematizar para que cualquier obrero no cualificado fuese capaz de construir los objetos que antes sólo estaban al alcance del gran artesano poseedor de la habilidad y el secreto. En esto consiste la nueva palabra &quot;tecnología&quot;, una especie de manifiesto de la era industrial, donde las artes se hicieron públicas y transparentes, donde se le quitó el halo de misterio que rodeaba al artesano, donde se pudo establecer y explicar la &quot;ciencia del hacer&quot;.&lt;br /&gt;A partir de allí, la fiebre tecnológica se desato en toda la sociedad occidental primero y global después. Pero también con el tiempo comenzó a aflorar el miedo y la preocupación; preocupación que tiene que ver con encauzar la tecnología, con ver de que manera usarla para que no termine volviéndose contra sus &quot;amos&quot;. Esto es un tema central irresuelto que ahora aflora con fuerza dada la degradación ecológica global que se agrava. Evidentemente, poner a la tecnología al servicio de la humanidad y limitar sus efectos nocivos, constituye una responsabilidad social importante. Pero seguramente para lograr este objetivo hará falta más tecnología, y más científicos que estudien los casos y que imaginen las soluciones a estos problemas. Lo que no se puede hacer , y cualquier intento en este sentido estará destinado al fracaso, es limitar el avance tecnológico. Porque la tecnología está intimamente ligada a la curiosidad humana, al afán de superación, al miedo (a la muerte) y a la valentía para experimentar nuevas cosas, todas estas características fundamentales del ser humano, rasgos que nos definen como especie desde aquel lejano día en que uno de nuestros abuelos tomó un hueso, y tanteándolo pensativamente, imaginó que aquello podía servir para algo más.</description><link>http://enproduccion.blogspot.com/2006/04/la-historia-de-un-garrotazo.html</link><author>noreply@blogger.com (Diego Cofré)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgD8lhZV7z2YDcWJTIWBvUq5CHM5jmQxcCqx4T6ZN-PJNODZLID73nx7MwHMB_bd9scHnR-1KsxKIum_SHMFrk81mNZD22hGzfG-8A9OjoCYGGnEelKZLuwOH0MpfBp4RAmD3Af/s72-c/ape_2.jpg" height="72" width="72"/><thr:total>1</thr:total></item></channel></rss>