tag:blogger.com,1999:blog-23943813317606364322024-02-19T08:08:43.504-08:00Rodrigo Barros Pascual - C# - VFP - PATRONES - ASP.NET y mucho mucho más..Rodrigo Barros Pascualhttp://www.blogger.com/profile/14562783405904128679noreply@blogger.comBlogger27125tag:blogger.com,1999:blog-2394381331760636432.post-48826964783494679222021-02-10T09:48:00.000-08:002021-02-10T09:48:09.592-08:00Juego de dibujos para imprimir y recortar! (Pictonary)<p> Adjunto el link para bajar el PDF para que lo pueda impimir y recortar.</p><p>A disfrutar!</p><p><br /></p><p><a href="https://mega.nz/file/wIg0VJDb#i7h6xqQdN6yWA7MN7qbLsLF48mE4OZhbow0zzeppoB8" target="_blank">Descargar el PDF</a><br /></p>Rodrigo Barros Pascualhttp://www.blogger.com/profile/14562783405904128679noreply@blogger.com0tag:blogger.com,1999:blog-2394381331760636432.post-43993721070975469772020-03-12T05:00:00.002-07:002020-03-12T05:15:22.935-07:00Tortitas Negras a la Rodrigo!<div style="text-align: center;">
<br /></div>
<span style="font-family: trebuchet ms, sans-serif; font-size: x-small;"><b><br /></b></span>
<span style="font-family: trebuchet ms, sans-serif;">Estás son las tradicionales y deliciosas facturas tortitas negras en una versión mucho más fácil ya que están hechas sin levadura , pero resultan igualmente deliciosas !!!</span><br />
<span style="font-family: trebuchet ms, sans-serif;"><br /></span>
<span style="font-family: trebuchet ms, sans-serif;">Tiempo de preparación: 15 a 30 minutos</span><br />
<span style="font-family: trebuchet ms, sans-serif;">Tiempo de cocción: menos de 15 min.</span><br />
<span style="font-family: trebuchet ms, sans-serif; font-size: x-small;"><b><br /></b></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<span style="font-family: trebuchet ms, sans-serif; font-size: x-small;"><b><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYKmDeGHynI2cMgZ2XXdOxp18lfeZGTfXf1ZYaVs5PhUFmaesRuy99g27kAHXic3OSXOSAXKosWgNLaYV2XmD2MglgD0Kplh5yRpVHKfzzzv8At6FbDW-dUzVGKPj7GB7wh1sTDUfHtec/s1600/tortitas2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="404" data-original-width="584" height="221" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYKmDeGHynI2cMgZ2XXdOxp18lfeZGTfXf1ZYaVs5PhUFmaesRuy99g27kAHXic3OSXOSAXKosWgNLaYV2XmD2MglgD0Kplh5yRpVHKfzzzv8At6FbDW-dUzVGKPj7GB7wh1sTDUfHtec/s320/tortitas2.jpg" width="320" /></a></b></span></div>
<br />
<span style="font-family: trebuchet ms, sans-serif; font-size: x-small;"><b><br /></b></span>
<span style="color: orange; font-family: trebuchet ms, sans-serif; font-size: large;"><b>Ingredientes</b></span><br />
<span style="font-family: trebuchet ms, sans-serif; font-size: x-small;"><b><br /></b></span>
<span style="font-family: trebuchet ms, sans-serif;"><b> 400 de Harina Leudante</b></span><br />
<span style="font-family: trebuchet ms, sans-serif;"><b> 100 de Manteca</b></span><br />
<span style="font-family: trebuchet ms, sans-serif;"><b> 1 de Azúcar</b></span><br />
<span style="font-family: trebuchet ms, sans-serif;"><b> 200 de Leche</b></span><br />
<span style="font-family: trebuchet ms, sans-serif;"><b> 200 de Azúcar Negra</b></span><br />
<span style="font-family: trebuchet ms, sans-serif;"><b> 2 de Harina</b></span><br />
<span style="font-family: trebuchet ms, sans-serif; font-size: x-small;"><b><br /></b></span>
<span style="font-family: trebuchet ms, sans-serif; font-size: x-small;"><b><br /></b></span>
<span style="color: orange; font-family: trebuchet ms, sans-serif; font-size: large;"><b>Preparación</b></span><br />
<span style="font-family: trebuchet ms, sans-serif; font-size: x-small;"><b><br /></b></span>
<span style="font-family: trebuchet ms, sans-serif;">Pisar los 100 gr. de manteca blanda con la cucharada de azúcar, agregar de a poco las 2 tazas de harina alternado con los 200cc. de leche, unir bien, volcar sobre la mesa enharinada y formar un bollo liso y tierno.</span><br />
<span style="font-family: trebuchet ms, sans-serif;">En un bol mezclar los 200 gr. de azúcar negra con 2 cucharadas de harina y reservar.</span><br />
<span style="font-family: trebuchet ms, sans-serif;">Estirar el bollo de masa sobre la mesa enharinada con el palo de amasar dejándola de 1 cm. de grosor y cortar medallones de 5 cm. de diámetro.</span><br />
<span style="font-family: trebuchet ms, sans-serif;">Colocar los medallones separados entre sí, sobre una placa previamente enmantecada y enharinada, espolvorear cada medallón de mas con harina y con un pincelito sacar el excedente hacia los costados, pincelar luego con agua y agregar con la mano el azúcar negra, aplastando apenas para que se adhiera bien.</span><br />
<span style="font-family: trebuchet ms, sans-serif;">Cocinar en horno precalentado medio a 190 grados hasta que están bien crecidas y doraditas en la base, 15 minutos aprox.</span>Rodrigo Barros Pascualhttp://www.blogger.com/profile/14562783405904128679noreply@blogger.com0tag:blogger.com,1999:blog-2394381331760636432.post-30929391954957204422013-03-27T07:51:00.000-07:002013-03-27T07:54:21.931-07:00Acceder al ClientID de un control que está dentro de un UserControl desde Javascript<br />
Hoy quiero comentarles la forma de acceder al ClientID de un control que está dentro de un UserControl en ASP.NET desde Javascript en el cliente. El ClienteID es el ID que genera ASP.NET al crear la página.<br />
<br />
Me surgió la necesidad de acceder a un control que está dentro de un UserControl a través de Javascript o jQuery cuando estaba programando una página un tanto compleja. Estuve buscando una solución y la mayoría hacia una inyección de código Javascript en alguna parte del UserControl de una forma parecida a esta:<br />
<br />
<span class="typ" style="border: 0px; color: #2b91af; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">ClientScriptManager</span><span class="pln" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;"> script </span><span class="pun" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">=</span><span class="pln" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;"> </span><span class="typ" style="border: 0px; color: #2b91af; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">Page</span><span class="pun" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">.</span><span class="typ" style="border: 0px; color: #2b91af; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">ClientScript</span><span class="pun" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">;</span><span class="pln" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;"><br /></span><span class="kwd" style="border: 0px; color: blue; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">if</span><span class="pln" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;"> </span><span class="pun" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">(!</span><span class="pln" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">script</span><span class="pun" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">.</span><span class="typ" style="border: 0px; color: #2b91af; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">IsClientScriptBlockRegistered</span><span class="pun" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">(</span><span class="kwd" style="border: 0px; color: blue; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">this</span><span class="pun" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">.</span><span class="typ" style="border: 0px; color: #2b91af; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">GetType</span><span class="pun" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">(),</span><span class="pln" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;"> </span><span class="str" style="border: 0px; color: #a31515; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">"RegisterVariables"</span><span class="pun" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">))</span><span class="pln" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;"><br /></span><span class="pun" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">{</span><span class="pln" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;"><br /> </span><span class="typ" style="border: 0px; color: #2b91af; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">StringBuilder</span><span class="pln" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;"> scriptBlock </span><span class="pun" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">=</span><span class="pln" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;"> </span><span class="kwd" style="border: 0px; color: blue; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">new</span><span class="pln" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;"> </span><span class="typ" style="border: 0px; color: #2b91af; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">StringBuilder</span><span class="pun" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">();</span><span class="pln" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;"><br /> scriptBlock</span><span class="pun" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">.</span><span class="typ" style="border: 0px; color: #2b91af; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">AppendLine</span><span class="pun" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">(</span><span class="str" style="border: 0px; color: #a31515; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">"<script type=text/javascript>"</span><span class="pun" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">);</span><span class="pln" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;"><br /> scriptBlock</span><span class="pun" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">.</span><span class="typ" style="border: 0px; color: #2b91af; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">AppendFormat</span><span class="pun" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">(</span><span class="str" style="border: 0px; color: #a31515; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">"var someVar = {0}"</span><span class="pun" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">,</span><span class="pln" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;"> </span><span class="typ" style="border: 0px; color: #2b91af; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">TextBox1</span><span class="pun" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">.</span><span class="typ" style="border: 0px; color: #2b91af; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">ClientID</span><span class="pun" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">);</span><span class="pln" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;"><br /> scriptBlock</span><span class="pun" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">.</span><span class="typ" style="border: 0px; color: #2b91af; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">AppendLine</span><span class="pun" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">(</span><span class="str" style="border: 0px; color: #a31515; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">"</script>"</span><span class="pun" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">);</span><span class="pln" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;"><br /><br /><br /> script</span><span class="pun" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">.</span><span class="typ" style="border: 0px; color: #2b91af; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">RegisterClientScriptBlock</span><span class="pun" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">(</span><span class="kwd" style="border: 0px; color: blue; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">this</span><span class="pun" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">.</span><span class="typ" style="border: 0px; color: #2b91af; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">GetType</span><span class="pun" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">(),</span><span class="pln" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;"> </span><span class="str" style="border: 0px; color: #a31515; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">"RegisterVariables"</span><span class="pun" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">,</span><span class="pln" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;"> </span><br />
<span class="pln" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">scriptBlock</span><span class="pun" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">.</span><span class="typ" style="border: 0px; color: #2b91af; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">ToString</span><span class="pun" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">());</span><span class="pln" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;"><br /></span><span class="pun" style="border: 0px; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; white-space: pre;">}</span><br />
<br />
ver: http://forums.asp.net/t/1506954.aspx<br />
<br />
Luego someVar al ser global puede ser accedida en cualquier parte de nuestro script.<br />
<br />
Realmente me pareció una manera poco elegante de solucionar el problema. Cada vez que el UserControl es utilizado ese código es agregado a la página, se use o no se use.<br />
<br />
Mi UserControl, llamado "SeleccionarEmpleados" tenía un listbox llamado "lsEmpleados". Decidí crear una propiedad pública en él de la siguiente forma:<br />
<br />
<br />
<span style="color: blue;">public string </span>lsEmpleados_ClientID<br />
{<br />
<span style="color: blue;">get</span><br />
{<br />
<span style="color: blue;">return </span>lsEmpleados.ClientID;<br />
}<br />
}<br />
<br />
<br />
<br />
Esta propiedad de "SeleccionarEmpleados" devuelve el ClientID del listbox.<br />
<br />
Luego en mi webform puedo acceder de esta forma:<br />
<br />
<br />
<br />
<span style="color: blue;">var</span> lst = document.getElementById(<span style="color: #990000;">'<%=SeleccionarEmpleados.lsEmpleados_ClientID%>'</span>);<br />
<br />
<br />
<br />
<br />
De está forma no hay inyección de código innecesario para otras páginas que no necesiten la funcionalidad y además el código utilizado es mucho más simple y fácil de leer.<br />
<br />
Espero que les haya servido!!<br />
<br />
<br />Rodrigo Barros Pascualhttp://www.blogger.com/profile/14562783405904128679noreply@blogger.com0tag:blogger.com,1999:blog-2394381331760636432.post-37555482391460659912012-01-18T09:02:00.000-08:002012-01-18T09:04:17.561-08:00Acá estamos de vueltaLuego de mucho tiempo vuelvo a escribir en el blog. Estaré posteando nuevas entradas acerca de características avanzadas de .net.Rodrigo Barros Pascualhttp://www.blogger.com/profile/14562783405904128679noreply@blogger.com0tag:blogger.com,1999:blog-2394381331760636432.post-86998352601601777762007-12-20T09:47:00.000-08:002007-12-20T09:50:07.045-08:00Diego Rivera<div>Este es otro de los íconos de la pintura mundial. Aca les dejo dos pinturas excelentes del pintor.</div><br /><div></div><img id="BLOGGER_PHOTO_ID_5146113698028304194" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizc92D5U6M7dFRnofaHCE7aQS4IdsSEyCv0oF8vpgA0z7GLA3zA7_SFcI2WdBPCUX1DuapGyTqLvNGbF3RvSWIipz3m9pCuplgxaXHnAVPI9luXoO5s8h7KfOhOkZ54beV0b4IJxVCnJ0/s400/pint_riverad3.jpg" border="0" /><br /><div></div><br /><div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhz2jdohSYz-bmy3tObvHvLzHKaMaQPSDQn4uHv46zxq2XCWMDDglnatoBnbgO7iE34hcJdSCo07Vd7zWP6NTRtHgsD-JxEQ7QtSXnn205N6m-0ryv3EiuFMjucfDHw8DqTaqt5L6q8TwM/s1600-h/pint_riverad4.jpg"><img id="BLOGGER_PHOTO_ID_5146113350135953202" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhz2jdohSYz-bmy3tObvHvLzHKaMaQPSDQn4uHv46zxq2XCWMDDglnatoBnbgO7iE34hcJdSCo07Vd7zWP6NTRtHgsD-JxEQ7QtSXnn205N6m-0ryv3EiuFMjucfDHw8DqTaqt5L6q8TwM/s400/pint_riverad4.jpg" border="0" /></a><br />Para saber más: <a href="http://tierra.free-people.net/artes/pintura-diego-rivera.php">http://tierra.free-people.net/artes/pintura-diego-rivera.php</a><br /><div></div></div>Rodrigo Barros Pascualhttp://www.blogger.com/profile/14562783405904128679noreply@blogger.com0tag:blogger.com,1999:blog-2394381331760636432.post-44836580678056088462007-12-20T09:15:00.000-08:002007-12-20T09:36:10.130-08:00La clase gameHoy vamos a ver un poco el tema de la clase Game que dejamos abierta en la publicación pasada.<br />Esta clase es la más importante de todas porque se ocupa de orquestar los distintos componentes del juego de manera tal que trabajen en sintonia.<br /><br />Veamos un poco de código...<br /><br />import javax.microedition.lcdui.*;<br />import javax.microedition.media.*;<br />import javax.microedition.media.control.*;<br />import java.io.*;<br />import java.util.*;<br />import javax.microedition.lcdui.game.*;<br /><br />class Game extends Canvas implements Runnable<br />{<br /><br />public Game() <br />{ <br />}<br /><br />static long FPS=14;<br /><br />public void run() <br />{ <br />setState(Estados.Load);<br />setFullScreenMode(true);<br />while (true)<br />{ <br />try <br />{ <br />long FPS_Timer = System.currentTimeMillis();<br />Update(); <br />draw(); <br />repaint(); <br />serviceRepaints(); <br />GameTimer++;<br />while ((System.currentTimeMillis()-FPS_Timer)<1000/FPS) <br />Thread.sleep(1); <br />} <br />catch (InterruptedException e) <br />{ <br />//System.out.println(e.toString()); <br />} <br />catch (Exception e) <br />{ <br />//e.printStackTrace(); <br />//System.out.println(e.toString()); <br />} <br />} <br />} <br /><br />public void hideNotify ()<br />{ }<br /><br />public void showNotify()<br /> { }<br /><br />}<br /><br />Como ya hemos dicho la clase game hereda de Canvas una clase muy importante para los midlets. pueden encontrar mucha info de ella en la red. Lo que no habíamos dicho era que implementa la interfaz Runnable<br />Esta interfaz lo que permite es correr la clase game en un nuevo hilo. Esencial para hacer el game loop.<br /><br />Cuando se implementa esta interfaz se debe agregar un método run a la clase. Este método se ejecutará cuando se dispare el hilo.<br /><br />En este método setearemos el estado incial y que se utilice la pantalla completa de celular.<br />además crearemos un while para crear el game loop.<br /><br />Aquí llamaremos a varios métodos muy importantes para nuestro juego (update, draw, etc que aún no están implementados y sirven para actualizar estados y dibujar la animación) y calcularemos los cuadros por segundo. Repaint y serviceRepaints son métodos de canvas que sirven para pintar en la pantalla.<br /><br />Bueno... ya tenemos lo básico. la estructura. Aunque todavia no hace ni pinta nada ya hemos comenzado...Rodrigo Barros Pascualhttp://www.blogger.com/profile/14562783405904128679noreply@blogger.com0tag:blogger.com,1999:blog-2394381331760636432.post-4452436023003628602007-12-19T07:29:00.000-08:002007-12-19T09:26:44.962-08:00Video juegos para móviles!!Hace un tiempo que he incursionado en el área de los video juegos para móviles.<br />Estuve desarrollando un juego de aventura muy simple al mejor estilo Super Mario Bros.<br /><br />Como saben (o no) los móviles usan j2me. Una versión reducida de java. hay mucha info al repsecto en la red.<br /><br />Hoy voy a empezar dandoles la estructura básica de un midlet de un juego:<br />(si no entienden a priori no importa ya lo vamos a ir explicando...)<br /><br /><br />import javax.microedition.midlet.*;<br />import javax.microedition.lcdui.*;<br /><br />public class gfx extends MIDlet<br />{ <br />private Display display; <br />static Game game; <br />static gfx _instance; <br /><br />public gfx() <br />{ <br />display=Display.getDisplay(this); <br />_instance=this; <br />game=new Game(); <br />new Thread(game).start(); <br />} <br /><br />public void startApp() throws MIDletStateChangeException <br />{ <br />display.setCurrent(game); <br />} <br /><br />public void pauseApp()<br />{} <br />public void destroyApp(boolean unconditional)<br />{}<br /><br />}<br /><br />Como verán lo primero que hago es heredar mi clase de midlet... muy importante. Sino no es un midlet.<br />Creo un display para mostrar el juego en pantalla, un Game que hereda de Canvas y que lo vamos a ver más a delante.<br />En el contructor creo las instancias de los distintos objetos y lanzó un hilo que ejecuta Game.<br />En el método startApp() le digo a display que canvas dibujar y como Game hereda de canvas le paso esa instancia.<br /><br />Es mul sencillo. Ahora el tema de como implementar la clase Game es bastante más complejo. lo iremos viendo en varias entragas más.Rodrigo Barros Pascualhttp://www.blogger.com/profile/14562783405904128679noreply@blogger.com0tag:blogger.com,1999:blog-2394381331760636432.post-20339123413083804572007-12-19T07:26:00.000-08:002007-12-19T07:27:59.378-08:00Estoy de vueltaHola!<br /><br />Hace un tiempo que no he tenido tiempo de crear nuevas entradas. En adelante trateré de hacerlo más seguido. :)Rodrigo Barros Pascualhttp://www.blogger.com/profile/14562783405904128679noreply@blogger.com0tag:blogger.com,1999:blog-2394381331760636432.post-68456260447791486282007-07-13T10:12:00.000-07:002007-07-13T10:17:44.880-07:00FTP con C#La siguiente es una clase que hice para subir, bajar, eliminar y renombrar archivos y carpetas en un servidor FTP con c#.<br /><br /><br /><br /><pre><br /> <span style="color:#5c5c5c;">/// <summary></span><br /> <span style="color:#5c5c5c;">/// Clase para hacer uso de un servidor FTP</span><br /> <span style="color:#5c5c5c;">/// </summary></span><br /> <span style="color:#5c5c5c;">/// <date>2007-07-11</date></span><br /> <span style="color:#5c5c5c;">/// <author>Rodrigo Barros Pascual</author></span><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">class</span> ManejadorFTP<br /> {<br /> #<span style="color:#0000ff;">region</span> <<Propiedades>><br /><br /> <span style="color:#0000ff;">private</span> <span style="color:#0000ff;">String</span> _usuario;<br /><br /> <span style="color:#5c5c5c;">/// <summary></span><br /> <span style="color:#5c5c5c;">/// Usuario FTP</span><br /> <span style="color:#5c5c5c;">/// </summary></span><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">String</span> Usuario<br /> {<br /> <span style="color:#0000ff;">get</span> { <span style="color:#0000ff;">return</span> _usuario; }<br /> <span style="color:#0000ff;">set</span> { _usuario = <span style="color:#0000ff;">value</span>; }<br /> }<br /><br /> <span style="color:#0000ff;">private</span> <span style="color:#0000ff;">String</span> _contraseña;<br /> <span style="color:#5c5c5c;">/// <summary></span><br /> <span style="color:#5c5c5c;">/// Contraseña de Usuario FTP</span><br /> <span style="color:#5c5c5c;">/// </summary></span><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">String</span> Contraseña<br /> {<br /> <span style="color:#0000ff;">get</span> { <span style="color:#0000ff;">return</span> _contraseña; }<br /> <span style="color:#0000ff;">set</span> { _contraseña = <span style="color:#0000ff;">value</span>; }<br /> }<br /><br /> <span style="color:#0000ff;">private</span> <span style="color:#0000ff;">String</span> _servidor;<br /><br /> <span style="color:#5c5c5c;">/// <summary></span><br /> <span style="color:#5c5c5c;">/// URL servidor FTP</span><br /> <span style="color:#5c5c5c;">/// </summary></span><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">String</span> Servidor<br /> {<br /> <span style="color:#0000ff;">get</span> { <span style="color:#0000ff;">return</span> _servidor; }<br /> <span style="color:#0000ff;">set</span> { _servidor = <span style="color:#0000ff;">value</span>; }<br /> }<br /><br /> <br /><br /> #<span style="color:#0000ff;">endregion</span><br /><br /> <span style="color:#5c5c5c;">/// <summary></span><br /> <span style="color:#5c5c5c;">/// Sube Documentos al servidor FTP</span><br /> <span style="color:#5c5c5c;">/// </summary></span><br /><span style="color:#666666;"> /// <param name=pPathDocumento">Path del Documento</param>"<br /> /// <param name=pNombreDocumento">Nombre del Documento</param>"<br /> /// <param name=pPathServidor">Path en el servidor donde se guardará el documento</param>"</span><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> SubirDocumento(<span style="color:#0000ff;">string</span> pPathDocumento, <span style="color:#0000ff;">string</span> pNombreDocumento, <span style="color:#0000ff;">string</span> pPathServidor)<br /> {<br /> <span style="color:#0000ff;">try</span><br /> {<br /> WebClient request = <span style="color:#0000ff;">new</span> WebClient();<br /> request.Credentials = <span style="color:#0000ff;">new</span> NetworkCredential(Usuario, Contraseña);<br /> request.UploadFile(Servidor + pPathServidor + pNombreDocumento, pPathDocumento + <span style="color:#b22222;">"\\"</span> + pNombreDocumento);<br /> }<br /> <span style="color:#0000ff;">catch</span> (Exception ex)<br /> {<br /> <span style="color:#0000ff;">throw</span> <span style="color:#0000ff;">new</span> Exception(<span style="color:#b22222;">"Error al intentar subir el documento al servidor."</span>, ex);<br /> }<br /> }<br /><br /> <span style="color:#5c5c5c;">/// <summary></span><br /> <span style="color:#5c5c5c;">/// Sube archivos al servidor FTP</span><br /> <span style="color:#5c5c5c;">/// </summary></span><br /><span style="color:#666666;"> /// <param name=pPathDocumento">Path del Documento</param>"<br /> /// <param name=pNombreDocumento">Nombre del Documento</param>"</span><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> SubirDocumento(<span style="color:#0000ff;">string</span> pPathDocumento, <span style="color:#0000ff;">string</span> pNombreDocumento)<br /> {<br /> SubirDocumento(pPathDocumento, pNombreDocumento, <span style="color:#0000ff;">String</span>.Empty);<br /> }<br /><br /> <span style="color:#5c5c5c;">/// <summary></span><br /> <span style="color:#5c5c5c;">/// Baja Documentos del servidor FTP</span><br /> <span style="color:#5c5c5c;">/// </summary></span><br /><span style="color:#666666;"> /// <param name=pPathServidor">Ruta del Documento en el servidor</param>"<br /> /// <param name=pNombreDocumento">Nombre y extensión del Documento</param>"<br /> /// <param name=pPathFisico">Ruta del documento en el sistema de archivos</param>"<br /> /// <param name=pNombreFisico">Nombre y extensión que se le asignará al documento en el sistema de archivos</param>"</span><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> BajarDocumento(<span style="color:#0000ff;">string</span> pPathServidor, <span style="color:#0000ff;">string</span> pNombreDocumento, <span style="color:#0000ff;">string</span> pPathFisico, <span style="color:#0000ff;">string</span> pNombreFisico)<br /> {<br /> <span style="color:#0000ff;">try</span><br /> {<br /> WebClient request = <span style="color:#0000ff;">new</span> WebClient();<br /> request.Credentials = <span style="color:#0000ff;">new</span> NetworkCredential(Usuario, Contraseña);<br /> request.DownloadFile(Servidor + pPathServidor + pNombreDocumento, pPathFisico + <span style="color:#b22222;">"\\"</span> + pNombreFisico);<br /> }<br /> <span style="color:#0000ff;">catch</span> (Exception ex)<br /> {<br /> <span style="color:#0000ff;">throw</span> <span style="color:#0000ff;">new</span> Exception(<span style="color:#b22222;">"Error al intentar bajar el documento del servidor."</span>, ex);<br /> }<br /> }<br /><br /> <span style="color:#5c5c5c;">/// <summary></span><br /> <span style="color:#5c5c5c;">/// Baja Documentos del servidor FTP</span><br /> <span style="color:#5c5c5c;">/// </summary></span><br /><span style="color:#666666;"> /// <param name=pNombreDocumento">Nombre y extensión del Documento situado en el directorio raíz</param>"<br /> /// <param name=pPathFisico">Ruta del documento en el sistema de archivos</param>"<br /> /// <param name=pNombreFisico">Nombre y extensión que se le asignará al documento en el sistema de archivos</param>"</span><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> BajarDocumento(<span style="color:#0000ff;">string</span> pNombreDocumento, <span style="color:#0000ff;">string</span> pPathFisico, <span style="color:#0000ff;">string</span> pNombreFisico)<br /> {<br /> BajarDocumento(<span style="color:#0000ff;">String</span>.Empty, pNombreDocumento, pPathFisico, pNombreFisico);<br /> }<br /><br /> <span style="color:#5c5c5c;">/// <summary></span><br /> <span style="color:#5c5c5c;">/// Crea directorios en el servidor FTP</span><br /> <span style="color:#5c5c5c;">/// </summary></span><br /><span style="color:#666666;"> /// <param name=pPathDirectorio">Path del directorio</param>"<br /> /// <param name=pNombreDirectorio">Nombre del directorio</param>"</span><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">String</span> CrearDirectorio(<span style="color:#0000ff;">string</span> pPathDirectorio, <span style="color:#0000ff;">string</span> pNombreDirectorio)<br /> {<br /> <span style="color:#0000ff;">try</span><br /> {<br /> FtpWebRequest ftp = (FtpWebRequest)FtpWebRequest.Create(Servidor + pPathDirectorio + <span style="color:#b22222;">"/"</span> + pNombreDirectorio);<br /> ftp.Credentials = <span style="color:#0000ff;">new</span> NetworkCredential(Usuario, Contraseña);<br /> ftp.KeepAlive = <span style="color:#0000ff;">false</span>;<br /> ftp.Method = WebRequestMethods.Ftp.MakeDirectory;<br /> ftp.Proxy = <span style="color:#0000ff;">null</span>;<br /> FtpWebResponse response = (FtpWebResponse)ftp.GetResponse();<br /> <span style="color:#0000ff;">return</span> response.StatusDescription;<br /> }<br /> <span style="color:#0000ff;">catch</span> (Exception ex)<br /> {<br /> <span style="color:#0000ff;">throw</span> <span style="color:#0000ff;">new</span> Exception(<span style="color:#b22222;">"Error al intentar crear el directorio en el servidor."</span>, ex);<br /> }<br /> }<br /><br /> <span style="color:#5c5c5c;">/// <summary></span><br /> <span style="color:#5c5c5c;">/// Crea directorios en el servidor FTP</span><br /> <span style="color:#5c5c5c;">/// </summary></span><br /><span style="color:#666666;"> /// <param name=pNombreDirectorio">Nombre del directorio que se agregará al directorio raíz</param>"</span><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">String</span> CrearDirectorio(<span style="color:#0000ff;">string</span> pNombreDirectorio)<br /> {<br /> <span style="color:#0000ff;">return</span> CrearDirectorio(<span style="color:#0000ff;">String</span>.Empty, pNombreDirectorio);<br /> }<br /><br /> <span style="color:#5c5c5c;">/// <summary></span><br /> <span style="color:#5c5c5c;">/// Elimina directorios en el servidor FTP</span><br /> <span style="color:#5c5c5c;">/// </summary></span><br /><span style="color:#666666;"> /// <param name=pPathDirectorio">Path del directorio</param>"<br /> /// <param name=pNombreDirectorio">Nombre del directorio</param>"</span><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">String</span> EliminarDirectorio(<span style="color:#0000ff;">string</span> pPathDirectorio, <span style="color:#0000ff;">string</span> pNombreDirectorio)<br /> {<br /> <span style="color:#0000ff;">try</span><br /> {<br /> FtpWebRequest ftp = (FtpWebRequest)FtpWebRequest.Create(Servidor + pPathDirectorio + <span style="color:#b22222;">"/"</span> + pNombreDirectorio);<br /> ftp.Credentials = <span style="color:#0000ff;">new</span> NetworkCredential(Usuario, Contraseña);<br /> ftp.KeepAlive = <span style="color:#0000ff;">false</span>;<br /> ftp.Method = WebRequestMethods.Ftp.RemoveDirectory;<br /> ftp.Proxy = <span style="color:#0000ff;">null</span>;<br /> FtpWebResponse response = (FtpWebResponse)ftp.GetResponse();<br /> <span style="color:#0000ff;">return</span> response.StatusDescription;<br /> }<br /> <span style="color:#0000ff;">catch</span> (Exception ex)<br /> {<br /> <span style="color:#0000ff;">throw</span> <span style="color:#0000ff;">new</span> Exception(<span style="color:#b22222;">"Error al intentar eliminar el directorio del servidor."</span>, ex);<br /> }<br /> }<br /><br /> <span style="color:#5c5c5c;">/// <summary></span><br /> <span style="color:#5c5c5c;">/// Elimina directorios en el servidor FTP</span><br /> <span style="color:#5c5c5c;">/// </summary></span><br /><span style="color:#666666;"> /// <param name=pNombreDirectorio">Nombre del directorio que se eliminará del directorio raíz</param>"</span><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">String</span> EliminarDirectorio(<span style="color:#0000ff;">string</span> pNombreDirectorio)<br /> {<br /> <span style="color:#0000ff;">return</span> EliminarDirectorio(<span style="color:#0000ff;">String</span>.Empty, pNombreDirectorio);<br /> }<br /><br /> <span style="color:#5c5c5c;">/// <summary></span><br /> <span style="color:#5c5c5c;">/// Renombra directorios en el servidor FTP</span><br /> <span style="color:#5c5c5c;">/// </summary></span><br /><span style="color:#666666;"> /// <param name=pPathDirectorio">Path del directorio</param>"<br /> /// <param name=pNombreDirectorio">Nombre del directorio</param>"<br /> /// <param name=pNuevoNombreDirectorio">Nombre con el que se renombrará</param>"</span><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">String</span> RenombrarDirectorio(<span style="color:#0000ff;">string</span> pPathDirectorio, <span style="color:#0000ff;">string</span> pNombreDirectorio, <span style="color:#0000ff;">string</span> pNuevoNombreDirectorio)<br /> {<br /> <span style="color:#0000ff;">return</span> Renombrar(pPathDirectorio, pNombreDirectorio, pNuevoNombreDirectorio);<br /> }<br /><br /> <span style="color:#5c5c5c;">/// <summary></span><br /> <span style="color:#5c5c5c;">/// Renombra directorios en el servidor FTP</span><br /> <span style="color:#5c5c5c;">/// </summary></span><br /><span style="color:#666666;"> /// <param name=pNombreDirectorio">Nombre del directorio</param>"<br /> /// <param name=pNuevoNombreDirectorio">Nombre con el que se renombrará</param>"</span><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">String</span> RenombrarDirectorio(<span style="color:#0000ff;">string</span> pNombreDirectorio, <span style="color:#0000ff;">string</span> pNuevoNombreDirectorio)<br /> {<br /> <span style="color:#0000ff;">return</span> Renombrar(<span style="color:#0000ff;">String</span>.Empty, pNombreDirectorio, pNuevoNombreDirectorio);<br /> }<br /><br /> <span style="color:#5c5c5c;">/// <summary></span><br /> <span style="color:#5c5c5c;">/// Renombra Documentos en el servidor FTP</span><br /> <span style="color:#5c5c5c;">/// </summary></span><br /><span style="color:#666666;"> /// <param name=pPathDocumento">Path del Documento</param>"<br /> /// <param name=pNombreDocumento">Nombre del Documento</param>"<br /> /// <param name=pNuevoNombreDocumento">Nombre con el que se renombrará</param>"</span><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">String</span> RenombrarDocumento(<span style="color:#0000ff;">string</span> pPathDocumento, <span style="color:#0000ff;">string</span> pNombreDocumento, <span style="color:#0000ff;">string</span> pNuevoNombreDocumento)<br /> {<br /> <span style="color:#0000ff;">return</span> Renombrar(pPathDocumento, pNombreDocumento, pNuevoNombreDocumento);<br /> }<br /><br /> <span style="color:#5c5c5c;">/// <summary></span><br /> <span style="color:#5c5c5c;">/// Renombra Documentos en el servidor FTP</span><br /> <span style="color:#5c5c5c;">/// </summary></span><br /><span style="color:#666666;"> /// <param name=pNombreDocumento">Nombre del Documento</param>"<br /> /// <param name=pNuevoNombreDocumento">Nombre con el que se renombrará</param>"</span><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">String</span> RenombrarDocumento(<span style="color:#0000ff;">string</span> pNombreDocumento, <span style="color:#0000ff;">string</span> pNuevoNombreDocumento)<br /> {<br /> <span style="color:#0000ff;">return</span> Renombrar(<span style="color:#0000ff;">String</span>.Empty, pNombreDocumento, pNuevoNombreDocumento);<br /> }<br /><br /> <span style="color:#5c5c5c;">/// <summary></span><br /> <span style="color:#5c5c5c;">/// Renombra en el servidor FTP</span><br /> <span style="color:#5c5c5c;">/// </summary></span><br /><span style="color:#666666;"> /// <param name=pPath">Path del directorio o documento</param>"<br /> /// <param name=pNombre">Nombre del directorio o documento</param>"<br /> /// <param name=pNuevoNombre">Nombre con el que se renombrará</param>"</span><br /> <span style="color:#0000ff;">private</span> <span style="color:#0000ff;">String</span> Renombrar(<span style="color:#0000ff;">string</span> pPath, <span style="color:#0000ff;">string</span> pNombre, <span style="color:#0000ff;">string</span> pNuevoNombre)<br /> {<br /> <span style="color:#0000ff;">try</span><br /> {<br /> FtpWebRequest ftp = (FtpWebRequest)FtpWebRequest.Create(Servidor + pPath + <span style="color:#b22222;">"/"</span> + pNombre);<br /> ftp.Credentials = <span style="color:#0000ff;">new</span> NetworkCredential(Usuario, Contraseña);<br /> ftp.KeepAlive = <span style="color:#0000ff;">false</span>;<br /> ftp.Method = WebRequestMethods.Ftp.Rename;<br /> ftp.RenameTo = pNuevoNombre;<br /> ftp.Proxy = <span style="color:#0000ff;">null</span>;<br /> FtpWebResponse response = (FtpWebResponse)ftp.GetResponse();<br /> <span style="color:#0000ff;">return</span> response.StatusDescription;<br /> }<br /> <span style="color:#0000ff;">catch</span> (Exception ex)<br /> {<br /> <span style="color:#0000ff;">throw</span> <span style="color:#0000ff;">new</span> Exception(<span style="color:#b22222;">"Error al intentar renombrar en el servidor."</span>, ex);<br /> }<br /> }<br /><br /> <span style="color:#5c5c5c;">/// <summary></span><br /> <span style="color:#5c5c5c;">/// Elimina documentos en el servidor FTP</span><br /> <span style="color:#5c5c5c;">/// </summary></span><br /><span style="color:#666666;"> /// <param name=pPathDirectorio">Path del documento</param>"<br /> /// <param name=pNombreDirectorio">Nombre del documento</param>"</span><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">String</span> EliminarDocumento(<span style="color:#0000ff;">string</span> pPathDocumento, <span style="color:#0000ff;">string</span> pNombreDocumento)<br /> {<br /> <span style="color:#0000ff;">try</span><br /> {<br /> FtpWebRequest ftp = (FtpWebRequest)FtpWebRequest.Create(Servidor + pPathDocumento + <span style="color:#b22222;">"/"</span> + pNombreDocumento);<br /> ftp.Credentials = <span style="color:#0000ff;">new</span> NetworkCredential(Usuario, Contraseña);<br /> ftp.KeepAlive = <span style="color:#0000ff;">false</span>;<br /> ftp.Method = WebRequestMethods.Ftp.DeleteFile;<br /> ftp.Proxy = <span style="color:#0000ff;">null</span>;<br /> FtpWebResponse response = (FtpWebResponse)ftp.GetResponse();<br /> <span style="color:#0000ff;">return</span> response.StatusDescription;<br /> }<br /> <span style="color:#0000ff;">catch</span> (Exception ex)<br /> {<br /> <span style="color:#0000ff;">throw</span> <span style="color:#0000ff;">new</span> Exception(<span style="color:#b22222;">"Error al intentar eliminar el documento del servidor."</span>, ex);<br /> }<br /> }<br /><br /> <span style="color:#5c5c5c;">/// <summary></span><br /> <span style="color:#5c5c5c;">/// Elimina documentos en el servidor FTP</span><br /> <span style="color:#5c5c5c;">/// </summary></span><br /><span style="color:#666666;"> /// <param name=pNombreDirectorio">Nombre del documento</param>"</span><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">String</span> EliminarDocumento(<span style="color:#0000ff;">string</span> pNombreDocumento)<br /> {<br /> <span style="color:#0000ff;">return</span> EliminarDocumento(<span style="color:#0000ff;">String</span>.Empty, pNombreDocumento);<br /> }<br /><br /> <span style="color:#5c5c5c;">/// <summary></span><br /> <span style="color:#5c5c5c;">/// Constructor por defecto.</span><br /> <span style="color:#5c5c5c;">/// </summary></span><br /><span style="color:#666666;"> /// <param name=pUsuario">Usuario FTP</param>"<br /> /// <param name=pContraseña">Contraseña de usuario FTP</param>"<br /> /// <param name=pURLServidor">URL del servidor FTP</param>"</span><br /> <span style="color:#0000ff;">public</span> ManejadorFTP(<span style="color:#0000ff;">String</span> pUsuario, <span style="color:#0000ff;">String</span> pContraseña, <span style="color:#0000ff;">String</span> pURLServidor)<br /> {<br /> Usuario = pUsuario;<br /> Contraseña = pContraseña;<br /> Servidor = pURLServidor;<br /> }<br /><br /> }</pre><pre> </pre><pre>Espero que les sirva.</pre>Rodrigo Barros Pascualhttp://www.blogger.com/profile/14562783405904128679noreply@blogger.com0tag:blogger.com,1999:blog-2394381331760636432.post-19655063736951469432007-07-02T14:10:00.000-07:002007-07-02T14:20:26.505-07:00WrapperDisculpen, pero he estado un poco ocupado y no he podido hacer publicaciones.<br /><br /><br />Acontinuación expongo un wrapper simple que he utilizado para la llamada a un servicio genérico expuesto en un servicio web. El mismo puede recibir cualquier objeto y devolver cualquier objeto. BSService.BSInterfazService es una referencia web. Como ven utilizo la clase Serializacion de la publicación anterior.<br /><br /><pre> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> RESPONSE EjecutarServicio<REQUEST, RESPONSE>(<span style="color:#0000ff;">String</span> pNombreProcesoDeNegocios, REQUEST pEntidad)<br /> {<br /> <span style="color:#0000ff;">try</span><br /> {<br /> BSService.BSInterfazService ws = <span style="color:#0000ff;">new</span> BS.FWK.Wrapper.BSService.BSInterfazService();<br /> <span style="color:#0000ff;">String</span> wXML = ws.EjecutarServicio(pNombreProcesoDeNegocios, Serializacion.Serialize(pEntidad));<br /><br /> RESPONSE dev = (RESPONSE)Serializacion.Deserialize(<span style="color:#0000ff;">typeof</span>(RESPONSE), wXML);<br /><br /> <span style="color:#0000ff;">return</span> dev;<br /> }<br /> <span style="color:#0000ff;">catch</span> (Exception ex)<br /> {<br /> <span style="color:#0000ff;">throw</span> <span style="color:#0000ff;">new</span> Exception(ex.Message, ex);<br /> }<br /> }</pre><pre> </pre><pre>Es un caso sencillo, pero efectivo.</pre>Rodrigo Barros Pascualhttp://www.blogger.com/profile/14562783405904128679noreply@blogger.com0tag:blogger.com,1999:blog-2394381331760636432.post-12633688123221945862007-06-20T13:48:00.000-07:002007-06-20T14:16:07.893-07:00Serialización en C#La clase siguiente tiene todas las funciones básicas para serializar.<br /><br />Pasando un objeto a Serialize te devuelve un string con el mismo serializado.<br />Si usas Deserialize todo lo que tenes que hacer es pasarle el tipo y el string para que te levante el objeto de nuevo.<br /><br /><br /><br /><pre> <br /> <span style="color:#5c5c5c;">/// <summary></span><br /> <span style="color:#5c5c5c;">/// Clase que contiene todas las funciones de serialización básicas.</span><br /> <span style="color:#5c5c5c;">/// </summary></span><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">class</span> Serializacion<br /> {<br /> #<span style="color:#0000ff;">region</span> -- Binary Serialization --<br /><br /> <span style="color:#5c5c5c;">/// <summary></span><br /> <span style="color:#5c5c5c;">/// Serializa un objeto a un archivo binario.</span><br /> <span style="color:#5c5c5c;">/// </summary></span><br /> <span style="color:#666666;">/// <param name="fileName">Ruta del archivo en el cual depositar los bytes</param><br /> /// <param name="objToSerialize">Objeto en memoria a transformar en bytes</param><br /></span> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">void</span> SerializeToBin(<span style="color:#0000ff;">string</span> fileName, <span style="color:#0000ff;">object</span> objToSerialize)<br /> {<br /> <span style="color:#0000ff;">if</span> (objToSerialize == <span style="color:#0000ff;">null</span>)<br /> {<br /> <span style="color:#0000ff;">throw</span> <span style="color:#0000ff;">new</span> Exception(<span style="color:#b22222;">"El objeto a serializar no debe ser nulo."</span>);<br /> }<br /><br /> <span style="color:#008000;">// Creo el archivo de destino y lo devuelvo a un fileStream</span><br /> FileStream fs = File.Create(fileName);<br /><br /> <span style="color:#008000;">// Creo un BinaryFormatter que me sirve como serializador</span><br /> BinaryFormatter serializer = <span style="color:#0000ff;">new</span> BinaryFormatter();<br /><br /> <span style="color:#008000;">// Le digo al serializador que guarde los bytes en un archivo</span><br /> <span style="color:#008000;">// binario, representado por el FileStream</span><br /> serializer.Serialize(fs, objToSerialize);<br /><br /> <span style="color:#008000;">// Cierro el FileStream</span><br /> fs.Close();<br /> }</pre><pre><br /> /// <summary><br /> /// Deserializa un objeto a partir del contenido de un archivo binario<br /> /// </summary><br /> /// <param name="fileName">Archivo desde donde toma los bytes que se<br /> /// encuentran serializados</param><br /> /// <returns>objeto deserializado</returns><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">object</span> DeserializeFromBin(<span style="color:#0000ff;">string</span> fileName)<br /> {<br /> <span style="color:#0000ff;">if</span> (!File.Exists(fileName))<br /> {<br /> <span style="color:#0000ff;">throw</span> <span style="color:#0000ff;">new</span> Exception(<span style="color:#b22222;">"El archivo de origen para deserializar "</span> +<br /> <span style="color:#b22222;">"no existe. No se encuentra la ruta '"</span> + fileName + <span style="color:#b22222;">"'"</span>);<br /> }<br /><br /> <span style="color:#008000;">// Abro el archivo de origen y lo devuelvo a un fileStream</span><br /> FileStream fs = File.OpenRead(fileName);<br /><br /> <span style="color:#008000;">// Creo un BinaryFormatter que me sirve como deserializador</span><br /> BinaryFormatter deserializer = <span style="color:#0000ff;">new</span> BinaryFormatter();<br /><br /> <span style="color:#008000;">// Le digo al deserializador que me devuelva el objeto a partir</span><br /> <span style="color:#008000;">// del FileStream</span><br /> <span style="color:#0000ff;">object</span> objDeserialized = deserializer.Deserialize(fs);<br /><br /> <span style="color:#008000;">// Cierro el FileStream</span><br /> fs.Close();<br /><br /> <span style="color:#008000;">// Devuelvo el objeto deserializado</span><br /> <span style="color:#0000ff;">return</span> objDeserialized;<br /> }<br /><br /> #<span style="color:#0000ff;">endregion</span><br /><br /> #<span style="color:#0000ff;">region</span> -- Xml Serialization <span style="color:#0000ff;">using</span> DataSet --<br /><br /> <span style="color:#5c5c5c;">/// <summary></span><br /> <span style="color:#5c5c5c;">/// Serializa a un XML y lo coloca en un DataSet</span><br /> <span style="color:#5c5c5c;">/// </summary></span><br /> <span style="color:#666666;">/// <param name="pObject">Objeto a serializar</param><br /> /// <param name="pDataSet">Dataset donde se coloca el XML</param><br /> </span><span style="color:#3333ff;">public</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">void</span> SerializeToXml(<span style="color:#0000ff;">object</span> pObject, <span style="color:#0000ff;">ref</span> DataSet pDataSet)<br /> {<br /> XmlSerializer wSerializer;<br /> MemoryStream wStream = <span style="color:#0000ff;">new</span> MemoryStream();<br /><br /> <span style="color:#0000ff;">if</span> (pDataSet == <span style="color:#0000ff;">null</span>)<br /> pDataSet = <span style="color:#0000ff;">new</span> DataSet();<br /><br /> wSerializer = <span style="color:#0000ff;">new</span> XmlSerializer(pObject.<span style="color:#0000ff;">GetType</span>());<br /><br /> wSerializer.Serialize(wStream, pObject);<br /><br /> wStream.Position = 0;<br /> pDataSet.ReadXml(wStream);<br /> }<br /><br /> <span style="color:#5c5c5c;">/// <summary></span><br /> <span style="color:#5c5c5c;">/// Serializa un objeto</span><br /> <span style="color:#5c5c5c;">/// </summary></span><br /> <span style="color:#666666;">/// <param name="pObj"></param><br /> /// <param name="pDataSet"></param><br /></span> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">void</span> Serialize(<span style="color:#0000ff;">object</span> pObj, <span style="color:#0000ff;">ref</span> DataSet pDataSet)<br /> {<br /> XmlSerializer serializer;<br /> MemoryStream ms = <span style="color:#0000ff;">new</span> MemoryStream();<br /><br /> <span style="color:#0000ff;">if</span> (pDataSet == <span style="color:#0000ff;">null</span>)<br /> pDataSet = <span style="color:#0000ff;">new</span> DataSet();<br /><br /> serializer = <span style="color:#0000ff;">new</span> XmlSerializer(pObj.<span style="color:#0000ff;">GetType</span>());<br /> serializer.Serialize(ms, pObj);<br /><br /> ms.Position = 0;<br /> pDataSet.ReadXml(ms);<br /> }<br /> <span style="color:#5c5c5c;">/// <summary></span><br /> <span style="color:#5c5c5c;">/// Deserializa un objeto a partir de un DataSet</span><br /> <span style="color:#5c5c5c;">/// </summary></span><br /> <span style="color:#666666;">/// <param name="pObjType"></param><br /> /// <param name="pDataSet"></param><br /> /// <param name="pTableName"></param><br /> /// <returns></returns><br /></span> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">object</span> Deserialize(Type pObjType, DataSet pDataSet, <span style="color:#0000ff;">string</span> pTableName)<br /> {<br /> XmlDocument wDom = <span style="color:#0000ff;">new</span> XmlDocument();<br /> wDom.LoadXml(pDataSet.GetXml());<br /> <span style="color:#0000ff;">return</span> Deserialize(pObjType, wDom.GetElementsByTagName(pTableName).Item(0).OuterXml);<br /> }<br /><br /> #<span style="color:#0000ff;">endregion</span><br /><br /> #<span style="color:#0000ff;">region</span> -- Xml Serialization <span style="color:#0000ff;">using</span> Xml --<br /><br /> <span style="color:#5c5c5c;">/// <summary></span><br /> <span style="color:#5c5c5c;">/// Deserializa un objeto.</span><br /> <span style="color:#5c5c5c;">/// </summary></span><br /> <span style="color:#666666;">/// <param name="pObjType"></param><br /> /// <param name="pXmlData"></param><br /> /// <returns></returns><br /></span> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">object</span> Deserialize(Type pObjType, <span style="color:#0000ff;">string</span> pXmlData)<br /> {<br /> XmlSerializer wSerializer;<br /> UTF8Encoding wEncoder = <span style="color:#0000ff;">new</span> UTF8Encoding();<br /> MemoryStream wStream = <span style="color:#0000ff;">new</span> MemoryStream(wEncoder.GetBytes(pXmlData));<br /><br /> wSerializer = <span style="color:#0000ff;">new</span> XmlSerializer(pObjType);<br /> <span style="color:#0000ff;">return</span> wSerializer.Deserialize(wStream);<br /> }<br /><br /> <span style="color:#5c5c5c;">/// <summary></span><br /> <span style="color:#5c5c5c;">/// Deserializa un objeto.</span><br /> <span style="color:#5c5c5c;">/// </summary></span><br /> <span style="color:#666666;">/// <param name="pObjType"></param><br /> /// <param name="pXmlData"></param><br /> /// <param name="pXPath"></param><br /> /// <returns></returns><br /></span> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">object</span> Deserialize(Type pObjType, <span style="color:#0000ff;">string</span> pXmlData, <span style="color:#0000ff;">string</span> pXPath)<br /> {<br /> XmlDocument wDom = <span style="color:#0000ff;">new</span> XmlDocument();<br /> wDom.LoadXml(pXmlData);<br /> <span style="color:#0000ff;">return</span> Deserialize(pObjType, wDom.DocumentElement.SelectSingleNode(pXPath).OuterXml);<br /> }<br /><br /> <span style="color:#5c5c5c;">/// <summary></span><br /> <span style="color:#5c5c5c;">/// Deserializa un objeto</span><br /> <span style="color:#666666;">/// </summary><br /> /// <param name="pTipo"></param><br /> /// <param name="pXml"></param><br /> /// <returns></returns><br /></span> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">object</span> DeserializeFromXml(Type pTipo, <span style="color:#0000ff;">string</span> pXml)<br /> {<br /> XmlSerializer wSerializer;<br /> StringReader wStrSerializado = <span style="color:#0000ff;">new</span> StringReader(pXml);<br /> XmlTextReader wXmlReader = <span style="color:#0000ff;">new</span> XmlTextReader(wStrSerializado);<br /> XmlSerializerNamespaces wNameSpaces = <span style="color:#0000ff;">new</span> XmlSerializerNamespaces();<br /> <span style="color:#0000ff;">object</span> wResObj = <span style="color:#0000ff;">null</span>;<br /><br /> wNameSpaces.<span style="color:#0000ff;">Add</span>("", "");<br /> wSerializer = <span style="color:#0000ff;">new</span> XmlSerializer(pTipo);<br /> wResObj = wSerializer.Deserialize(wXmlReader);<br /><br /> <span style="color:#0000ff;">return</span> wResObj;<br /> }<br /><br /> <span style="color:#5c5c5c;">/// <summary></span><br /> <span style="color:#5c5c5c;">/// Serializa un objeto</span><br /> <span style="color:#666666;">/// </summary><br /> /// <param name="pObj"></param><br /> /// <returns></returns><br /></span> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">string</span> SerializeToXml(<span style="color:#0000ff;">object</span> pObj)<br /> {<br /> XmlSerializer wSerializer;<br /> StringWriter wStwSerializado = <span style="color:#0000ff;">new</span> StringWriter();<br /> XmlTextWriter wXmlWriter = <span style="color:#0000ff;">new</span> XmlTextWriter(wStwSerializado);<br /> XmlSerializerNamespaces wNameSpaces = <span style="color:#0000ff;">new</span> XmlSerializerNamespaces();<br /><br /> wXmlWriter.Formatting = Formatting.Indented;<br /> wNameSpaces.<span style="color:#0000ff;">Add</span>("", "");<br /> wSerializer = <span style="color:#0000ff;">new</span> XmlSerializer(pObj.<span style="color:#0000ff;">GetType</span>());<br /> wSerializer.Serialize(wXmlWriter, pObj, wNameSpaces);<br /><br /> <span style="color:#0000ff;">return</span> wStwSerializado.ToString().Replace(<span style="color:#b22222;">"<?xml version=\"</span>1.0\<span style="color:#b22222;">" encoding=\"</span>utf-16\<span style="color:#b22222;">"?>"</span>, "");<br /> }<br /><br /> <span style="color:#5c5c5c;">/// <summary></span><br /> <span style="color:#5c5c5c;">/// Serializa un objeto.</span><br /> <span style="color:#666666;">/// </summary><br /> /// <param name="pObj">Objeto a serializar</param><br /> /// <returns>Representación en XML del objeto</returns><br /></span> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">string</span> Serialize(<span style="color:#0000ff;">object</span> pObj)<br /> {<br /> <span style="color:#0000ff;">return</span> Serialize(pObj, <span style="color:#0000ff;">false</span>);<br /> }<br /><br /> <span style="color:#5c5c5c;">/// <summary></span><br /> <span style="color:#5c5c5c;">/// Serializa un objeto.</span><br /> <span style="color:#666666;">/// </summary><br /> /// <param name="pObj">Objeto a serializar</param><br /> /// <param name="pRemoveDeclaration">Indica si se debe remover el nodo de declaración</param><br /> /// <returns>Representación en XML del objeto</returns><br /></span> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">string</span> Serialize(<span style="color:#0000ff;">object</span> pObj, <span style="color:#0000ff;">bool</span> pRemoveDeclaration)<br /> {<br /> XmlDocument wDoc = <span style="color:#0000ff;">new</span> XmlDocument();<br /> wDoc.Load(GetStream(pObj));<br /><br /> <span style="color:#0000ff;">if</span> (pRemoveDeclaration && wDoc.ChildNodes.Count > 0 && wDoc.FirstChild.NodeType == XmlNodeType.XmlDeclaration)<br /> {<br /> wDoc.RemoveChild(wDoc.FirstChild);<br /> }<br /><br /> <span style="color:#0000ff;">return</span> wDoc.InnerXml;<br /> }<br /><br /><br /> <span style="color:#5c5c5c;">/// <summary></span><br /> <span style="color:#5c5c5c;">/// Devuelve un stream formado a partir del objeto enviado por parámetro.</span><br /> <span style="color:#666666;">/// </summary><br /> /// <param name="pObj">Objeto para extraer stream</param><br /> /// <returns>MemoryStream</returns><br /></span> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> MemoryStream GetStream(<span style="color:#0000ff;">object</span> pObj)<br /> {<br /> XmlSerializer wSerializer;<br /> MemoryStream wStream = <span style="color:#0000ff;">new</span> MemoryStream();<br /><br /> wSerializer = <span style="color:#0000ff;">new</span> XmlSerializer(pObj.<span style="color:#0000ff;">GetType</span>());<br /> wSerializer.Serialize(wStream, pObj);<br /><br /> wStream.Position = 0;<br /><br /> <span style="color:#0000ff;">return</span> wStream;<br /> }<br /><br /> #<span style="color:#0000ff;">endregion</span><br /> }</pre>Rodrigo Barros Pascualhttp://www.blogger.com/profile/14562783405904128679noreply@blogger.com0tag:blogger.com,1999:blog-2394381331760636432.post-14683328636999575702007-06-19T08:40:00.000-07:002007-06-19T09:06:48.805-07:00El Patrón Abstract Factory<div>Este patrón es útil cuando se necesita instanciar clases complejas y devuelven varios objetos en conjunto.<br /><br />A continuación voy a presentar un ejemplo muy simple de este patrón.<br /><br /><br /><br /><br /></div><pre><span style="color:#0000ff;">using</span> System;<br /><br /><span style="color:#0000ff;">using</span> System.Collections.Generic;<br /><br /><span style="color:#0000ff;">using</span> System.Text;<br /><br /><br /><br /><span style="color:#0000ff;">namespace</span> carpinteriaFactory<br /><br />{<br /><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">enum</span> tipoTabla<br /><br /> {<br /><br /> Cuadrada,<br /><br /> Redonda,<br /><br /> Ovalada<br /><br /> }<br /><br /> <span style="color:#0000ff;">class</span> tabla<br /><br /> {<br /><br /> <span style="color:#0000ff;">private</span> tipoTabla _tipo = tipoTabla.Cuadrada;<br /><br /><br /><br /> <span style="color:#0000ff;">public</span> tipoTabla Tipo<br /><br /> {<br /><br /> <span style="color:#0000ff;">get</span> { <span style="color:#0000ff;">return</span> _tipo; }<br /><br /> <span style="color:#0000ff;">set</span> { _tipo = <span style="color:#0000ff;">value</span>; }<br /><br /> }<br /><br /><br /><br /> <span style="color:#0000ff;">public</span> tabla(tipoTabla tipo)<br /><br /> {<br /><br /> Tipo = tipo;<br /><br /> }<br /><br /> }<br /><br /><br /><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">enum</span> tipoPata<br /><br /> {<br /><br /> Cuadrada,<br /><br /> Redonda<br /><br /> }<br /><br /> <span style="color:#0000ff;">class</span> Pata<br /><br /> {<br /><br /> <span style="color:#0000ff;">private</span> tipoPata _tipo = tipoPata.Redonda;<br /><br /><br /><br /> <span style="color:#0000ff;">public</span> tipoPata Tipo<br /><br /> {<br /><br /> <span style="color:#0000ff;">get</span> { <span style="color:#0000ff;">return</span> _tipo; }<br /><br /> <span style="color:#0000ff;">set</span> { _tipo = <span style="color:#0000ff;">value</span>; }<br /><br /> }<br /><br /><br /><br /> <span style="color:#0000ff;">public</span> Pata(tipoPata tipo)<br /><br /> {<br /><br /> <span style="color:#0000ff;">this</span>.Tipo = tipo;<br /><br /> }<br /><br /> }<br /><br /><br /><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">class</span> Mueble<br /><br /> {<br /><br /><br /><br /> }<br /><br /><br /><br /> <span style="color:#0000ff;">class</span> Mesa : Mueble<br /><br /> {<br /><br /> <span style="color:#0000ff;">private</span> Pata[] _Patas;<br /><br /><br /><br /> <span style="color:#0000ff;">public</span> Pata[] Patas<br /><br /> {<br /><br /> <span style="color:#0000ff;">get</span> { <span style="color:#0000ff;">return</span> _Patas; }<br /><br /> <span style="color:#0000ff;">set</span> { _Patas = <span style="color:#0000ff;">value</span>; }<br /><br /> }<br /><br /><br /><br /> <span style="color:#0000ff;">private</span> tabla _tabla;<br /><br /><br /><br /> <span style="color:#0000ff;">public</span> tabla Tabla<br /><br /> {<br /><br /> <span style="color:#0000ff;">get</span> { <span style="color:#0000ff;">return</span> _tabla; }<br /><br /> <span style="color:#0000ff;">set</span> { _tabla = <span style="color:#0000ff;">value</span>; }<br /><br /> }<br /><br /><br /><br /> <span style="color:#0000ff;">private</span> <span style="color:#0000ff;">String</span> _nombre;<br /><br /><br /><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">String</span> Nombre<br /><br /> {<br /><br /> <span style="color:#0000ff;">get</span> { <span style="color:#0000ff;">return</span> _nombre; }<br /><br /> <span style="color:#0000ff;">set</span> { _nombre = <span style="color:#0000ff;">value</span>; }<br /><br /> }<br /><br /><br /><br /> <span style="color:#0000ff;">public</span> Mesa() { }<br /><br /><br /><br /> <span style="color:#0000ff;">public</span> Mesa(<span style="color:#0000ff;">String</span> nombre, tipoTabla tabla, tipoPata TipoPata, Int32 CantidadPatas)<br /><br /> {<br /><br /> <span style="color:#0000ff;">this</span>.Nombre = nombre;<br /><br /><br /><br /> <span style="color:#0000ff;">this</span>.Tabla = <span style="color:#0000ff;">new</span> tabla(tabla);<br /><br /><br /><br /> Pata[] wPatas = <span style="color:#0000ff;">new</span> Pata[CantidadPatas];<br /><br /><br /><br /> <span style="color:#0000ff;">for</span> (<span style="color:#0000ff;">int</span> i = 0; i < CantidadPatas; i++)<br /><br /> {<br /><br /> wPatas[i] = <span style="color:#0000ff;">new</span> Pata(TipoPata);<br /><br /> }<br /><br /><br /><br /> <span style="color:#0000ff;">this</span>.Patas = wPatas;<br /><br /> }<br /><br /><br /><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">override</span> <span style="color:#0000ff;">string</span> ToString()<br /><br /> {<br /><br /> <span style="color:#0000ff;">String</span> r = Nombre + <span style="color:#b22222;">" => "</span> + Tabla.Tipo.ToString();<br /><br /> Int32 i = 1;<br /><br /> <span style="color:#0000ff;">foreach</span> (Pata p <span style="color:#0000ff;">in</span> Patas)<br /><br /> {<br /><br /> r = r + <span style="color:#b22222;">" Pata "</span> + i.ToString() + <span style="color:#b22222;">": "</span> + p.Tipo.ToString();<br /><br /> i++;<br /><br /> }<br /><br /> <span style="color:#0000ff;">return</span> r;<br /><br /> }<br /><br /><br /><br /> }<br /><br /><br /><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">abstract</span> <span style="color:#0000ff;">class</span> CarpinteriaFactory<br /><br /> {<br /><br /> <span style="color:#0000ff;">abstract</span> <span style="color:#0000ff;">public</span> Mueble crearMueble();<br /><br /> }<br /><br /><br /><br /><br /><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">class</span> MesaAntiguaFactory : CarpinteriaFactory<br /><br /> {<br /><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">override</span> Mueble crearMueble()<br /><br /> {<br /><br /> <span style="color:#0000ff;">return</span> <span style="color:#0000ff;">new</span> Mesa(<span style="color:#b22222;">"Mesa Antigua"</span>, tipoTabla.Cuadrada, tipoPata.Cuadrada, 4);<br /><br /> }<br /><br /> }<br /><br /><br /><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">class</span> MesaExoticaFactory : CarpinteriaFactory<br /><br /> {<br /><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">override</span> Mueble crearMueble()<br /><br /> {<br /><br /> Mesa exotica = <span style="color:#0000ff;">new</span> Mesa(<span style="color:#b22222;">"Mesa Exótica"</span>, tipoTabla.Ovalada, tipoPata.Redonda, 4);<br /><br /> exotica.Patas[1].Tipo = tipoPata.Cuadrada;<br /><br /> exotica.Patas[3].Tipo = tipoPata.Cuadrada;<br /><br /> <span style="color:#0000ff;">return</span> exotica;<br /><br /> }<br /><br /> }<br /><br /><br /><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">class</span> MesaModernaFactory : CarpinteriaFactory<br /><br /> {<br /><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">override</span> Mueble crearMueble()<br /><br /> {<br /><br /> <span style="color:#0000ff;">return</span> <span style="color:#0000ff;">new</span> Mesa(<span style="color:#b22222;">"Mesa Moderna"</span>, tipoTabla.Redonda, tipoPata.Redonda, 3);<br /><br /> }<br /><br /> }<br /><br /><br /><br />}</pre><br /><p></p><br /><p>Como pueden ver existen las clases pata y tabla que tienen propiedades cada una que definen su ámbito.</p><br /><p>Luego existe una clase mueble que por el momento no tiene nada pero que se podría anexar funcionalidad.</p><br /><p>La clase mesa hereda de mueble y se compone de una tabla y un array de patas, además de un nombre. </p><br /><p>Luego existe la clase abstracta carpinteriaFactory que define el método publico crearMueble.</p><br /><p>Por último existen tres implementaciones de carpinteríaFactory: MesaExoticaFactory,MesaAntiguaFactory y MesaModernaFactory.</p><br /><p>Estas clases instancian la clase mesa, crear todos los objetos necesarios y asignan valores a sus propiedades.</p><br /><p>De esta forma se pueden obtener objetos complejos y encapsular su instanciación. Les dejo el esquema del patrón:</p><br /><p></p><img id="BLOGGER_PHOTO_ID_5077807339279226914" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicVEMm2W38EbBBYTvzvykHGFJhAp0FvEeSHqS5bEc-QrWvhVcCZhZDntokxkUqumnGvFmLE0tTfKYv17ikfTaEwaclxHcWiREfAlXUrJ3DIenVUULFgb8kgRBfnjh_nQmvg1pHgUPjKVE/s400/factory.jpg" border="0" /><br /><div><br /></div>Rodrigo Barros Pascualhttp://www.blogger.com/profile/14562783405904128679noreply@blogger.com0tag:blogger.com,1999:blog-2394381331760636432.post-15846025794246229842007-06-11T11:59:00.000-07:002007-06-11T12:03:33.211-07:00MasterPage con ASP.Net 2.0<p>Este es un video que explica de forma muy básica el uso de MasterPage de ASP.NET 2.0. Tal vez sirva como introducción para los principiantes. ¡Espero que les sirva!</p><p><object height="350" width="425"><param name="movie" value="http://www.youtube.com/v/D6TFqMmYo60"><param name="wmode" value="transparent"><embed src="http://www.youtube.com/v/D6TFqMmYo60" type="application/x-shockwave-flash" wmode="transparent" width="425" height="350"></embed></object></p><p></p>Rodrigo Barros Pascualhttp://www.blogger.com/profile/14562783405904128679noreply@blogger.com0tag:blogger.com,1999:blog-2394381331760636432.post-82641807730728202042007-06-11T06:04:00.000-07:002007-06-11T10:49:09.650-07:00Las señoritas de Avignon<img id="BLOGGER_PHOTO_ID_5074792439741159442" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZHMsK24OHr3nKc-_5AtWb9I-Zi3s-_R83PIsHEZJNF4rg8grZ_JkdmGWswqFi7YghyfVpGv74zcQ-b5aFrJFRzLZtyo6yEFyopx4GgO259irN79Q8YINdJpLta0gX7YJgWG8jXekuXdM/s400/picasso_avignon.jpg" border="0" /><br /><br />Las señoritas de Avignon es un cuadro de Pablo Picasso. Es un cuadro que a primera vista genera repudio. En realidad puede llegar a parecer feo. Pero lo que hizo este cuedro tan famoso es como el autor plasma los sentimientos de rechazo y astío por aquellas mujeres de forma inconciente.<br />Este es un cuadro de gran composición que mezcla de forma exiquisita la tradición naturalista y el movimiento abstracto. Demuestra la capacidad pictórica de Picasso y su talento para crear una obra tan revolucionaria para la época.Rodrigo Barros Pascualhttp://www.blogger.com/profile/14562783405904128679noreply@blogger.com0tag:blogger.com,1999:blog-2394381331760636432.post-28989931914562588892007-06-06T09:49:00.000-07:002007-06-11T10:48:55.393-07:00Los Patrones Estrategia y Decorador trabajando en conjuntoA continuación daré un ejemplo de como utilizar estos dos patrones de forma conjunta en C#, aunque se podría aplicar en VFP de forma muy sencilla siguiendo la misma lógica que venimos trabajando en los distintos artículos.<br /><br /><br /><br /><br /><br />Vamos a reutilizar todas las clases que venimos publicando en el artículo de estategia, decorador y puente.<br /><br /><br /><br /><br /><p><img id="BLOGGER_PHOTO_ID_5072998337412339714" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgM2-heZDBt-yh3i-R8kFCIEPPT-Is1-pRnywlJAa99KpHIXliexwRjNE2SpAJpRfKATcRIvt748YvdE4J5KVBug252Czo7ddq4q1GQ341yVbK9LFNiUnVPaCPi_I_eoO0u5-7xIBNYyMs/s400/juntos1.JPG" border="0" /></p><p></p><p>La pantalla anterior es como luce nuestra aplicación. Veamos el código para lograrlo:</p><p><br /></p><br /><br /><br /><pre><span style="color:#0000ff;">using</span> System;<br /><span style="color:#0000ff;">using</span> System.Collections.Generic;<br /><span style="color:#0000ff;">using</span> System.ComponentModel;<br /><span style="color:#0000ff;">using</span> System.Data;<br /><span style="color:#0000ff;">using</span> System.Drawing;<br /><span style="color:#0000ff;">using</span> System.Text;<br /><span style="color:#0000ff;">using</span> System.Windows.Forms;<br /><span style="color:#0000ff;">using</span> estrategia;<br /><br /><br /><span style="color:#0000ff;">namespace</span> WindowsApplication1<br />{<br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">partial</span> <span style="color:#0000ff;">class</span> CodigoDinamico : Form<br /> {<br /> <span style="color:#0000ff;">public</span> CodigoDinamico()<br /> {<br /> InitializeComponent();<br /> }<br /><br /> <span style="color:#0000ff;">private</span> Estrategia _Procesador= <span style="color:#0000ff;">new</span> Estrategia();<br /><br /> <span style="color:#0000ff;">public</span> Estrategia Procesador<br /> {<br /> <span style="color:#0000ff;">get</span> { <span style="color:#0000ff;">return</span> _Procesador; }<br /> <span style="color:#0000ff;">set</span> { _Procesador = <span style="color:#0000ff;">value</span>; }<br /> }<br /><br /> <span style="color:#0000ff;">private</span> <span style="color:#0000ff;">void</span> asignarFuncionalidad()<br /> {<br /> Lis<<span style="color:#0000ff;">String</span>> Items = <span style="color:#0000ff;">new</span> List<<span style="color:#0000ff;">String</span>>();<br /> <span style="color:#0000ff;">if</span> (optApeNom.<span style="color:#0000ff;">Checked</span>) { Items.<span style="color:#0000ff;">Add</span>(<span style="color:#b22222;">"Puente"</span>); }<br /> <span style="color:#0000ff;">if</span> (optNomApe.<span style="color:#0000ff;">Checked</span>) { Items.<span style="color:#0000ff;">Add</span>(<span style="color:#b22222;">"NombreApellido"</span>); }<br /> <span style="color:#0000ff;">if</span> (optEnriquecido.<span style="color:#0000ff;">Checked</span>) { Items.<span style="color:#0000ff;">Add</span>(<span style="color:#b22222;">"Enriquecido"</span>); }<br /> <span style="color:#0000ff;">if</span> (chkNumera.<span style="color:#0000ff;">Checked</span>) { Items.<span style="color:#0000ff;">Add</span>(<span style="color:#b22222;">"AgregarNumeracion"</span>); };<br /> <span style="color:#0000ff;">if</span> (chkNacion.<span style="color:#0000ff;">Checked</span>) { Items.<span style="color:#0000ff;">Add</span>(<span style="color:#b22222;">"AgregarNacionalidad"</span>); };<br /> Procesador = Dinamico.Proceso(Items);<br /> <span style="color:#0000ff;">if</span> (chkNacion.<span style="color:#0000ff;">Checked</span>)<br /> {<br /> AgregarNacionalidad Nacionalidad = (AgregarNacionalidad)Procesador.Contexto.MiClase;<br /> Nacionalidad.Nacionalidad = txtNacion.Text;<br /> }<br /><br /> }<br /><br /> <span style="color:#0000ff;">private</span> <span style="color:#0000ff;">void</span> btn1_Click(<span style="color:#0000ff;">object</span> sender, EventArgs e)<br /> {<br /> asignarFuncionalidad();<br /> txtSalida.Text = <span style="color:#0000ff;">this</span>.Procesador.ProcesarNombres(txtNombre.Text, txtApellido.Text);<br /> }<br /><br /> <span style="color:#0000ff;">private</span> <span style="color:#0000ff;">void</span> chkNacion_CheckedChanged(<span style="color:#0000ff;">object</span> sender, EventArgs e)<br /> {<br /> <span style="color:#0000ff;">if</span> (chkNacion.<span style="color:#0000ff;">Checked</span>)<br /> {<br /> txtNacion.<span style="color:#0000ff;">ReadOnly</span> = <span style="color:#0000ff;">false</span>;<br /> }<br /> <span style="color:#0000ff;">else</span><br /> {<br /> txtNacion.<span style="color:#0000ff;">ReadOnly</span> = <span style="color:#0000ff;">true</span>;<br /> }<br /> }<br /><br /><br /> }<br />}</pre><pre> </pre>Como verán, en el botón btn1 siempre llamamos a asignarFuncionalidad antes de llamar a nuestra función. Esta función crea una lista genérica de String y se la pasa al metódo Estático "Proceso" de la Clase Dinamico. Veamos esta nueva clase:<br /><br /><pre><span style="color:#0000ff;">using</span> System;<br /><span style="color:#0000ff;">using</span> System.Collections.Generic;<br /><span style="color:#0000ff;">using</span> System.Text;<br /><span style="color:#0000ff;">using</span> System.Reflection;<br /><br /><span style="color:#0000ff;">namespace</span> estrategia<br />{<br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">class</span> Dinamico<br /> {<br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> Estrategia Proceso(List<<span style="color:#0000ff;">String</span>> Decoradores)<br /> {<br /> <span style="color:#0000ff;">Assembly</span> Ass = <span style="color:#0000ff;">Assembly</span>.GetExecutingAssembly();<br /> <span style="color:#0000ff;">Object</span> Estra = Ass.CreateInstance(<span style="color:#b22222;">"estrategia."</span> + Decoradores[0].Trim());<br /> Decoradores.<span style="color:#0000ff;">Remove</span>(Decoradores[0]);<br /> <span style="color:#0000ff;">Object</span>[] o = <span style="color:#0000ff;">new</span> <span style="color:#0000ff;">Object</span>[1];<br /> o[0] = Estra;<br /> <span style="color:#0000ff;">foreach</span> (<span style="color:#0000ff;">String</span> deco <span style="color:#0000ff;">in</span> Decoradores)<br /> {<br /> o[0] = Ass.CreateInstance(<span style="color:#b22222;">"estrategia."</span> + deco, <span style="color:#0000ff;">false</span>, BindingFlags.CreateInstance,<span style="color:#0000ff;">null</span>, o, <span style="color:#0000ff;">null</span>, <span style="color:#0000ff;">null</span>);<br /> }<br /> Estrategia st = <span style="color:#0000ff;">new</span> Estrategia(<span style="color:#0000ff;">new</span> contexto((IProcesarNombres)o[0]));<br /> <span style="color:#0000ff;">return</span> st;<br /> }<br /> }<br />}</pre><pre>La función genera la estrategia y los decoradores mediante Reflection.</pre><pre>Con el primer elemento de la lista selecciona la estrategia y con el resto agrega los decoradores. De esta forma se puede crear dinámicamente toda la funcionalidad. </pre><pre>Si se crea una nueva clase solo se debe para el nombre de la misma en la lista genérica y sale funcionando sin tocar casi nada del código.</pre><pre>Este tipo de tecnología tiene muchas aplicaciones y que seguro ustedes ya deben estar pensando.</pre>Rodrigo Barros Pascualhttp://www.blogger.com/profile/14562783405904128679noreply@blogger.com0tag:blogger.com,1999:blog-2394381331760636432.post-23947407537409823972007-06-05T09:26:00.000-07:002007-06-11T10:48:35.524-07:00El Patrón Estrategia en VFPPara implementar el patrón estrategia en Visual Fox Pro vamos a tomar el mismo ejemplo que trabajamos con C#.<br /><br />Debemos crear el contexto, la estrategia abstracta, etc, etc...<br /><br />Veamos un poco de código:<br /><br /><br /><br /><pre><br />*Interfaz<br /><br /><span style="color:#000000;">DEFINE</span> <span style="color:#000000;">CLASS</span> IComponente <span style="color:#000000;">as</span> <span style="color:#000000;">Custom</span><br /><br /> <span style="color:#000000;">FUNCTION</span> procesarNombres()<br /><br /> LPARAMETERS nombre,apellido<br /><br /> endfunc<br /><br />ENDDEFINE<br /><br /><br /><br /><br /><br />*estrategia concreta<br /><br /><span style="color:#000000;">DEFINE</span> <span style="color:#000000;">CLASS</span> puente <span style="color:#000000;">as</span> Icomponente<br /><br /><br /><br /> Caracter= <span style="color:#000000;">", "</span><br /><br /> <br /><br /> PROCEDURE Caracter_ACCESS<br /><br /> <span style="color:#000000;">RETURN</span> <span style="color:#000000;">THIS</span>.Caracter<br /><br /> ENDPROC<br /><br /> <br /><br /> PROCEDURE Caracter_ASSIGN<br /><br /> LPARAMETERS Valor<br /><br /> <span style="color:#000000;">THIS</span>.Caracter=Valor<br /><br /> ENDPROC<br /><br /><br /><br /> <span style="color:#000000;">FUNCTION</span> procesarNombres()<br /><br /> LPARAMETERS nombre,apellido<br /><br /> <span style="color:#000000;">RETURN</span> ALLTRIM(Apellido) + <span style="color:#000000;">this</span>.Caracter + ALLTRIM(nombre)<br /><br /> ENDFUNC<br /><br /> <br /><br />ENDDEFINE<br /><br /><br /><br />*estrategia concreta<br /><br /><span style="color:#000000;">DEFINE</span> <span style="color:#000000;">CLASS</span> NombreApellido <span style="color:#000000;">as</span> Icomponente<br /><br /><br /><br /> Caracter= <span style="color:#000000;">" "</span><br /><br /> <br /><br /> PROCEDURE Caracter_ACCESS<br /><br /> <span style="color:#000000;">RETURN</span> <span style="color:#000000;">THIS</span>.Caracter<br /><br /> ENDPROC<br /><br /> <br /><br /> PROCEDURE Caracter_ASSIGN<br /><br /> LPARAMETERS Valor<br /><br /> <span style="color:#000000;">THIS</span>.Caracter=Valor<br /><br /> ENDPROC<br /><br /><br /><br /> <span style="color:#000000;">FUNCTION</span> procesarNombres()<br /><br /> LPARAMETERS nombre,apellido<br /><br /> <span style="color:#000000;">RETURN</span> ALLTRIM(nombre) + <span style="color:#000000;">this</span>.Caracter + ALLTRIM(Apellido)<br /><br /> ENDFUNC<br /><br /> <br /><br />ENDDEFINE<br /><br /><br /><br />*estrategia concreta<br /><br /><span style="color:#000000;">DEFINE</span> <span style="color:#000000;">CLASS</span> Enriquecido <span style="color:#000000;">as</span> Icomponente<br /><br /><br /><br /> Caracter= <span style="color:#000000;">" - "</span><br /><br /> <br /><br /> PROCEDURE Caracter_ACCESS<br /><br /> <span style="color:#000000;">RETURN</span> <span style="color:#000000;">THIS</span>.Caracter<br /><br /> ENDPROC<br /><br /> <br /><br /> PROCEDURE Caracter_ASSIGN<br /><br /> LPARAMETERS Valor<br /><br /> <span style="color:#000000;">THIS</span>.Caracter=Valor<br /><br /> ENDPROC<br /><br /><br /><br /> <span style="color:#000000;">FUNCTION</span> procesarNombres()<br /><br /> LPARAMETERS nombre,apellido<br /><br /> <span style="color:#000000;">RETURN</span> <span style="color:#000000;">"Apellido: "</span> + ALLTRIM(Apellido) + <span style="color:#000000;">this</span>.Caracter + <span style="color:#000000;">"Nombre: "</span> + ALLTRIM(nombre)<br /><br /> ENDFUNC<br /><br /> <br /><br />ENDDEFINE<br /><br /><br /><br />*clase de contexto<br /><br /><span style="color:#000000;">DEFINE</span> <span style="color:#000000;">CLASS</span> contexto <span style="color:#000000;">as</span> <span style="color:#000000;">Custom</span><br /><br /><br /><br /><br /><br /> MiClase= <span style="color:#000000;">null</span><br /><br /> <br /><br /> PROCEDURE MiClase_ACCESS<br /><br /> <span style="color:#000000;">RETURN</span> <span style="color:#000000;">THIS</span>.MiClase<br /><br /> ENDPROC<br /><br /> <br /><br /> PROCEDURE MiClase_ASSIGN<br /><br /> LPARAMETERS Valor<br /><br /> <span style="color:#000000;">THIS</span>.MiClase=Valor<br /><br /> ENDPROC<br /><br /><br /><br /> PROCEDURE init()<br /><br /> LPARAMETERS Clase<br /><br /> <span style="color:#000000;">This</span>.MiClase=Clase<br /><br /> ENDPROC<br /><br /> <br /><br />ENDDEFINE<br /><br /><br /><br />*estrategia abstracta<br /><br /><span style="color:#000000;">DEFINE</span> <span style="color:#000000;">CLASS</span> Estrategia <span style="color:#000000;">as</span> Icomponente<br /><br /><br /><br /> contexto= <span style="color:#000000;">" "</span><br /><br /> <br /><br /> PROCEDURE contexto_ACCESS<br /><br /> <span style="color:#000000;">RETURN</span> <span style="color:#000000;">THIS</span>.contexto<br /><br /> ENDPROC<br /><br /> <br /><br /> PROCEDURE contexto_ASSIGN<br /><br /> LPARAMETERS Valor<br /><br /> <span style="color:#000000;">THIS</span>.contexto=Valor<br /><br /> ENDPROC<br /><br /><br /><br /> PROCEDURE init()<br /><br /> LPARAMETERS Clase<br /><br /> <span style="color:#000000;">This</span>.contexto=Clase<br /><br /> ENDPROC<br /><br /><br /><br /> <span style="color:#000000;">FUNCTION</span> procesarNombres()<br /><br /> LPARAMETERS nombre,apellido<br /><br /> <span style="color:#000000;">RETURN</span> <span style="color:#000000;">this</span>.contexto.MiClase.procesarNombres(nombre,apellido)<br /><br /> ENDFUNC<br /><br /> <br /><br />ENDDEFINE</pre><br /><br /><p></p><br /><br /><p></p><br /><br />Se agregaron dos estrategias además de Puente: NombreApellido y Enriquecido. Las misma realizan distintas acciones para tener de ejemplo.<br /><br /><br /><br /><br /><br />Veamos ahora como utilizar esto en un formulario:<br /><br /><br /><br /><p><img id="BLOGGER_PHOTO_ID_5072620083937548274" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgG_bwW03hgnRvdzfQNi6OQthVX9xG1LcHpHLrPm7ORVfiwmFD5xmecAubxvpCfx6ZP79K9ReiY7alTmRpb6oOZzDHq2bYE-cnO1RjCLFFXFuQ1V2nUVs_1KSAzUE26omqPYv_R8oeKQo8/s400/estrate2.JPG" border="0" /></p><p></p><p>Al presionar cada botón estamos utilizando una estrategia distinta. </p><p>El código del primer botón:</p><p><br />Estrategia = NEWOBJECT("Estrategia",'','',NEWOBJECT("contexto",'','',NEWOBJECT("NombreApellido")))<br />ThisForm.txt1.Value=Estrategia.procesarnombres(thisform.txtNombre.Value,thisform.txtApellido.Value)<br />RELEASE Estrategia</p><p></p><p>El código del segundo botón:</p><p><br />Estrategia = NEWOBJECT("Estrategia",'','',NEWOBJECT("contexto",'','',NEWOBJECT("Puente")))<br />ThisForm.txt2.Value=Estrategia.procesarnombres(thisform.txtNombre.Value,thisform.txtApellido.Value)<br />RELEASE Estrategia<br /></p>El código del tercer botón:<br /><br /><br />Estrategia = NEWOBJECT("Estrategia",'','',NEWOBJECT("contexto",'','',NEWOBJECT("Enriquecido")))<br />ThisForm.txt3.Value=Estrategia.procesarnombres(thisform.txtNombre.Value,thisform.txtApellido.Value)<br />RELEASE Estrategia<br /><br />En el init del formulario:<br /><br /><br />SET PROCEDURE TO "estrategia.prg"<br /><br />donde "estrategia.prg" es el archivo donde están escritas las clases.<br /><br />Cambiar de una estrategia a otra es muy simple. En entornos donde la tasa de cambios es muy alta este tipo de metodología es excelente.<br /><br />En las siguientes publicaciones veremos cómo utilizar varios patrones a la vez.-Rodrigo Barros Pascualhttp://www.blogger.com/profile/14562783405904128679noreply@blogger.com0tag:blogger.com,1999:blog-2394381331760636432.post-3328993178432395512007-06-05T08:15:00.000-07:002007-06-11T10:48:18.087-07:00El Patrón Estrategia en C#Vamos a ver ahora como implementar el patrón estrategia en c#.<br /><br />Vamos a reutilizar las clases que venimos trabajando con el puente y el decorador. Pues esa es la idea de los patrones ¿no?. Vamos a reutilizar, entonces, la interfaz "p<procesarnombres>rocesarNombres" y la Clase "Puente" dentro del namespace estrategia.<br /><br />Vamos a crear la clase de contexto:<br /><br /><br /><br /><pre><span style="color:#0000ff;">using</span> System;<br /><br /><span style="color:#0000ff;">using</span> System.Collections.Generic;<br /><br /><span style="color:#0000ff;">using</span> System.Text;<br /><br /><br /><br /><span style="color:#0000ff;">namespace</span> estrategia<br /><br />{<br /><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">class</span> contexto<br /><br /> {<br /><br /> IProcesarNombres _MiClase;<br /><br /><br /><br /> <span style="color:#0000ff;">public</span> IProcesarNombres MiClase<br /><br /> {<br /><br /> <span style="color:#0000ff;">get</span> { <span style="color:#0000ff;">return</span> _MiClase; }<br /><br /> <span style="color:#0000ff;">set</span> { _MiClase = <span style="color:#0000ff;">value</span>; }<br /><br /> }<br /><br /><br /><br /> <span style="color:#0000ff;">public</span> contexto(IProcesarNombres Clase)<br /><br /> {<br /><br /> MiClase = Clase;<br /><br /> }<br /><br /> }<br /><br />}</pre><pre> </pre><pre>Ahora crearemos la estrategia abstracta que implementa IProcesarNombres.</pre><pre> </pre><br /><br /><br /><pre><span style="color:#0000ff;">using</span> System;<br /><br /><span style="color:#0000ff;">using</span> System.Collections.Generic;<br /><br /><span style="color:#0000ff;">using</span> System.Text;<br /><br /><br /><br /><span style="color:#0000ff;">namespace</span> estrategia<br /><br />{<br /><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">class</span> Estrategia : IProcesarNombres<br /><br /> {<br /><br /> <span style="color:#0000ff;">private</span> contexto _contexto;<br /><br /><br /><br /> <span style="color:#0000ff;">public</span> contexto Contexto<br /><br /> {<br /><br /> <span style="color:#0000ff;">get</span> { <span style="color:#0000ff;">return</span> _contexto; }<br /><br /> <span style="color:#0000ff;">set</span> { _contexto = <span style="color:#0000ff;">value</span>; }<br /><br /> }<br /><br /><br /><br /> <span style="color:#0000ff;">public</span> Estrategia(contexto clase)<br /><br /> {<br /><br /> Contexto = clase;<br /><br /> }<br /><br /><br /><br /> <span style="color:#0000ff;">public</span> Estrategia()<br /><br /> {<br /><br /> }<br /><br /><br /><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> AsignarContexto(contexto clase)<br /><br /> {<br /><br /> Contexto = clase;<br /><br /> }<br /><br /><br /><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">string</span> ProcesarNombres(<span style="color:#0000ff;">string</span> Nombre, <span style="color:#0000ff;">string</span> Apellido)<br /><br /> {<br /><br /> <span style="color:#0000ff;">return</span> Contexto.MiClase.ProcesarNombres(Nombre, Apellido);<br /><br /> }<br /><br /> <br /><br /> }<br /><br />}</pre><pre> </pre><br /><div align="justify"><pre>Ya teniendo el contexto y la estategia abstracta podemos hacer las estrategias concretas que también implementan IProcesarNombres. </pre><pre>Vamos a utlizar aquí la clase puente que ya implementa esta interfaz y además vamos a crear dos estrategias más: Una que muestre nombre y apellido, y otra que Muestre 'Apellido:' y 'Nombre:' y sus respectivos valores.</pre><pre><br /></pre></div><br /><br /><pre><span style="color:#0000ff;">using</span> System;<br /><br /><span style="color:#0000ff;">using</span> System.Collections.Generic;<br /><br /><span style="color:#0000ff;">using</span> System.Text;<br /><br /><br /><br /><span style="color:#0000ff;">namespace</span> estrategia<br /><br />{<br /><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">class</span> NombreApellido:IProcesarNombres<br /><br /> {<br /><br /> <span style="color:#0000ff;">private</span> <span style="color:#0000ff;">String</span> _caracter = <span style="color:#b22222;">" "</span>;<br /><br /><br /><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">String</span> Caracter<br /><br /> {<br /><br /> <span style="color:#0000ff;">get</span> { <span style="color:#0000ff;">return</span> _caracter; }<br /><br /> <span style="color:#0000ff;">set</span> { _caracter = <span style="color:#0000ff;">value</span>; }<br /><br /> }<br /><br /><br /><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">string</span> ProcesarNombres(<span style="color:#0000ff;">string</span> Nombre, <span style="color:#0000ff;">string</span> Apellido)<br /><br /> {<br /><br /> <span style="color:#0000ff;">return</span> Nombre.Trim() + Caracter + Apellido.Trim();<br /><br /> }<br /><br /> }</pre><pre>}<br /><br /><br /><br /> </pre><br /><br /><pre><span style="color:#0000ff;">using</span> System;<br /><br /><span style="color:#0000ff;">using</span> System.Collections.Generic;<br /><br /><span style="color:#0000ff;">using</span> System.Text;<br /><br /><br /><br /><span style="color:#0000ff;">namespace</span> estrategia<br /><br />{<br /><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">class</span> Enriquecido:IProcesarNombres<br /><br /> {<br /><br /> <span style="color:#0000ff;">private</span> <span style="color:#0000ff;">String</span> _caracter = <span style="color:#b22222;">" - "</span>;<br /><br /><br /><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">String</span> Caracter<br /><br /> {<br /><br /> <span style="color:#0000ff;">get</span> { <span style="color:#0000ff;">return</span> _caracter; }<br /><br /> <span style="color:#0000ff;">set</span> { _caracter = <span style="color:#0000ff;">value</span>; }<br /><br /> }<br /><br /><br /><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">string</span> ProcesarNombres(<span style="color:#0000ff;">string</span> Nombre, <span style="color:#0000ff;">string</span> Apellido)<br /><br /> {<br /><br /> <span style="color:#0000ff;">return</span> <span style="color:#b22222;">"Apellido: "</span> + Apellido.Trim() + Caracter + <span style="color:#b22222;">"Nombre: "</span> + Nombre.Trim();<br /><br /> }<br /><br /> }<br /><br />}</pre><pre>Ahora sólo nos falta ver como deberíamos utilizarlo. En la siguiente figura se muestra el formulario.</pre><pre><img id="BLOGGER_PHOTO_ID_5072605313545017314" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYvx158JBBZZJdHLkdHjxDcZ6z_47ORY2dTTcBMhyphenhyphenRW3nAYreOPFFfYcqan85AhIYIuGx_5q1gjBgUBGfw-Lgzk4hq3rQYR0HGHsDiRDLYjAFAqnoxCLy1qq9_aGpHsJ2juGtMNtNyYrI/s400/estrate1.JPG" border="0" /></pre><pre> </pre><pre>El código que contiene es el siguiente:</pre><pre><br /> </pre><br /><br /><pre><span style="color:#0000ff;">using</span> System;<br /><br /><span style="color:#0000ff;">using</span> System.Collections.Generic;<br /><br /><span style="color:#0000ff;">using</span> System.ComponentModel;<br /><br /><span style="color:#0000ff;">using</span> System.Data;<br /><br /><span style="color:#0000ff;">using</span> System.Drawing;<br /><br /><span style="color:#0000ff;">using</span> System.Text;<br /><br /><span style="color:#0000ff;">using</span> System.Windows.Forms;<br /><br /><span style="color:#0000ff;">using</span> estrategia;<br /><br /><br /><br /><span style="color:#0000ff;">namespace</span> WindowsApplication1<br /><br />{<br /><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">partial</span> <span style="color:#0000ff;">class</span> Form1 : Form<br /><br /> {<br /><br /> <span style="color:#0000ff;">public</span> Form1()<br /><br /> {<br /><br /> InitializeComponent();<br /><br /> }<br /><br /><br /><br /> <span style="color:#0000ff;">private</span> <span style="color:#0000ff;">void</span> btn1_Click(<span style="color:#0000ff;">object</span> sender, EventArgs e)<br /><br /> {<br /><br /> Estrategia Proceso = <span style="color:#0000ff;">new</span> Estrategia(<span style="color:#0000ff;">new</span> contexto(<span style="color:#0000ff;">new</span> NombreApellido()));<br /><br /> txt1.Text = Proceso.ProcesarNombres(txtNombre.Text, txtApellido.Text);<br /><br /> }<br /><br /><br /><br /> <span style="color:#0000ff;">private</span> <span style="color:#0000ff;">void</span> button1_Click(<span style="color:#0000ff;">object</span> sender, EventArgs e)<br /><br /> {<br /><br /> Estrategia Proceso = <span style="color:#0000ff;">new</span> Estrategia(<span style="color:#0000ff;">new</span> contexto(<span style="color:#0000ff;">new</span> Puente()));<br /><br /> txt2.Text = Proceso.ProcesarNombres(txtNombre.Text, txtApellido.Text);<br /><br /> }<br /><br /><br /><br /> <span style="color:#0000ff;">private</span> <span style="color:#0000ff;">void</span> btn3_Click(<span style="color:#0000ff;">object</span> sender, EventArgs e)<br /><br /> {<br /><br /> Estrategia Proceso = <span style="color:#0000ff;">new</span> Estrategia(<span style="color:#0000ff;">new</span> contexto(<span style="color:#0000ff;">new</span> Enriquecido()));<br /><br /> txt3.Text = Proceso.ProcesarNombres(txtNombre.Text, txtApellido.Text);<br /><br /> }<br /><br /><br /><br /> }<br /><br />}</pre><pre> </pre><pre>Como se puede observar es muy sencillo cambiar de estrategia y obtener un resultado distinto cada vez.</pre>Rodrigo Barros Pascualhttp://www.blogger.com/profile/14562783405904128679noreply@blogger.com1tag:blogger.com,1999:blog-2394381331760636432.post-32755426602449807182007-06-04T14:15:00.000-07:002007-06-11T10:48:03.749-07:00El Patrón Estrategia<div align="justify">La estrategia describe una solución al problema principal inherente a escribir el código principal – como accionar con demandas inesperadas para cambios de implementación.<br />La definición formal de estrategia, fue dada por el "GoF" es: </div><br /><div align="center"><br /><em>"Define una familia de algoritmos, encapsula cada uno, y los hace intercambiables. La estrategia permite al algoritmo variar en dependencia del cliente que la utilice."<br /></div></em><br /><br /><br />Esto resulta algo oscuro en una primera lectura, vamos a tratar de aclarar.<br /><br /><br />¿Cuáles son los componentes de una estrategia?<br /><br /><div align="justify"><br />Una estrategia tiene tres componentes esenciales: "la estrategia abstracta", que es una clase que define la interfaz, y funcionalidad genérica para las "estrategias concretas", que son subclases que definen varias implementaciones posibles. El tercer componente, el "Contexto", es responsable de controlar la referencia a la implementación actual.</div><div align="justify"><br /></div><br /><br /><img id="BLOGGER_PHOTO_ID_5072321375256082274" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguwkZcx56wPfY1i6JY6Zh6gp0l1vIIXYzfZpl8Xg8kaZ7N_vsDrTAb6fzeWrQK6sCAkA88DK24D-A5QoWQ4sYPXjtNX85ZOrsv3TYOCPhNraOkeo1vfn9BRzndwkQJ6pMRHecxB89xBlU/s400/image003.gif" border="0" /><br /><br /><br /><div align="justify">Si está pensando que este diagrama se ve muy similar al puente, está en lo cierto. Puede pensar incluso, que el patrón de estrategia es como un "puente dinámico" en el cual un final (el contexto) es estático; pero el otro (la estrategia) está creado por varias variantes con el propósito de entregar una implementación específica en un momento específico. La esencia del patrón es tal que la decisión como establecer qué subclase debe ser instanciada en cualquier momento dependa del estado del "cliente". El ejemplo clásico del patrón descansa en la responsabilidad de instanciar la estrategia concreta del objeto en el cliente, con la que pasa la referencia al contexto. </div>Rodrigo Barros Pascualhttp://www.blogger.com/profile/14562783405904128679noreply@blogger.com0tag:blogger.com,1999:blog-2394381331760636432.post-22977425592025012472007-06-01T05:49:00.000-07:002007-06-11T10:44:47.052-07:00Implementando el Patrón Decorador con Visual Fox ProSiguiendo la misma línea del artículo anterior, vamos a implementar el patrón decorador en Visual Fox Pro.<br /><br /><br /><br /><br /><br />Dentro de un prg para mi caso ejemplos.prg vamos a escrbir las clases:<br /><br /><br /><br /><br /><br /><br /><pre><span style="color:#000000;">DEFINE</span> <span style="color:#000000;">CLASS</span> IComponente <span style="color:#000000;">as</span> <span style="color:#000000;">Custom</span><br /> <span style="color:#000000;">FUNCTION</span> procesarNombres()<br /> LPARAMETERS nombre,apellido<br /> endfunc<br />ENDDEFINE<br /><br /><br /><br /><span style="color:#000000;">DEFINE</span> <span style="color:#000000;">CLASS</span> puente <span style="color:#000000;">as</span> Icomponente<br /><br /> Caracter= <span style="color:#000000;">", "</span><br /> <br /> PROCEDURE Caracter_ACCESS<br /> <span style="color:#000000;">RETURN</span> <span style="color:#000000;">THIS</span>.Caracter<br /> ENDPROC<br /> <br /> PROCEDURE Caracter_ASSIGN<br /> LPARAMETERS Valor<br /> <span style="color:#000000;">THIS</span>.Caracter=Valor<br /> ENDPROC<br /><br /> <span style="color:#000000;">FUNCTION</span> procesarNombres()<br /> LPARAMETERS nombre,apellido<br /> <span style="color:#000000;">RETURN</span> ALLTRIM(Apellido) + <span style="color:#000000;">this</span>.Caracter + ALLTRIM(nombre)<br /> ENDFUNC<br /> <br />ENDDEFINE<br /><br /><br /><br /><span style="color:#000000;">DEFINE</span> <span style="color:#000000;">CLASS</span> decorador <span style="color:#000000;">as</span> Icomponente<br /><br /> componente=<span style="color:#000000;">null</span><br /><br /> PROCEDURE init ()<br /> LPARAMETERS clase<br /> <span style="color:#000000;">this</span>.componente=clase<br /> ENDPROC<br /><br /> <span style="color:#000000;">FUNCTION</span> procesarNombres()<br /> LPARAMETERS nombre,apellido<br /> <span style="color:#000000;">RETURN</span> <span style="color:#000000;">this</span>.componente.procesarNombres(nombre,apellido)<br /> ENDFUNC<br /> <br />ENDDEFINE</pre><pre><br /><br /><span style="color:#000000;">DEFINE</span> <span style="color:#000000;">CLASS</span> AgregarNumeracion <span style="color:#000000;">as</span> decorador<br /><br /> padre=<span style="color:#000000;">null</span><br /> <br /> Numero= 1<br /> <br /> PROCEDURE Numero_ACCESS<br /> <span style="color:#000000;">RETURN</span> <span style="color:#000000;">THIS</span>.Numero<br /> ENDPROC<br /> <br /> PROCEDURE Numero_ASSIGN<br /> LPARAMETERS Valor<br /> <span style="color:#000000;">THIS</span>.Numero=Valor<br /> ENDPROC<br /> <br /> Separador= <span style="color:#000000;">" - "</span><br /> <br /> PROCEDURE Separador_ACCESS<br /> <span style="color:#000000;">RETURN</span> <span style="color:#000000;">THIS</span>.Separador<br /> ENDPROC<br /> <br /> PROCEDURE Separador_ASSIGN<br /> LPARAMETERS Valor<br /> <span style="color:#000000;">THIS</span>.Separador=Valor<br /> ENDPROC<br /><br /> PROCEDURE init ()<br /> LPARAMETERS clase<br /> <span style="color:#000000;">this</span>.padre=NEWOBJECT(<span style="color:#000000;">"decorador"</span>,<span style="color:#000000;">'','',clase)</span><br /> ENDPROC<br /><br /> <span style="color:#000000;">FUNCTION</span> procesarNombres()<br /> LPARAMETERS nombre,apellido<br /> <span style="color:#000000;">RETURN</span> ALLTRIM(STR(<span style="color:#000000;">this</span>.numero))+ <span style="color:#000000;">this</span>.separador + <span style="color:#000000;">this</span>.padre.procesarNombres(nombre,apellido)<br /> ENDFUNC<br /> <br />ENDDEFINE<br /><br /><span style="color:#000000;">DEFINE</span> <span style="color:#000000;">CLASS</span> AgregarNacionalidad <span style="color:#000000;">as</span> decorador<br /><br /> padre=<span style="color:#000000;">null</span><br /> <br /> Nacionalidad= <span style="color:#000000;">"Argentina"</span><br /> <br /> PROCEDURE Nacionalidad_ACCESS<br /> <span style="color:#000000;">RETURN</span> <span style="color:#000000;">THIS</span>.Nacionalidad<br /> ENDPROC<br /> <br /> PROCEDURE Nacionalidad_ASSIGN<br /> LPARAMETERS Valor<br /> <span style="color:#000000;">THIS</span>.Nacionalidad=Valor<br /> ENDPROC<br /> <br /> Separador= <span style="color:#000000;">" - "</span><br /> <br /> PROCEDURE Separador_ACCESS<br /> <span style="color:#000000;">RETURN</span> <span style="color:#000000;">THIS</span>.Separador<br /> ENDPROC<br /> <br /> PROCEDURE Separador_ASSIGN<br /> LPARAMETERS Valor<br /> <span style="color:#000000;">THIS</span>.Separador=Valor<br /> ENDPROC<br /> <br /> <br /> PROCEDURE init ()<br /> LPARAMETERS clase<br /> <span style="color:#000000;">this</span>.padre=NEWOBJECT(<span style="color:#000000;">"decorador"</span>,<span style="color:#000000;">'','',clase)</span><br /> ENDPROC<br /><br /> <span style="color:#000000;">FUNCTION</span> procesarNombres()<br /> LPARAMETERS nombre,apellido<br /> <span style="color:#000000;">RETURN</span> <span style="color:#000000;">this</span>.padre.procesarNombres(nombre,apellido) + <span style="color:#000000;">this</span>.separador + <span style="color:#000000;">this</span>.nacionalidad<br /> ENDFUNC<br /> <br />ENDDEFINE</pre><pre><br /> </pre><br /><br /><br /><br /><br />Ya estamos listos para consumir las clases. Creamos el mismo formulario que para C#:<br /><br /><br /><br /><p><img id="BLOGGER_PHOTO_ID_5071083419652486994" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiaF3Tm8WJ0LQfc5eIIgFfcE3J8FitIW6OXwnliLdfDHyFXFpXQzPM_y5luzT36yZ09R4foMWmZV00gSnUP2WoNhtFDPzhLg92M9flu5KWnBWGqfEGCFptdd2LfpNGi2ybiYdTcrzbhSHg/s400/deco2.JPG" border="0" /></p><p></p><p>En el Init del formulario hacemos una referencia al archivo de las clases...</p><p><br />SET PROCEDURE TO "ejemplos.prg" </p><p>En el primer botón colocamos...</p><p><br />MiPuente = NEWOBJECT("puente")<br />ThisForm.txt1.Value=MiPuente.procesarnombres(thisform.txtNombre.Value,thisform.txtApellido.Value)<br />RELEASE MiPuente </p><p>En el segundo...</p><p><br />MiPuente = NEWOBJECT("puente")<br />*agrego los decoradores<br />deco1 = NEWOBJECT("AgregarNumeracion",'','',MiPuente)<br />*llamo al método<br />ThisForm.txt2.Value=deco1.procesarnombres(thisform.txtNombre.Value,thisform.txtApellido.Value)<br />*elimino los objetos<br />RELEASE MiPuente<br />RELEASE deco1</p><p></p><p>En el tercero...</p><p><br />MiPuente = NEWOBJECT("puente")<br />*agrego los decoradores<br />deco2 = NEWOBJECT("AgregarNacionalidad",'','',MiPuente)<br />deco2.nacionalidad=thisform.txtNacionalidad.value<br />*llamo al método<br />ThisForm.txt3.Value=deco2.procesarnombres(thisform.txtNombre.Value,thisform.txtApellido.Value)<br />*elimino los objetos<br />RELEASE MiPuente<br />RELEASE deco2</p><p></p><p>En el cuarto...</p><p><br />MiPuente = NEWOBJECT("puente")<br />*agrego los decoradores<br />deco1 = NEWOBJECT("AgregarNumeracion",'','',MiPuente)<br />deco2 = NEWOBJECT("AgregarNacionalidad",'','',deco1)<br />deco2.nacionalidad=thisform.txtNacionalidad.value<br /><br />*llamo al método<br />ThisForm.txt4.Value=deco2.procesarnombres(thisform.txtNombre.Value,thisform.txtApellido.Value)<br />*elimino los objetos<br />RELEASE MiPuente<br />RELEASE deco1<br />RELEASE deco2</p><p></p><p>y por último en el quinto...</p><p><br />*agrego los decoradores<br />deco2 = NEWOBJECT("AgregarNacionalidad",'','',NEWOBJECT("AgregarNumeracion",'','',NEWOBJECT("puente")))<br />deco2.nacionalidad=thisform.txtNacionalidad.value<br />*llamo al método<br />ThisForm.txt5.Value=deco2.procesarnombres(thisform.txtNombre.Value,thisform.txtApellido.Value)<br />*elimino los objetos<br />RELEASE deco2</p><p></p><p>Como se puede ver, al igual que en artículo anterior, con una sola línea se puede agregar funcionalidad de forma dinámica al objeto.</p><p><br />deco2 = NEWOBJECT("AgregarNacionalidad",'','',NEWOBJECT("AgregarNumeracion",'','',NEWOBJECT("puente")))</p><p></p><p>El patrón decorador es muy útil en ambientes multiempresa, por ejemplo, donde las reglas de negocio son muy cambiantes entre sí, e incluso entre sucursales. Con este patrón se podría manejar de forma más eficiente la diversidad de funcionalidades que el trabajo multiempresa significa.</p><p></p><p><br /></p>Rodrigo Barros Pascualhttp://www.blogger.com/profile/14562783405904128679noreply@blogger.com0tag:blogger.com,1999:blog-2394381331760636432.post-38526805724741352862007-06-01T05:16:00.000-07:002007-06-11T10:47:50.194-07:00Implementando el Patrón Decorador con C#<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjc4r4e9xQf2ok-Og2f7hOWqJaxOUmpL9wEYpvMVDac6Y0AqovlMPPMDUemvttfxPhVAFCnFP4zLe7LvionK8nuQcjBTqP8dfFEx75AJYQUrHVoDAjIttrqd5fr5qDOW9s4LMF93qRAlMU/s1600-h/deco1.JPG"></a>Para empezar vamos a Implementar el patrón decorador en C#. Lo primero será crear la interfaz IProcesarNombres.<br /><br /><br /><br /><br /><br /><pre><span style="color:#0000ff;">using</span> System;<br /><span style="color:#0000ff;">using</span> System.Collections.Generic;<br /><span style="color:#0000ff;">using</span> System.Text;<br /><span style="color:#0000ff;">namespace</span> patronDecorador<br />{<br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">interface</span> IProcesarNombres<br /> {<br /> <span style="color:#0000ff;">String</span> ProcesarNombres(<span style="color:#0000ff;">String</span> Nombre, <span style="color:#0000ff;">String</span> Apellido);<br /> }<br />} </pre><pre><br /><br /><br /><br /><br /><br />Ahora bien, nuestra clase (en este caso puente) debe implementar esta interfaz.<br /></pre><pre><br /><br /><br /><br /><br /><span style="color:#0000ff;">using</span> System;<br /><span style="color:#0000ff;">using</span> System.Collections.Generic;<br /><span style="color:#0000ff;">using</span> System.Text;<br /><span style="color:#0000ff;">namespace</span> patronDecorador<br />{<br /><span style="color:#0000ff;">public</span> <span style="color:#0000ff;">class</span> Puente : IProcesarNombres<br />{<br /><span style="color:#0000ff;">private</span> <span style="color:#0000ff;">String</span> _caracter = <span style="color:#b22222;">", "</span>;<br /><span style="color:#0000ff;">public</span> <span style="color:#0000ff;">String</span> Caracter<br />{<br /><span style="color:#0000ff;">get</span> { <span style="color:#0000ff;">return</span> _caracter; }<br /><span style="color:#0000ff;">set</span> { _caracter = <span style="color:#0000ff;">value</span>.Trim(); }<br />}<br /><span style="color:#0000ff;">public</span> <span style="color:#0000ff;">String</span> ProcesarNombres(<span style="color:#0000ff;">String</span> Nombre, <span style="color:#0000ff;">String</span> Apellido)<br />{<br /><span style="color:#0000ff;">return</span> Apellido.Trim() + Caracter + Nombre.Trim();<br />}<br />}<br />}<br /></pre><pre><br /><br /><br /><br /><br /><br /><br />El decorador también debe implementarla como se muestra a continuación.<br /></pre><pre><br /><br /><br /><br /><br /><br /> </pre><pre><span style="color:#0000ff;">using</span> System;<br /><span style="color:#0000ff;">using</span> System.Collections.Generic;<br /><span style="color:#0000ff;">using</span> System.Text;<br /><span style="color:#0000ff;">namespace</span> patronDecorador<br />{<br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">abstract</span> <span style="color:#0000ff;">class</span> Decorador : IProcesarNombres<br /> {<br /> <span style="color:#0000ff;">protected</span> IProcesarNombres _Componente;<br /> <span style="color:#0000ff;">public</span> Decorador(IProcesarNombres Clase)<br /> {<br /> _Componente = Clase;<br /> }<br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">virtual</span> <span style="color:#0000ff;">String</span> ProcesarNombres(<span style="color:#0000ff;">String</span> Nombre, <span style="color:#0000ff;">String</span> Apellido)<br /> {<br /> <span style="color:#0000ff;">return</span> _Componente.ProcesarNombres(Nombre, Apellido);<br /> }<br /> }<br />}</pre><pre><br /> </pre><br /><br />Luego creamos dos clases decoradoras:<br /><br /><br /><br /><br /><br />1) AgregarNumeracion:<br /><br /><pre><br /><br /><span style="color:#0000ff;">using</span> System;<br /><span style="color:#0000ff;">using</span> System.Collections.Generic;<br /><span style="color:#0000ff;">using</span> System.Text;<br /><span style="color:#0000ff;">namespace</span> patronDecorador<br />{<br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">class</span> AgregarNumeracion : Decorador<br /> {<br /> <span style="color:#0000ff;">private</span> Int32 _numero = 1;<br /> <span style="color:#0000ff;">public</span> Int32 Numero<br /> {<br /> <span style="color:#0000ff;">get</span> { <span style="color:#0000ff;">return</span> _numero; }<br /> <span style="color:#0000ff;">set</span> { _numero = <span style="color:#0000ff;">value</span>; }<br /> }<br /><br /> <span style="color:#0000ff;">private</span> <span style="color:#0000ff;">String</span> _separador = <span style="color:#b22222;">" - "</span>;<br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">String</span> Separador<br /> {<br /> <span style="color:#0000ff;">get</span> { <span style="color:#0000ff;">return</span> _separador; }<br /> <span style="color:#0000ff;">set</span> { _separador = <span style="color:#0000ff;">value</span>; }<br /> }<br /><br /> <span style="color:#0000ff;">public</span> AgregarNumeracion(IProcesarNombres Clase): <span style="color:#0000ff;">base</span>(Clase){}<br /><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">override</span> <span style="color:#0000ff;">String</span> ProcesarNombres(<span style="color:#0000ff;">String</span> Nombre, <span style="color:#0000ff;">String</span> Apellido)<br /> {<br /> <span style="color:#0000ff;">return</span> Numero.ToString()+ Separador + <span style="color:#0000ff;">base</span>.ProcesarNombres(Nombre, Apellido);<br /> }<br /> }<br />}<br /><br /><br /></pre><br /><br /><br />2) AgregarNacionalidad :<br /><br /><br /><br /><pre><span style="color:#0000ff;">using</span> System;<br /><span style="color:#0000ff;">using</span> System.Collections.Generic;<br /><span style="color:#0000ff;">using</span> System.Text;<br /><span style="color:#0000ff;">namespace</span> patronDecorador<br />{<br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">class</span> AgregarNacionalidad : Decorador<br /> {<br /> <span style="color:#0000ff;">private</span> <span style="color:#0000ff;">String</span> _Nacionalidad= <span style="color:#b22222;">"Argentina"</span>;<br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">String</span> Nacionalidad<br /> {<br /> <span style="color:#0000ff;">get</span> { <span style="color:#0000ff;">return</span> _Nacionalidad; }<br /> <span style="color:#0000ff;">set</span> { _Nacionalidad = <span style="color:#0000ff;">value</span>.Trim(); }<br /> }<br /><br /> <span style="color:#0000ff;">private</span> <span style="color:#0000ff;">String</span> _separador = <span style="color:#b22222;">" - "</span>;<br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">String</span> Separador<br /> {<br /> <span style="color:#0000ff;">get</span> { <span style="color:#0000ff;">return</span> _separador; }<br /> <span style="color:#0000ff;">set</span> { _separador = <span style="color:#0000ff;">value</span>; }<br /> }<br /><br /> <span style="color:#0000ff;">public</span> AgregarNacionalidad(IProcesarNombres Clase): <span style="color:#0000ff;">base</span>(Clase){}<br /><br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">override</span> <span style="color:#0000ff;">String</span> ProcesarNombres(<span style="color:#0000ff;">String</span> Nombre, <span style="color:#0000ff;">String</span> Apellido)<br /> {<br /> <span style="color:#0000ff;">return</span> <span style="color:#0000ff;">base</span>.ProcesarNombres(Nombre, Apellido) + Separador +Nacionalidad;<br /> }<br /> }<br />}<br /><br /></pre><br /><br /><br /><br /><br /><br /><br />Ahora ya se puede comenzar a usarlas. Creamos el siguiente formulario:<br /><br /><br /><br /><p><img id="BLOGGER_PHOTO_ID_5071072261327451954" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtmyKe16UTktQHOSmSFdYGjjWAEd8tZ5GQKbnMVFMVD8of2eB2dT4gcsHjpjV6eGSRt-smgCbybxtXlnyw_jTNZQGvfFxuP8zze03YdP3Qw_5rGA8eCdmMKjkAc1GwxTtornd7N65U_18/s400/deco1.JPG" border="0" /></p><p></p><p>A continuación el código que le da la funcionalidad:</p><p><br /><pre><span style="color:#0000ff;">using</span> System;<br /><span style="color:#0000ff;">using</span> System.Collections.Generic;<br /><span style="color:#0000ff;">using</span> System.ComponentModel;<br /><span style="color:#0000ff;">using</span> System.Data;<br /><span style="color:#0000ff;">using</span> System.Drawing;<br /><span style="color:#0000ff;">using</span> System.Text;<br /><span style="color:#0000ff;">using</span> System.Windows.Forms;<br /><span style="color:#0000ff;">using</span> patronDecorador;<br /><span style="color:#0000ff;">namespace</span> WindowsApplication1<br />{<br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">partial</span> <span style="color:#0000ff;">class</span> Decorador : Form<br /> {<br /> <span style="color:#0000ff;">public</span> Decorador()<br /> {<br /> InitializeComponent();<br /> }<br /><br /> <span style="color:#0000ff;">private</span> <span style="color:#0000ff;">void</span> btn1_Click(<span style="color:#0000ff;">object</span> sender, EventArgs e)<br /> {<br /> Puente MiClase = <span style="color:#0000ff;">new</span> Puente();<br /> txt1.Text= MiClase.ProcesarNombres(txtNombre.Text,txtApellido.Text);<br /> }<br /> <span style="color:#0000ff;">private</span> <span style="color:#0000ff;">void</span> btn2_Click(<span style="color:#0000ff;">object</span> sender, EventArgs e)<br /> {<br /> Puente MiClase = <span style="color:#0000ff;">new</span> Puente();<br /> AgregarNumeracion Deco1 = <span style="color:#0000ff;">new</span> AgregarNumeracion(MiClase);<br /> txt2.Text = Deco1.ProcesarNombres(txtNombre.Text,txtApellido.Text);<br /> }<br /> <span style="color:#0000ff;">private</span> <span style="color:#0000ff;">void</span> btn3_Click(<span style="color:#0000ff;">object</span> sender, EventArgs e)<br /> {<br /> Puente MiClase = <span style="color:#0000ff;">new</span> Puente();<br /> AgregarNacionalidad Deco2 = <span style="color:#0000ff;">new</span> AgregarNacionalidad(MiClase);<br /> Deco2.Nacionalidad = txtNacionalidad.Text;<br /> txt3.Text = Deco2.ProcesarNombres(txtNombre.Text, txtApellido.Text);<br /> }<br /> <span style="color:#0000ff;">private</span> <span style="color:#0000ff;">void</span> btn4_Click(<span style="color:#0000ff;">object</span> sender, EventArgs e)<br /> {<br /> Puente MiClase = <span style="color:#0000ff;">new</span> Puente();<br /> AgregarNumeracion Deco1 = <span style="color:#0000ff;">new</span> AgregarNumeracion(MiClase);<br /> AgregarNacionalidad Deco2 = <span style="color:#0000ff;">new</span> AgregarNacionalidad(Deco1);<br /> Deco2.Nacionalidad = txtNacionalidad.Text;<br /> txt4.Text = Deco2.ProcesarNombres(txtNombre.Text, txtApellido.Text);<br /> }<br /> <span style="color:#0000ff;">private</span> <span style="color:#0000ff;">void</span> btn5_Click_1(<span style="color:#0000ff;">object</span> sender, EventArgs e)<br /> {<br /> AgregarNacionalidad FormaReducida = <span style="color:#0000ff;">new</span> AgregarNacionalidad(<span style="color:#0000ff;">new</span> AgregarNumeracion(<span style="color:#0000ff;">new</span> Puente()));<br /> FormaReducida.Nacionalidad = txtNacionalidad.Text;<br /> txt5.Text = FormaReducida.ProcesarNombres(txtNombre.Text, txtApellido.Text);<br /> }<br /> }<br />}</pre><br /><p></p><p></p><p>Como verán con una sola y sencilla linea se agrega funcionalidad al objeto:</p><p>AgregarNacionalidad FormaReducida = new AgregarNacionalidad(new AgregarNumeracion(new Puente()));</p><p>Esta es la principal ventaja del patrón Decorador.</p><p>A continuación su aplicación en VFP.</p><p></p><p><br /></p>Rodrigo Barros Pascualhttp://www.blogger.com/profile/14562783405904128679noreply@blogger.com0tag:blogger.com,1999:blog-2394381331760636432.post-55171997637513200802007-06-01T05:00:00.000-07:002007-06-11T10:47:07.016-07:00El Patrón DecoradorEl decorador describe una solución al problema de agregar una funcionalidad a un objeto sin cambiar realmente el código en el objeto.<br />La definición formal del decorador, dada por el "GoF" es:<br /><br /><em>"Adjuntar responsabilidad adicional a un objeto dinámicamente."</em><br /><br />La necesidad de cambiar dinámicamente la funcionalidad o comportamiento de un objeto surge típicamente en una de estas dos situaciones. Primero, cuando el código fuente del objeto está no disponible, puede ser que el objeto es un control ActiveX o una biblioteca de clases de terceras partes está utilizada. Segundo, cuando la clase que es ampliamente utilizada para la responsabilidad específica, se necesita sólo en una o más situaciones<br /><br />La principal diferencia entre usar subclases y el patrón Decorador es que con las subclases se trabaja directamente con la clase, en cambio con el patrón Decorador se modifican los objetos dinámicamente. Cuando se extiende una clase, los cambios hechos a las clases hijos serán afectados a todas las instancias de las clases hijos; sin embargo, con el patrón Decorador se aplican los cambios a cada objeto individual que se quiere cambiar.<br /><br /><strong>Estructura del patrón Decorador</strong><br /><br /><br /><img id="BLOGGER_PHOTO_ID_5071067992129959698" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi843ZkyTCvYUtBp3gnoRK5DR5L7it4TforMAIt0_4erXJHflI46tlMINp40nYOGiI9FzG-JZbpRpyd_dbk9EARSDX2JpIOlkcjpgF2BY1AOvqgad7rV-6052tVhY9S-3ci1c0Ys-u3miQ/s400/art163-img05-367x293.gif" border="0" /><br /><br /><br />A continuación describiremos la estructura:<br /><br /><strong>Componente</strong>: Clase abstracta común a todas las clases susceptibles de ser ampliadas con el Decorador.<br /><br /><strong>ComponenteConcreto:</strong> Son las clases cuya funcionalidad se puede extender y en las que se delega en última instancia para realizar las operaciones propias de la clase.<br /><br /><strong>Decorator:</strong> Clase abstracta que declara la estructura común a todos los Decoradores y declara (o implementa, según sea el caso) la responsabilidad de mantener una referencia al objeto que se extiende. Es posible que sobrecargue todos los métodos de la clase Componente con llamadas al componente concreto, de forma que aquellos métodos cuya funcionalidad no se extiende simplemente llaman a los originales.<br /><p><strong>DecoradorConcreto1 y DecoradorConcreto2:</strong> Son clases concretas que heredan de Decorator e implementan las extensiones de funcionalidad de la clase original ComponenteConcreto. </p><p><br /><a name="uso"></a><a name="estructura"></a>Este patrón es en realidad un puente extendido. Debido a que el cliente está afectado, puede dirigir el objeto decorador como si realmente fuera la implementación al final del puente estándar, porque la interfaz de los dos es la misma. Debido a que la implementación está afectada, la petición mira exactamente igual que si fuera directamente desde el cliente. No necesita nunca conocer que incluso que el decorador existe.<br />En los próximos dos artículos veremos como se implementa este patrón en VFP y C# extendiendo el ejemplo del patrón puente que venimos tratando en artículos anteriores. </p><p></p>Rodrigo Barros Pascualhttp://www.blogger.com/profile/14562783405904128679noreply@blogger.com0tag:blogger.com,1999:blog-2394381331760636432.post-89726380877262081862007-06-01T04:58:00.000-07:002007-06-11T10:46:40.359-07:00García Marquez en Macondo<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgq3eB9BmWpUWqNjF1ZHxKsx0sTuUdDe9Mue_ur45g1ksqIOdbwU5P7KEM6T-OEBK7sdOIuR3endcZCGja2WFjSGnZypPVmOh3y-_Xj0VUguqk9aFHtSNyqjyTCGeldIf0gnSynz7wG3iE/s1600-h/300px-Gabogabo.jpg"><img id="BLOGGER_PHOTO_ID_5071064268393314050" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgq3eB9BmWpUWqNjF1ZHxKsx0sTuUdDe9Mue_ur45g1ksqIOdbwU5P7KEM6T-OEBK7sdOIuR3endcZCGja2WFjSGnZypPVmOh3y-_Xj0VUguqk9aFHtSNyqjyTCGeldIf0gnSynz7wG3iE/s400/300px-Gabogabo.jpg" border="0" /></a><br /><div>Anoche estuve viendo en la tele que Gabriel García Márquez regreso a su tierra natal, el pueblo que inspiro su tan famoso Macondo. Como verán uno de los libros que recomiendo es “Cien años de Soledad”. Este libro es una joya de la literatura. Tal vez hay algunos que dicen que es un libro difícil de leer y de mantener el hilo conductivo, pero yo creo que en realidad es una obra magnifica. Tiene un dinamismo sensacional. No es una historia más contada en un libro muy bien escrito, todo lo contrario, es una recopilación de historias entrelazadas de forma coherente y con gusto más que superior.<br />Es por ello que recomiendo este libro que yo definiría como “Delicioso”.</div><br /><div></div><br /><div></div>Rodrigo Barros Pascualhttp://www.blogger.com/profile/14562783405904128679noreply@blogger.com0tag:blogger.com,1999:blog-2394381331760636432.post-5130100056450847642007-05-31T06:39:00.000-07:002007-06-11T10:46:14.584-07:00EL CRISTO DE SAN JUAN DE LA CRUZ<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGe9lfqcq5VJStFhot0VMs4gpiLnIM4tmI8gqTchpRcE0PCWMQ-9zk9ylasALK5tSCV-62Cdg8SwTQ3TtlWLDf-i1nia9KgsQAoX1AkFctd-plFNU3suQw6ze5ekCJeVcPjW7vL0B0Trg/s1600-h/cristo.jpg"><img id="BLOGGER_PHOTO_ID_5070720095484016370" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGe9lfqcq5VJStFhot0VMs4gpiLnIM4tmI8gqTchpRcE0PCWMQ-9zk9ylasALK5tSCV-62Cdg8SwTQ3TtlWLDf-i1nia9KgsQAoX1AkFctd-plFNU3suQw6ze5ekCJeVcPjW7vL0B0Trg/s400/cristo.jpg" border="0" /></a><br /><div>Posiblemente el cuadro más famoso y difundido de Dalí. Fue hecho en 1951. Curiosamente la posición del Cristo no es idea original del pintor, se basó en un cuadro conservado en el Monasterio de la Encarnación de Avíla realizado por San Juan de la Cruz. Pertenece a su época mística-clásica que comenzó en los años 40 y que ha sido criticada por numerosos entendidos acusándola de comercial. Realmente son pinturas con un domino absoluto del dibujo, muy trabajadas y con composiciones espléndidas. Picasso comentó en esta época de Dalí "...el último pintor renacentista que le queda al mundo..", una opinión que comparto totalmente.</div><br /><div></div><br /><div>Definitivamente EXCELENTE!!.</div>Rodrigo Barros Pascualhttp://www.blogger.com/profile/14562783405904128679noreply@blogger.com0tag:blogger.com,1999:blog-2394381331760636432.post-73162925269424499962007-05-31T06:30:00.000-07:002007-06-11T10:45:52.952-07:00El Patrón Singleton con C#<div align="justify">Uno de los patrones de diseño sin lugar a dudas más utilizado y conocido, es el patrón Singleton. De forma resumida, un singleton en una clase que únicamente permite que exista simultáneamente una única instancia de si misma y que ofrece un punto de acceso común a ella.<br />Este patrón nos puede ayudar en situaciones en las que queramos que haya únicamente una única instancia de una clase, por ejemplo para tener un acceso centralizado a un sistema de log o un sistema de caché, de forma que desde cualquier punto de la aplicación en el que queramos utilizar estos recursos, podamos garantizar que accedamos siempre a la misma instancia.<br />El código necesario para poder disponer de un singleton es realmente sencillo, son básicamente 2 líneas, que podremos ampliar con el comportamiento específico que queramos darle.</div><br /><br /><pre><span style="color:#0000ff;">sealed</span> <span style="color:#0000ff;">class</span> Singleton<br />{<br /> <span style="color:#0000ff;">private</span> Singleton() {}<br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">readonly</span> Singleton Instance = <span style="color:#0000ff;">new</span> Singleton();<br />} </pre><br /><br />Para utilizar el código, podríamos usar desde cualquier punto Singleton.Instance y accederíamos siempre a la misma instancia.<br />Entrando un poco más al detalle del código utilizado, merece la pena explicar un par de cosas referentes a cómo se crea la instancia y cómo se evitan posibles problemas que podrían provocarse, sobretodo en entornos multihilo.<br />Lo primero de todo es destacar como el constructor de la clase está marcado como “private”, lo cual hace imposible crear instancias de la clase y nos obliga a acceder a la única posible instancia a través de la propiedad Instance. Con el mismo fin la clase está marcada como “sealed”, por lo que nos garantizamos de que nadie va a poder heredar de esta clase y crear múltiples instancias de nuestro singleton.<br />En cuanto a la instancia de la clase, está marcada como “public”, “readonly” y “static”, lo cual hace que se pueda acceder a ella desde cualquier otra parte, que no sea modificable y que se cree la primera vez que se acceda a ella, como veremos más adelante.<br />Hay un par de cuestiones típicas que suelen afectar a otras implementaciones de este patrón en otros lenguajes, una es la inicialización perezosa y la segunda los posibles problemas con el uso de múltiples hilos. La inicialización perezosa se refiere a la conveniencia por eficiencia, de no crear la instancia hasta el momento en que se acceda por primera vez a la instancia. En otros lenguajes esto se realiza mediante un “if” en un método “getInstance”, que comprueba si la instancia ha sido ya creada o no, de forma que se crea la primera vez que se llama al método. En situaciones multihilo esto puede provocar que varios hilos entre en el “if” a la vez, creando varias instancias. Para solventar este posible problema se suele utilizar una solución basada en un “Double-Check”, en la cual, lo primero que hace el método “getInstance” es comprobar si la instancia ha sido creada y en caso contrario entra en una “sección crítica”, en la cual se vuelve a realizar la comprobación y si sigue sin estar creada, se crea. De esta forma si dos hilos entran en el primer “if”, al llegar a la sección crítica sus accesos se serializarían, produciendo que el primero de ellos crease la instancia y al entrar el segundo, la comprobación de si existe la instancia fuera positiva. A continuación puede verse el código correspondiente a este funcionamiento en C#, aunque no es necesario utilizarlo, ya que el código mostrado anteriormente tiene la misma funcionalidad como veremos a continuación.<br /><br /><pre><span style="color:#0000ff;">class</span> Singleton<br />{<br /> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> Singleton Instance()<br /> {<br /> <span style="color:#0000ff;">if</span> (_instance == <span style="color:#0000ff;">null</span>)<br /> {<br /> <span style="color:#0000ff;">lock</span> (<span style="color:#0000ff;">typeof</span>(Singleton))<br /> {<br /> <span style="color:#0000ff;">if</span> (_instance == <span style="color:#0000ff;">null</span>)<br /> {<br /> _instance = <span style="color:#0000ff;">new</span> Singleton();<br /> }<br /> }<br /> }<br /> <span style="color:#0000ff;">return</span> _instance;<br /> }<br /><br /> <span style="color:#0000ff;">protected</span> Singleton() {}<br /> <span style="color:#0000ff;">private</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">volatile</span> Singleton _instance = <span style="color:#0000ff;">null</span>;<br />} </pre>Rodrigo Barros Pascualhttp://www.blogger.com/profile/14562783405904128679noreply@blogger.com2tag:blogger.com,1999:blog-2394381331760636432.post-52458814152039851602007-05-30T08:06:00.000-07:002007-06-11T10:45:13.944-07:00¿Qué es un puente (bridge) y cómo se debe utilizar?<div align="justify">El puente es el patrón más básico de todos y lo encontrará, en la medida que se familiarice más con los patrones, en general. Notará entonces, que el puente (en alguna forma) se encuentra en la cima de casi todos los otros patrones. Es por esto que se le conoce como la "madre" de los patrones de diseño.<br />¿Cómo puedo reconocer cuando necesito un puente?<br />La definición formal de un puente, tomada del Gof es:<br /><br /><em>"Desacoplar una abstracción de su implementación de tal forma que las dos puedan variar independientemente."<br /></em><br />Espectacular, ¿eh? ¿Hacemos esto realmente en nuestro código? La respuesta corta es que probablemente nosotros lo hacemos más de lo que nos damos cuenta.<br /><br />Vamos a tomar un ejemplo común en Visual Fox Pro.<br />Supongamos que nuestra aplicación necesita que le ingresen el nombre y apellido y que luego estos valores sean mostrados de alguna forma en otro lado.<br />Podríamos crear dos TextBox para ingresar estos datos y un EditBox para que estos sean mostrados. </div><br /><br /><div align="center"></div><br /><br /><p align="center"><img id="BLOGGER_PHOTO_ID_5070371954735045938" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhshbz9dPDgeoqbWFVyA0XgKGwS_gn_8KIniKObtT_K_Y0Y6YQjrriJixfyRmZxxORHyk-0s6xaJOJ0II31enoHeMSf0oYC9Ovd3JgQxTXOfs8xC5wzNEU69LR028VWct04hkG5tJemIeA/s320/puente1.JPG" border="0" /><br />Figura 1. Formulario </p><p align="justify"><br />En el evento click del botón podríamos escribir el siguiente código:<br /></p><p align="justify"><br />ThisForm.txtMostrar.Value = ALLTRIM(thisform.txtApellido.Value) + ", " + ALLTRIM(thisform.txtNombre.Value)</p><p align="justify"></p><p align="justify">Esto produce una salida donde el Apellido se muestra primero que el nombre y separados entre sí por una coma.<br />Ahora… si queremos reutilizar este código… IMPOSIBLE!.</p><br /><br /><strong>¿Cuáles son los componentes de un puente?</strong><br /><br /><br /><div align="justify"><br />Un puente tiene dos componentes esenciales, la "abstracción", que es el objeto responsable de inicializar una operación, y la "implementación", que es el objeto que la lleva a cabo. (Figura 2) La abstracción conoce su implementación porque guarda una referencia a la misma, o porque lo posee (por ejemplo, lo contiene). Observe que, a pesar de esta estructura, el diagrama denota que la abstracción crea la implementación, y que no es, en absoluto, un requerimiento del patrón. Un puente también puede hacer uso de una referencia ya existente para una misma implementación de objeto. De hecho, diseñar puentes de esta forma, puede ser muy eficiente porque diferentes objetos abstracción pueden ser utilizados en un mismo objeto implementación. </div><br /><br /><br /><br /><br /><br /><img id="BLOGGER_PHOTO_ID_5070373612592422210" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj520xNs3BJain84OvJJcRRAVRjwJQdQWsc1eTCNnAUiWWPHnnGjyphqzB_zpkh-2pZdX28t-52yDgpeqrLxu6cb2bony7ekgsn_3MhEkvYmV96Zh0bFhJKaDSFPk5Aw_mgTDGdGrxtT80/s400/puente2.JPG" border="0" /><br /><div align="center"><br />Figura 2. El patrón de puente básico </div><div align="justify"><br />Debido a que Visual FoxPro tiene un modelo de contenedores muy bueno, la mayoría de los desarrolladores notarán que lo han utilizado (no intencionalmente) para implementar Puentes con más frecuencia de lo que imaginan. Sin embargo, no confunda el envío de mensajes con el puente. Si un método de un botón de comandos llama a un método en su formulario padre, esto implementa directamente la acción necesaria, que es enviar un mensaje, no un puente. Sin embargo, si el método del formulario va a llamar a otro objeto para que lleve a cabo la acción, entonces tenemos un puente.<br />Entonces, para implementar un puente necesita identificar qué objeto va a realizar la función de abstracción y cuál la implementación. Una vez que lo haya definido, todo lo que queda por decidir es cómo el puente entre los dos será codificado y esto dependerá enteramente del escenario. </div><div align="justify"></div><div align="justify"></div><div align="justify"></div><div align="justify"><strong>¿Cómo implementar el puente en el caso anterior?</strong></div><strong></strong><div align="justify"><br />Para implementar el puente debemos separar la implementación de la abstracción. Para ello vamos a crear una clase de tipo Custom llamada puente dentro de alguna biblioteca de clases, para este caso será “ejemplos”. A la clase puente le vamos a anexar un método llamado “procesarNombre”. Este método recibirá como parámetros dos string y devolverá otro string. Quedaría algo como lo siguiente:</div><div align="justify"><br />LPARAMETERS nombre,apellido<br />RETURN ALLTRIM(Apellido) + ", " + ALLTRIM(nombre) </div><div align="justify"><br /></div><div align="justify">Ahora bien, desde el formulario vamos a escribir el siguiente código: </div><div align="justify"><br /></div><div align="justify">MiPuente = CREATEOBJECT("Ejemplos.puente")<br />ThisForm.txtMostrar.Value=MiPuente.procesarnombres(thisform.txtNombre.Value,thisform.txtApellido.Value) </div><div align="justify"><br /></div><div align="justify">Como se puede observar la manera de cómo se procesan los nombres no le importan a mi aplicación. De hecho se puede cambiar la manera de procesar los nombres sin tocar nada de código en el formulario. Lo único que hay que respetar es la interfaz, que en este caso es el método procesarnombres().<br /><br />Esta estrategia desacopla exitosamente la abstracción de la implementación y, como resultado, nuestro código, es mucho más reutilizable.</div><div align="justify"></div><div align="justify"></div>Rodrigo Barros Pascualhttp://www.blogger.com/profile/14562783405904128679noreply@blogger.com0