<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Century Minds</title>
	<atom:link href="http://centuryminds.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://centuryminds.wordpress.com</link>
	<description>Ingeniería del Software en general y Java en particular</description>
	<lastBuildDate>Thu, 03 Feb 2011 03:00:44 +0000</lastBuildDate>
	<language></language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='centuryminds.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Century Minds</title>
		<link>http://centuryminds.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://centuryminds.wordpress.com/osd.xml" title="Century Minds" />
	<atom:link rel='hub' href='http://centuryminds.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Moved!</title>
		<link>http://centuryminds.wordpress.com/2007/05/15/moved/</link>
		<comments>http://centuryminds.wordpress.com/2007/05/15/moved/#comments</comments>
		<pubDate>Tue, 15 May 2007 20:22:24 +0000</pubDate>
		<dc:creator>Rubén Barroso</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://centuryminds.wordpress.com/2007/05/15/moved/</guid>
		<description><![CDATA[We&#8217;ve moved! Our new site here. And our RSS here. Seeya there!<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=centuryminds.wordpress.com&amp;blog=20696&amp;post=45&amp;subd=centuryminds&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>We&#8217;ve moved! Our new site <a href="http://blog.centuryminds.com" title="here">here</a>. And our RSS <a href="http://blog.centuryminds.com" title="feed" target="_blank">here</a>.</p>
<p>Seeya there!</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/centuryminds.wordpress.com/45/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/centuryminds.wordpress.com/45/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/centuryminds.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/centuryminds.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/centuryminds.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/centuryminds.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/centuryminds.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/centuryminds.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/centuryminds.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/centuryminds.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/centuryminds.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/centuryminds.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/centuryminds.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/centuryminds.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/centuryminds.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/centuryminds.wordpress.com/45/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=centuryminds.wordpress.com&amp;blog=20696&amp;post=45&amp;subd=centuryminds&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://centuryminds.wordpress.com/2007/05/15/moved/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b677956a8f95bbb95d02b5775eca6d15?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">centuryminds</media:title>
		</media:content>
	</item>
		<item>
		<title>Anemic Domain Model Antipattern</title>
		<link>http://centuryminds.wordpress.com/2007/03/08/anemic-domain-model-antipattern/</link>
		<comments>http://centuryminds.wordpress.com/2007/03/08/anemic-domain-model-antipattern/#comments</comments>
		<pubDate>Thu, 08 Mar 2007 22:47:15 +0000</pubDate>
		<dc:creator>Mikel Alcón</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://centuryminds.wordpress.com/2007/03/08/anemic-domain-model-antipattern/</guid>
		<description><![CDATA[Anemic ¿Qué!?? Hoy toca hablar de patrones, o mejor dicho, de anti patrones. Esas cosas que se deben evitar por norma general. Mucha de la gente que venimos de lenguajes procedurales (vaya palabro&#8230;) tipo C, tendemos a pensar de esta forma a la hora de programar en Java. ¿Por qué? Por que C no es [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=centuryminds.wordpress.com&amp;blog=20696&amp;post=44&amp;subd=centuryminds&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Anemic ¿Qué!??</p>
<p>Hoy toca hablar de patrones, o mejor dicho, de anti patrones. Esas cosas que se deben evitar por norma general.</p>
<p>Mucha de la gente que venimos de lenguajes procedurales (vaya palabro&#8230;) tipo C, tendemos a pensar de esta forma a la hora de programar en Java. ¿Por qué? Por que C no es un lenguaje orientado a objetos. Para representar en C un dato usamos lo siguiente:<br />
<code></code></p>
<p><code>typedef struct point { int x,y; } point;<br />
....<br />
y usamos punto.x </code><br />
Así que cuando vamos a un lenguaje orientado a objetos tendemos a hacer cosas de este tipo:<br />
<code><br />
public class Casa{<br />
private String nombre;<br />
private boolean alquilada;<br />
private boolean habitable;<br />
public void setNombre()...<br />
public String getNombre()...<br />
public void setAlquilada()...<br />
public boolean isAlquilada()...<br />
....<br />
}</code></p>
<p><code>public class Persona{<br />
private String nombre;<br />
private List casas;<br />
public void setNombre()...<br />
public String getNombre()...<br />
public void setCasas()...<br />
public List getCasas()...<br />
}<br />
..</code><br />
<code> List casasNoAlquiladas= new ArrayList();<br />
for(Persona persona: personas){<br />
for (Casa casa : persona.getCasas()){<br />
if (! casa.isAlquilada() &amp;&amp; casa.isHabitable()){<br />
casasNoAlquiladas.add(casa);<br />
}<br />
}<br />
}<br />
</code></p>
<p>&#8230;.</p>
<p>¿Cuál es el problema con esto? Pues que estamos utilizando las clases de negocio como simples estructuras de datos. Hemos avanzado en la tecnología, ¡ Avancemos  en su uso también! Vale, siempre lo has hecho así, te sientes cómodo con esta solución ¿Con qué problemas te vas a encontrar?</p>
<ul>
<li>Lógica de negocio dispersa por toda la aplicación, seguramente incluso repetida.</li>
<li>Complejidad a la hora de hacer las clases controladoras</li>
<li>Estamos exponiendo la forma en que mantenemos las casas al exterior. Solo debemos exponer las entities, no los value objects! (esto daría para otro post)</li>
<li>¿La lista de casas que devolvemos es inmutable? ¡Cuidado!</li>
<li>Sumando todo lo anterior: Más complejidad = más bugs, además de menos extensible</li>
</ul>
<p>Bueno y ¿Cómo lo solucionaríamos? Muy fácil, introduciendo la lógica de negocio en las clases de negocio:<br />
<code><br />
public class Casa{</code></p>
<p>&#8230;.</p>
<p><code> private final String nombre;<br />
private boolean alquilada;<br />
private boolean habitable;<br />
public String getNombre()...<br />
public void setAlquilada()...<br />
public boolean isAlquilada()...<br />
public boolean isAlquilable(){<br />
return (! casa.isAlquilada() &amp;&amp; casa.isHabitable());<br />
}</code></p>
<p>&#8230;.<br />
}</p>
<p><code>public class Persona{<br />
private String nombre;<br />
private List casas;<br />
public void setNombre()...<br />
public String getNombre()...<br />
public void setCasas()...<br />
public List getCasasAlquilables(){<br />
List list= new ArrayList();<br />
for (Casa casa: casas){<br />
if (casa.isAlquilable()) list.add(casa);<br />
}<br />
return list;<br />
}<br />
}<br />
..</code><br />
<code> List casasNoAlquiladas= new ArrayList();<br />
for(Persona persona: personas){<br />
casasNoAlquiladas.addAll(persona.getCasasAlquilables());<br />
}<br />
</code><br />
Más fácil ¿Verdad? Si no conocías este error común, seguro que ahora te vienen a la memoria un montón de casos en los que podrías ahorrar mucho en código y hacerlo mucho más extensible.</p>
<p>Otro ejemplo: En cierto cliente, hace un cierto tiempo y haciendo cierta aplicación <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  De una clase muy importante en el modelo (Entity) sacabamos unos cuantos informes. En un momento dado, me pidieron que si se podía cambiar cierta lógica a la hora de generar los informes.  Mi respuesta fue: tardo 2 segundos (y uno para pulsar ctrl+shif+T  en Eclipse!! ). ¿Por qué? Porque mi clase de ese entity tan importante tenía lo siguiente:<br />
<code><br />
List&lt;Dato&gt; getSubObjetosQueCumplenCiertaCondiciónDeNegocio(){<br />
for....{<br />
if (obj.condicion1() &amp;&amp; obj.condicion2() &amp;&amp; entity.....)</code></p>
<p><code>        lista.add(...)</code><br />
&#8230;</p>
<p><code>}<br />
}<br />
</code></p>
<p>Lo que me pedían era un cambio de negocio. Yo había entendido mál, un objeto de tipo Dato debía de cumplir obj.condicion() &amp;&amp; obj.condicion3(), pero el cambio no suponía el menor esfuerzo. ¿Cuánto hubiese costado si hubiesemos tenido este código disperso por toda la aplicación?</p>
<p>Se puede discutir si incluir los DAO dentro del objeto de negocio es bueno o malo (Rails y Grails lo hacen),  si algúna lógica concreta debería ir en los controladores, pero al menos este tipo de cosas creo que pueden ayudarte bastante.</p>
<p>Bueno, no se si ha quedado claro, hoy no he dormido mucho y estoy muuuuuy cansado <img src='http://s0.wp.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/centuryminds.wordpress.com/44/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/centuryminds.wordpress.com/44/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/centuryminds.wordpress.com/44/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/centuryminds.wordpress.com/44/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/centuryminds.wordpress.com/44/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/centuryminds.wordpress.com/44/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/centuryminds.wordpress.com/44/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/centuryminds.wordpress.com/44/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/centuryminds.wordpress.com/44/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/centuryminds.wordpress.com/44/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/centuryminds.wordpress.com/44/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/centuryminds.wordpress.com/44/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/centuryminds.wordpress.com/44/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/centuryminds.wordpress.com/44/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/centuryminds.wordpress.com/44/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/centuryminds.wordpress.com/44/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=centuryminds.wordpress.com&amp;blog=20696&amp;post=44&amp;subd=centuryminds&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://centuryminds.wordpress.com/2007/03/08/anemic-domain-model-antipattern/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/84ec0ae167726c1eba48457abcd6b3ee?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">activez</media:title>
		</media:content>
	</item>
		<item>
		<title>You Need Code Reviews</title>
		<link>http://centuryminds.wordpress.com/2007/02/05/you-need-code-reviews/</link>
		<comments>http://centuryminds.wordpress.com/2007/02/05/you-need-code-reviews/#comments</comments>
		<pubDate>Mon, 05 Feb 2007 23:08:59 +0000</pubDate>
		<dc:creator>Rubén Barroso</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://centuryminds.wordpress.com/2007/02/05/you-need-code-reviews/</guid>
		<description><![CDATA[Look at this code: (within a while body) ... if (log.isDebugEnabled()) log.debug("Parsing line " + (lineNumber++)); ... lineNumber used here ... You might be wondering: what´s wrong with it? Well, it turns out that this sort of construction it could become extremely difficult to spot in certain conditions. Imagine a hypothetical situation where this code [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=centuryminds.wordpress.com&amp;blog=20696&amp;post=43&amp;subd=centuryminds&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Look at this code:</p>
<p><em>(within a while body)</em><br />
<code><br />
...<br />
if (log.isDebugEnabled()) log.debug("Parsing line " + (lineNumber++));<br />
...<br />
lineNumber used here<br />
...</code></p>
<p>You might be wondering: what´s wrong with it? Well, it turns out that this sort of construction it could become extremely difficult to spot in certain conditions. Imagine a hypothetical  situation where this code is not working properly in the production environment, and meanwhile the developer in charge of this block of code -the guy as cool as a cucumber- is totally sure about the correctness of it. Okay, you got it, you may be thinking of me: &#8220;How noob this guy is!&#8221;; but Hey!, sometimes you are toiling late in the night and this kind of bugs pass unnoticed until you receive an email from your Development Manager muttering:</p>
<blockquote><p><em>Subject: Potential bug</em></p>
<p><em>I have come across with this statement -</em><em>incidentally- while surfing the code. Beware that the log will be printed out only if the log level is set to DEBUG, so the lineNumber variable won´t be incremented.</em></p>
<p><em>All the best,</em></p>
<p><em>Your Development Manager</em></p></blockquote>
<p>Guess which level the Production Support had established in their environment? Fortunately, I started off saying &#8220;<em>Imagine a hypothetical  situation &#8230;</em>&#8220;.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/centuryminds.wordpress.com/43/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/centuryminds.wordpress.com/43/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/centuryminds.wordpress.com/43/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/centuryminds.wordpress.com/43/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/centuryminds.wordpress.com/43/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/centuryminds.wordpress.com/43/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/centuryminds.wordpress.com/43/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/centuryminds.wordpress.com/43/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/centuryminds.wordpress.com/43/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/centuryminds.wordpress.com/43/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/centuryminds.wordpress.com/43/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/centuryminds.wordpress.com/43/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/centuryminds.wordpress.com/43/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/centuryminds.wordpress.com/43/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/centuryminds.wordpress.com/43/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/centuryminds.wordpress.com/43/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=centuryminds.wordpress.com&amp;blog=20696&amp;post=43&amp;subd=centuryminds&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://centuryminds.wordpress.com/2007/02/05/you-need-code-reviews/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b677956a8f95bbb95d02b5775eca6d15?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">centuryminds</media:title>
		</media:content>
	</item>
		<item>
		<title>Share your knowledge</title>
		<link>http://centuryminds.wordpress.com/2006/12/15/share-your-knowledge/</link>
		<comments>http://centuryminds.wordpress.com/2006/12/15/share-your-knowledge/#comments</comments>
		<pubDate>Fri, 15 Dec 2006 22:32:44 +0000</pubDate>
		<dc:creator>Rubén Barroso</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://centuryminds.wordpress.com/2006/12/15/share-your-knowledge/</guid>
		<description><![CDATA[Thomas Jefferson said: And no matter how many people share it, the idea is not diminished. When I hear your idea, I gain knowledge without diminishing anything of yours. In the same way, if you use your candle to light mine, I get light without darkening your. Like fire, ideas encompass the globe without lessening [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=centuryminds.wordpress.com&amp;blog=20696&amp;post=41&amp;subd=centuryminds&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Thomas Jefferson <a href="http://www.aaronsw.com/weblog/001115" title="And no matter ..." target="_blank">said</a>:</p>
<blockquote><p><em>And no matter how many people share it, the idea is not diminished. When I hear your idea, I gain knowledge without diminishing anything of yours. In the same way, if you use your candle to light mine, I get light without darkening your. Like fire, ideas encompass the globe without lessening their density.</em></p></blockquote>
<p>Sometimes, in this hectic world, you realise that your knowledge about a subject has increased considerably, and probably at that moment you are an expert on it. The &#8220;problem&#8221; now is how you ought to handle that situation in regards to your team mates. You can keep such expertise for your own benefit, considering them a sort of nuissance, if not worse. But that is not supportive. As I see it, helping your co-workers is a professional duty, no matter the reason. No matter the guy. <strong>You must do it because you must do it</strong>. And that´s all. There shouldn´t have to exist more reasons besides that one. Yeah, I know, there are lotsa situations where excuses arise in order not to help someone, but anyway I think it is a good principle to start with. Write it down in your tickler file.</p>
<p>Nonetheless,  there are some important benefits of  being supportive and willing to give others a hand:</p>
<ol>
<li>You can cause a great impact in the morale of your huddle, because your positive attitude might make them want to better themselves in turn. The overall competence of your team spikes. Betcha! That´s good for you as well. If this doesn´t work, pull out.</li>
<li>You may <em>think</em> you are an expert. Believe me: even experts are requested to answer questions they don´t know about! IMHO, I consider this awesome. The search for those answers permits you to assimilate unexplored areas of the topic on discussion.  Therefore, you are gaining more insight, which is always neat. For example, the other day someone asked me about subversion, and how this system performs the merging. I <em>thought</em> I had that under control. I explained to him the basics of the merging in subversion, the reason it should be called <em>diff-and-apply</em> instead of merging, how two revisions from the origin and destination trees are applied to the working copy, and so on. So far, so good. All the same, point in time, he asked me how a merge was actually applied to a specific file in the working copy. That was kinda going thorugh bad times, <em><strong>because I didn´t understand it seamlessly</strong>,</em> hence I wasn´t able to provide him with an answer. Well, in fact, I had to look up that section in a subversion book, read it thoroughly, sink in all that stuff, and lastly give to him the right answer. I could have told him to grab a book and look it up. That would have been a lazy behaviour and, what it´s much worse, I would still be thinking I have that part under control now. It´s wonderful not to be an expert in nearly anything, isn´t it?</li>
<li><strong>Corollary:</strong> the rest of the team come to trust they can rely on you when they feel they´re dead in the water.</li>
</ol>
<p><strong>Corollary to the last Corollary:</strong> Be nice <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/centuryminds.wordpress.com/41/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/centuryminds.wordpress.com/41/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/centuryminds.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/centuryminds.wordpress.com/41/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/centuryminds.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/centuryminds.wordpress.com/41/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/centuryminds.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/centuryminds.wordpress.com/41/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/centuryminds.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/centuryminds.wordpress.com/41/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/centuryminds.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/centuryminds.wordpress.com/41/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/centuryminds.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/centuryminds.wordpress.com/41/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/centuryminds.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/centuryminds.wordpress.com/41/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=centuryminds.wordpress.com&amp;blog=20696&amp;post=41&amp;subd=centuryminds&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://centuryminds.wordpress.com/2006/12/15/share-your-knowledge/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b677956a8f95bbb95d02b5775eca6d15?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">centuryminds</media:title>
		</media:content>
	</item>
		<item>
		<title>AbstractTransactionalSpringContextTests meets TestNG</title>
		<link>http://centuryminds.wordpress.com/2006/12/12/abstracttransactionalspringcontexttests-meets-testng/</link>
		<comments>http://centuryminds.wordpress.com/2006/12/12/abstracttransactionalspringcontexttests-meets-testng/#comments</comments>
		<pubDate>Tue, 12 Dec 2006 20:53:57 +0000</pubDate>
		<dc:creator>Rubén Barroso</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://centuryminds.wordpress.com/2006/12/12/abstracttransactionalspringcontexttests-meets-testng/</guid>
		<description><![CDATA[Introduction In the search of an alternative to JUnit, in relation to the testing of our classes, we -Mikel and I- decided to give TestNG a try. This testing framework takes advantage of a useful feature introduced in the release 5.0 of the Java Language: the annotations. In addition, it provides a rich set of [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=centuryminds.wordpress.com&amp;blog=20696&amp;post=38&amp;subd=centuryminds&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><strong>Introduction </strong></p>
<p>In the search of an alternative to <a href="http://www.junit.org/" title="JUnit" target="_blank">JUnit</a>, in relation to the testing of our classes, we -Mikel and I- decided to give <a href="http://testng.org/" title="TestNG" target="_blank">TestNG</a> a try. This testing framework takes advantage of a useful feature introduced in the release 5.0 of the Java Language: the <a href="http://jcp.org/en/jsr/detail?id=175" title="Annotations (JSR)" target="_blank">annotations</a>. In addition, it provides a rich set of facilities to ease the unit and integration testing of Java classes, like groups and data providers. Unfortunately, these are very well explained in the home page of the project, so let´s consider them as being out of the scope in regards to the main thread of this post.</p>
<p><strong>The Problem</strong></p>
<p>What we want to have: test cases running within a transactional context AND take advantage of the TestNG facilities. The former is neatly addressed by a class named <a href="http://www.springframework.org/docs/api/org/springframework/test/AbstractTransactionalSpringContextTests.html" title="AbstractTransactionalSpringContextTests" target="_blank">AbstractTransactionalSpringContextTests</a>, present in the Spring´s mock package. The latter, well, pretty obvious. What it isn´t so obvious is the way to combine both. Why? TestNG does not provide a direct way to surround the test cases with a transaction, so a rollback action is performed at the end of every test. This way, we are able to avoid side effects between test executions, because one test inserts a row and the next one didn´t expect it, or because a database row is updated between executions breaking some assertions, or because &#8230; you get the idea. When we decided to start using TestNG as our main framework for testing, this absence lead us to ask Cedric Beust, the TestNG project leader, about some way to accomplish with the transaction stuff. He responded us very kind and rapidly, recommending to implement the rollbacking in an <code>@AfterMethod</code> method.</p>
<p><strong>TransactionRollbackTearDownTestCase </strong></p>
<p><em>Note: for this class&#8217;s name origin, take a look at <a href="http://xunitpatterns.com/Transaction%20Rollback%20Teardown.html" title="Transaction Rollback Tear Down" target="_blank">this site </a></em></p>
<p>Probably Cedric is completely right, but we like how <code>AbstractTransactionalSpringContextTests</code> does its business, and of course, the integration with the Spring´s IoC in order to inject the dependencies to the test classes. For that reason, we have come up with an adapter class, which permits us to run TestNG test cases within the transactional context provided by the Spring class. It is kinda adapter because we change the way the class <code>AbstractTransactionalSpringContextTests</code> is used (i.e. inheriting from it), right now we can extend from the new base class and define our test cases as the usual TestNG manner (i.e. through the use of annotations). It is not an adapter as in the software design patterns.</p>
<p>The class is named <code>TransactionalRollbackTearDownTestCase</code>, and following there is a diagram of its relationships:</p>
<p style="text-align:center;"><img src="https://centuryminds.files.wordpress.com/2006/12/testng.png?w=450" alt="TransactionalRollbackTeardownTestCase" /></p>
<p>The code of this class could prove more descriptive than me trying to explain how it does its job:</p>
<pre>
package com.centuryminds.test;

import org.springframework.test.AbstractDependencyInjectionSpringContextTests;
import org.springframework.test.AbstractTransactionalSpringContextTests;

import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;

/**
 * Base test class which permits: 1) Inject dependencies defined in a Spring
 * context. The aforementioned dependencies must be declared as protected
 * members 2) Perform a rollback action after every test. Basically, it
 * acts as an adapter between the TestNG test case structure and the facilities
 * provided by the class {@link AbstractDependencyInjectionSpringContextTests}
 * in the Spring package
 *
 * @see AbstractDependencyInjectionSpringContextTests
 * @see AfterMethod
 * @see BeforeMethod
 */
public abstract class TransactionRollbackTearDownTestCase extends
		AbstractTransactionalSpringContextTests
{

	/**
	 * Test Fixture
	 *
	 * @throws Exception if a error occurred during the fixture execution
	 * @see {@link AbstractDependencyInjectionSpringContextTests#setUp()}
	 * @see {@link AbstractDependencyInjectionSpringContextTests#setPopulateProtectedVariables(boolean)}
	 */
	@BeforeMethod
	protected final void before() throws Exception
	{
		setPopulateProtectedVariables(true);
		super.setUp();
	}

	/**
	 * Test Teardown
	 *
	 * @throws Exception if a error occurred during the teardown execution
	 * @see {@link AbstractDependencyInjectionSpringContextTests#tearDown()}
	 */
	@AfterMethod
	protected final void after() throws Exception
	{
		super.tearDown();
	}
}</pre>
<p>As it can be seen, this class is really simple. It defines two final methods, both TestNG-annotated which delegate the test fixture and teardown actions to the underlying parent implementation. Therefore, every time a test case method is going to be executed, <code>before() </code>will inject the dependencies defined in the Spring context and will create and start a new transaction context. The method <code>tearDown()</code> in turn will perform a rollback action just after the test ends.</p>
<p><strong>Extending the Hierarchy </strong></p>
<p>Obviously, the class above is not enough: where are the dependencies to be injected defined? We have to tell <code>AbstractTransactionalSpringContextTests</code> where to look for them. This can be achieved by a subclass of <code>TransactionalRollbackTearDownTestCase</code>, for example:</p>
<pre>
package com.centuryminds.test;

/**
 * Base test class that specifies the spring contexts containing the dao
 * definitions. The subclasses must provide an implementation of the method
 * {@link #getConfigLocations()}, specifying the files with the spring contexts
 * holding the definitions of the dao and its dependencies
 */
public class BaseDAOTestCase extends TransactionRollbackTearDownTestCase
{
	/**
	 * @see org.springframework.test.AbstractDependencyInjectionSpringContextTests#getConfigLocations()
	 */
	@Override
	protected String[] getConfigLocations()
	{
		return new String[] { "classpath:applicationContext-datasource.xml",
				"classpath:applicationContext-service.xml" };
	}
}</pre>
<p><strong>The Actual Test Class </strong></p>
<p>One important benefit of the separation above is that we could define several BaseDAO* classes, each one of them declaring its own context set. Let´s see an example DAO test class extending from BaseDAOTestCase:</p>
<pre>
package com.centuryminds.test;

import java.util.HashSet;

import org.testng.annotations.Test;

import com.threefish.aquarium.dao.hibernate.GenericHibernateDAO;
import com.threefish.aquarium.model.Role;
import com.threefish.aquarium.model.User;

/**
 * Tests for RoleDAO
 */
public class RoleDAOTest extends BaseDAOTestCase
{
	/** role dao */
	protected GenericHibernateDAO roleDAO;

	/** role */
	private Role role;

	@Test
	public void testCreate() throws Exception
	{
		int amount = roleDAO.findAll().size();

		// let's create a new role to persist
		role = new Role();
		role.setName("testrole");
		role.setDescription("Master of Universe");
		role.setUsers(new HashSet());

		roleDAO.makePersistent(role);

		assertNotNull(role.getId());
		assertEquals(amount + 1, roleDAO.findAll().size());
	}

	@Test
	public void testSuccessfulGet() throws Exception
	{
		role = roleDAO.findById(Long.valueOf(1));

		assertEquals("admin", role.getName());
	}

	@Test
	public void testUpdate() throws Exception
	{
		role = roleDAO.findById(Long.valueOf(1));
		role.setDescription("Super Administrator Role");
		roleDAO.makePersistent(role);

		assertEquals("Super Administrator Role", role.getDescription());
	}
}</pre>
<p>The <code>RoleDAO</code> test class makes use of a custom generic DAO framework, but despite that I think it is pretty self-explanatory. We shall try to explain the generic DAO related interfaces and classes in another post when we get a chance, but for now we have enough.</p>
<p>The test methods are executed within a transaction per test method, which is rollbacked at the very end of it. So, the role insert in the first test (<code>testCreate()</code>), would be rollbacked and future tests depending on the initial state (i.e. the state before <code>testCreate()</code> ran) wouldn´t be affected. We accomplished with the goal of executing the test cases in isolation. Thanks Spring! We accomplished with the goal of using some of the features offered by TestNG. Thanks to you as well!</p>
<p><strong>Future</strong></p>
<p>We are aware about the drawbacks of this solution, and we are pretty sure about the fact that there must exist a more sophisticated solution out there, hence we are very willing to listen to your suggestions to improve the general structure of our current one. We&#8217;ll stay tuned &#8230;</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/centuryminds.wordpress.com/38/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/centuryminds.wordpress.com/38/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/centuryminds.wordpress.com/38/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/centuryminds.wordpress.com/38/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/centuryminds.wordpress.com/38/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/centuryminds.wordpress.com/38/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/centuryminds.wordpress.com/38/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/centuryminds.wordpress.com/38/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/centuryminds.wordpress.com/38/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/centuryminds.wordpress.com/38/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/centuryminds.wordpress.com/38/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/centuryminds.wordpress.com/38/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/centuryminds.wordpress.com/38/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/centuryminds.wordpress.com/38/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/centuryminds.wordpress.com/38/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/centuryminds.wordpress.com/38/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=centuryminds.wordpress.com&amp;blog=20696&amp;post=38&amp;subd=centuryminds&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://centuryminds.wordpress.com/2006/12/12/abstracttransactionalspringcontexttests-meets-testng/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b677956a8f95bbb95d02b5775eca6d15?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">centuryminds</media:title>
		</media:content>

		<media:content url="https://centuryminds.files.wordpress.com/2006/12/testng.png" medium="image">
			<media:title type="html">TransactionalRollbackTeardownTestCase</media:title>
		</media:content>
	</item>
		<item>
		<title>Refactoring the Golden Gate</title>
		<link>http://centuryminds.wordpress.com/2006/12/11/refactoring-the-golden-gate/</link>
		<comments>http://centuryminds.wordpress.com/2006/12/11/refactoring-the-golden-gate/#comments</comments>
		<pubDate>Mon, 11 Dec 2006 09:26:22 +0000</pubDate>
		<dc:creator>Rubén Barroso</dc:creator>
				<category><![CDATA[Refactoring]]></category>

		<guid isPermaLink="false">http://centuryminds.wordpress.com/2006/12/11/refactoring-the-golden-gate/</guid>
		<description><![CDATA[While watching a documentary about the restoration of the Golden Gate -on Discovery Channel-, the main architect of the project confessed: &#8220;It seems hard to justify the huge amount of funds spent in this bridge, getting it ready for The Big One*, when one of our core goals consists of changing its external appearance nothing [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=centuryminds.wordpress.com&amp;blog=20696&amp;post=37&amp;subd=centuryminds&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>While watching a documentary about the restoration of the Golden Gate -on Discovery Channel-, the main architect of the project confessed:</p>
<p>&#8220;<em>It seems hard to justify the huge amount of funds spent in this bridge, getting it ready for The Big One*, when one of our core goals consists of changing its external appearance nothing whatsoever</em>&#8220;</p>
<p>* Referring to the earthquake likely to happen in California</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/centuryminds.wordpress.com/37/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/centuryminds.wordpress.com/37/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/centuryminds.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/centuryminds.wordpress.com/37/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/centuryminds.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/centuryminds.wordpress.com/37/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/centuryminds.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/centuryminds.wordpress.com/37/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/centuryminds.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/centuryminds.wordpress.com/37/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/centuryminds.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/centuryminds.wordpress.com/37/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/centuryminds.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/centuryminds.wordpress.com/37/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/centuryminds.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/centuryminds.wordpress.com/37/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=centuryminds.wordpress.com&amp;blog=20696&amp;post=37&amp;subd=centuryminds&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://centuryminds.wordpress.com/2006/12/11/refactoring-the-golden-gate/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b677956a8f95bbb95d02b5775eca6d15?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">centuryminds</media:title>
		</media:content>
	</item>
		<item>
		<title>No todo va a ser Java: Nintendo Wii</title>
		<link>http://centuryminds.wordpress.com/2006/12/07/no-todo-va-a-ser-java-nintendo-wii/</link>
		<comments>http://centuryminds.wordpress.com/2006/12/07/no-todo-va-a-ser-java-nintendo-wii/#comments</comments>
		<pubDate>Thu, 07 Dec 2006 14:13:09 +0000</pubDate>
		<dc:creator>f3km1n</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://centuryminds.wordpress.com/2006/12/07/no-todo-va-a-ser-java-nintendo-wii/</guid>
		<description><![CDATA[Hace tiempo que tengo ganas de escribir algo. Después de las presiones recibidas por Rubén y tras ver que Colin y Mikel también se han animado a escribir, no tengo más excusas. Aunque para mi primer post no hablaré sobre Java. De momento, no voy a escribir nada sobre: OSGi, Java 6, Apache Mina, Aplicacione [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=centuryminds.wordpress.com&amp;blog=20696&amp;post=35&amp;subd=centuryminds&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Hace tiempo que tengo ganas de escribir algo. Después de las presiones recibidas por Rubén y tras ver que <a href="http://blog.colinfleming.net/">Colin</a> y Mikel también se han animado a escribir, no tengo más excusas. Aunque para mi primer post no hablaré sobre Java. De momento, no voy a escribir nada sobre: OSGi, Java 6, Apache Mina, Aplicacione distribuidas, etc. Aunque estoy deseando empezar a hablar sobre estos temas.</p>
<p>Para mi debut en el blog,  voy a contar brevemente mis primeras impresiones con mi nueva consola: Nintendo Wii. Soy un jugador casual de videojuegos a quien le gusta, sobre todo, jugar con sus amigos de vez en cuando. Aunque en estos momentos no tengo demasiado tiempo libre (tengo pendiente por leerme el <a href="http://www.amazon.com/Java-Concurrency-Practice-Brian-Goetz/dp/0321349601">Java Concurrency In Practice</a> y la especificación de OSGi) me he comprado la consola sin dudarlo.</p>
<p>Después de estar una horas jugando la <a href="http://www.redsteelgame.com/">RedSteel</a> en el salón,  tipico mata-mata en primera persona, sólo puedo decir que es una pasada. La capacidad de inmersión en el juego es espectacular, gracias al mando. Esto de poder apuntar con el mando como si fuera una pistola le da una nueva vida a los &#8220;shot´em up&#8221;.  Estoy deseando ver las aplicaciones del Wiimando en otro tipo de juegos.</p>
<p>Por otro lado, no he visto ningún problema para jugar con un proyector. Leí hace poco un post que decía que había problemas para jugar con la Wii en un proyector. Al parecer comentaba que existía perdida de precisión en el mando, debido a las distancia y al tamaño de la pantalla generada por el proyector. Yo he encontrado insignificante la perdida de precisión del mando en un proyector y queda compensada por el tamaño de la imagen</p>
<p><img src="http://www.computeremuzone.com/fichas/e/buitre-ams.gif" alt="Emilo Butrageño CPC" align="middle" height="136" width="218" /></p>
<p>Por ultimo, este fin de semana voy a comprobar como de divertido es jugar con los amigos. Veremos si la consola pasa la prueba de la jugabilidad. Va a tener un duro juez, un amigo que piensa que el último juego divertido es el <a href="http://www.computeremuzone.com/fichas/e/emiliobutragueno.php">Emilio Butrageño</a> del <a href="http://en.wikipedia.org/wiki/Amstrad_CPC">Amstrad CPC</a> y que los juegos actuales son demasiado complicados.</p>
<p>Bueno, espero seguir contando más cosas, aunque creo que después de esto no me van a dejar volver escribir. A por cierto, este es mi Mii. He salido muy favorecido.<a href="https://centuryminds.wordpress.com/wp-admin/upload.php?style=inline&amp;tab=browse&amp;post_id=35&amp;_wpnonce=787fd377f2&amp;ID=36&amp;action=view&amp;paged" id="file-link-36" title="Mii" class="file-link image"> 			</a></p>
<p><a href="http://centuryminds.files.wordpress.com/2006/12/mii.JPG" title="Mii"><img src="http://centuryminds.files.wordpress.com/2006/12/mii.JPG?w=450" alt="Mii" /></a></p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/centuryminds.wordpress.com/35/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/centuryminds.wordpress.com/35/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/centuryminds.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/centuryminds.wordpress.com/35/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/centuryminds.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/centuryminds.wordpress.com/35/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/centuryminds.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/centuryminds.wordpress.com/35/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/centuryminds.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/centuryminds.wordpress.com/35/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/centuryminds.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/centuryminds.wordpress.com/35/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/centuryminds.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/centuryminds.wordpress.com/35/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/centuryminds.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/centuryminds.wordpress.com/35/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=centuryminds.wordpress.com&amp;blog=20696&amp;post=35&amp;subd=centuryminds&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://centuryminds.wordpress.com/2006/12/07/no-todo-va-a-ser-java-nintendo-wii/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/35abf87770aacea28cdbe0ad3b7ba3a5?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">f3km1n</media:title>
		</media:content>

		<media:content url="http://www.computeremuzone.com/fichas/e/buitre-ams.gif" medium="image">
			<media:title type="html">Emilo Butrageño CPC</media:title>
		</media:content>

		<media:content url="http://centuryminds.files.wordpress.com/2006/12/mii.JPG" medium="image">
			<media:title type="html">Mii</media:title>
		</media:content>
	</item>
		<item>
		<title>Thinking Recursive</title>
		<link>http://centuryminds.wordpress.com/2006/11/23/thinking-recursive/</link>
		<comments>http://centuryminds.wordpress.com/2006/11/23/thinking-recursive/#comments</comments>
		<pubDate>Thu, 23 Nov 2006 20:29:38 +0000</pubDate>
		<dc:creator>Rubén Barroso</dc:creator>
				<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://centuryminds.wordpress.com/2006/11/23/thinking-recursive/</guid>
		<description><![CDATA[My first attempt to write something in English (Don´t cut me some slack!) Basically, the programs written in functional languages like Lisp or Haskell are based on function definitions. I don´t want, by no means, to give a thorough explanation of the features that functional languages offer because, among other things, I am not an [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=centuryminds.wordpress.com&amp;blog=20696&amp;post=33&amp;subd=centuryminds&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p> <a href="http://centuryminds.wordpress.com/2006/11/23/thinking-recursive/englishgif/" rel="attachment wp-att-34" title="english.gif"><img src="https://centuryminds.files.wordpress.com/2006/11/english.gif?w=450" alt="english.gif" /></a> My first attempt to write something in English (Don´t cut me some slack!)</p>
<p>Basically, the programs written in functional languages like <a href="http://en.wikipedia.org/wiki/Lisp_programming_language">Lisp</a> or <a href="http://www.haskell.org/">Haskell</a> are based on function definitions. I don´t want, by no means, to give a thorough explanation of the features that functional languages offer because, among other things, I am not an expert on such languages (although I´d like to). I am writting this because not until I tried to implement some probs kinda recursive-natured, did I find how quick &amp; fun this kind of programming style is.<br />
Let´s set out to implement a naive algorithm for sorting lists in Haskell, so for a given input list, we get the corresponding sorted list. The function <code>sort</code> takes an argument of type list and returns a new list representing the former one in order.</p>
<pre>-- Sort a list
sort :: Ord a =&gt; [a] -&gt; [a]
sort [] = []
sort (x:xs) = insert x (sort xs)</pre>
<p>The first line comprises the function definition, which takes a list of elements of type <code>a</code>, and returns the same type (<code>[a] -&gt; [a]</code>). The string &#8220;<code>Ord a</code>&#8221; restricts the potential members of the list to types compliant with the ordering rules (integers for instance). But this is Haskell specifics, not very appealing. Let´s go to the implementation. The second line is the implementation of the function for an empty list, which in turn returns an empty list.<br />
Lokking over the last line, we can notice that it defines how a non-empty list, (<code>x:xs</code>) being <code>x</code> the first element and <code>xs</code> the remainder, is going to be sorted. For that, it makes use of a new function named <code>insert</code>. Here you are:</p>
<pre>-- Insert an element in to a list, maintaining the order
insert :: Ord a =&gt; a -&gt; [a] -&gt; [a]
insert y [] = y:[]
insert y (m:ms)    | y &lt;= m = y:(m:ms)
                   | y &gt; m     = m:(insert y ms)</pre>
<p>This second function takes two arguments, the first one being an element of type <code>a</code>, and the other a list of elements of the same type. Same type restrictions as in the parent function. The return value is another list. The trivial case (<code>insert y [] = y:[]</code>) concatenates an element with an empty list. The general case says (last two lines): &#8220;if the element to insert is less or equal than the first element in the list, concatenate them. Otherwise, join the first element in the list with a recursive call using the same element and the remaining elements in the list&#8221;. Easy ha!</p>
<p>Let´s see the recursive call stack for this execution:</p>
<pre>
sort [9, 3, 5]
       |
insert 9 (sort [3, 5])
       |
insert 9 (insert 3 (sort [5]))
       |
insert 9 (insert 3 (insert 5 (sort [])))
       |
insert 9 (insert 3 (insert 5 []))
       |
insert 9 (insert 3 5:[])
       |
insert 9 (3:5)
       |
3:(insert 9 5:[])
       |
3:5(insert 9 [])
       |
3:5:9:[]
       |
[3, 5, 9]</pre>
<p>Yay! Some may argue that this implementation is time-taking, that it does too many recursive calls even for small inputs. A complete resource waster. I couldn´t do anything else but agree with that, but, you know what? I don´t care! It´s just this code´s neatness what makes me feel thrilled. I look at it and I think: &#8220;Ey dude! It´s as pretty as a picture!&#8221;. If you still feel like sprucing it up, a good starting point could be <a href="http://citeseer.ist.psu.edu/burstall77transformation.html">this one.</a></p>
<p>Another good point in the functions above is that I didn´t say that the input list had to hold numeric elements! Surprisingly (not for an expert), the following execution outputs a nice result (guess why?):</p>
<pre>sort ["Water", "The", "Dead", "In"]

... (call trace left out)

["Dead","In","The","Water"]</pre>
<p>For the most part, this is what I wanted to show here. Isn´t it worth the hassle? At least for me, no doubts.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/centuryminds.wordpress.com/33/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/centuryminds.wordpress.com/33/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/centuryminds.wordpress.com/33/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/centuryminds.wordpress.com/33/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/centuryminds.wordpress.com/33/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/centuryminds.wordpress.com/33/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/centuryminds.wordpress.com/33/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/centuryminds.wordpress.com/33/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/centuryminds.wordpress.com/33/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/centuryminds.wordpress.com/33/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/centuryminds.wordpress.com/33/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/centuryminds.wordpress.com/33/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/centuryminds.wordpress.com/33/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/centuryminds.wordpress.com/33/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/centuryminds.wordpress.com/33/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/centuryminds.wordpress.com/33/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=centuryminds.wordpress.com&amp;blog=20696&amp;post=33&amp;subd=centuryminds&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://centuryminds.wordpress.com/2006/11/23/thinking-recursive/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b677956a8f95bbb95d02b5775eca6d15?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">centuryminds</media:title>
		</media:content>

		<media:content url="https://centuryminds.files.wordpress.com/2006/11/english.gif" medium="image">
			<media:title type="html">english.gif</media:title>
		</media:content>
	</item>
		<item>
		<title>Cuidado con el SQL Injection</title>
		<link>http://centuryminds.wordpress.com/2006/11/10/cuidado-con-el-sql-injection/</link>
		<comments>http://centuryminds.wordpress.com/2006/11/10/cuidado-con-el-sql-injection/#comments</comments>
		<pubDate>Fri, 10 Nov 2006 12:27:32 +0000</pubDate>
		<dc:creator>Mikel Alcón</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://centuryminds.wordpress.com/2006/11/10/cuidado-con-el-sql-injection/</guid>
		<description><![CDATA[Un reciente post de Joel explicaba como hacer SQL Injection. Voy a extender aquí un poco la información. Imaginemos que somos muy malos programadores y tenemos el siguiente código: String query=&#8221;select user, pass from user where user=&#8217;&#8221;+user+&#8221;&#8216; &#8220;; Si introducimos como usuario pepito, tenemos que se ejecuta: select user, pass from user where user=&#8217;pepito&#8217; ¡Fenomenal! [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=centuryminds.wordpress.com&amp;blog=20696&amp;post=32&amp;subd=centuryminds&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Un <a href="http://www.joelonsoftware.com/items/2006/11/01.html">reciente</a> post de Joel explicaba como hacer SQL Injection. Voy a extender aquí un poco la información.<br />
Imaginemos que somos muy malos programadores y tenemos el siguiente código:</p>
<p><em><strong>String query=&#8221;select user, pass from user where user=&#8217;&#8221;+user+&#8221;&#8216; &#8220;;</strong></em></p>
<p>Si introducimos como usuario pepito, tenemos que se ejecuta:</p>
<p><em><strong>select user, pass from user where user=&#8217;pepito&#8217;</strong></em></p>
<p>¡Fenomenal! &#8230;¿Fenomenal? y si en vez de usar pepito pongo &#8216;;drop table xxxx; &#8212; , ¿Qué pasa?</p>
<p><em><strong>select user, pass from user where user=&#8221;; drop table xxxx; &#8212; &#8216;</strong></em></p>
<p>¡Fenomenal!  Nos acabamos de cepillar la tabla xxxx;</p>
<p>Vale, entonces es cuando pensamos, pues filtramos todos las comillas simples. Y entonces es cuando viene nuestro mejor cliente, el señor O&#8217;Brian y decide que si nuestro sistema no acepta su nombre quizás es que no merecemos que se gaste dinero en nosotros. Así que bueno, aceptamos &#8216;, pero sustituimos &#8216; por &#8221; en todos los literales.</p>
<p>Encones tenemos algo así:</p>
<p><strong><em>insert into xxxx values &#8230; O&#8221;Brian &#8230;.</em></strong></p>
<p>Y en BD queda como O&#8217;Brian.</p>
<p>Joder. ¡Somos buenísimos! Hemos arreglado el problema del SQL Injection con sustituir &#8216; por &#8221; doble&#8230; ¿o no?</p>
<p>Imaginamos que una vez tenemos un usuario en nuestra BD, luego utilizamos dicho dato para hacer otras queries a su vez (Ej.:&#8221;Dame todas las compras del usuario X&#8221;). Como solo securizamos las queries que tenían entrada de usuario, resulta que seguimos teniendo la siguiente query:</p>
<p><em><strong>query=&#8221;select * from compras where usuario=&#8217;&#8221;+usuario+&#8221;&#8216;&#8221;;</strong></em></p>
<p>¡Y  ya la tenemos montada otra vez!</p>
<p>Resulta que como protegemos la query de entrada pero, una vez almacenado el registro,   guardamos el texto sin proteger, tenemos otra vez el mismo problema.</p>
<p><strong>Conclusión 1 : </strong>Protege TODAS LAS QUERIES, no solo las que crees que son de entrada.</p>
<p>¿Filtramos solo las comillas simples?</p>
<p>Bueno, quizás tengas algo así:</p>
<p><em><strong>String id= xxxxx</strong></em></p>
<p><em><strong>query=&#8221;select * from tabla where id=&#8221; +id;</strong></em></p>
<p>Siendo el id numérico en la BD. Pues ya la tenemos montada, no nos hacen falta comillas para nada.</p>
<p>Podemos dar a id el valor de<em> id</em>, o algo peor <em>id; drop table xxxx;</em> o quitamos el resto del filtrado con &#8212; o /** **/ (Comentario en SQL) ,etc.</p>
<p>Otra: en mysql por ejemplo 9e3 es 9000, cuidado con pensar que limitando el tamaño del parámetro podemos conseguir algo&#8230;</p>
<p><strong>Conclusión 2:</strong> Son vulnerables TODOS los campos, repasa todos y cada uno de los campos</p>
<p>Otro error común es pensar, bueno, nuestro modelo de datos es complejo, nadie va a adivinar el nombre de las tablas y de los campos&#8230;¡MAL! Pueden sacarlos si los errores de BD se sacan directamente al usuario. Ahh vale, tu siempre rediriges a una página de error, estas a salvo&#8230;¡EEEERRROOOOOR! Se pueden sacar por inferencia. ¿Cómo? Con sentencias condicionales:</p>
<p><em><strong>select case when condicion then &#8216;menor&#8217; else &#8216;mayor&#8217; end;</strong></em></p>
<p>Es decir, devolvemos un texto o otro dependiendo de la condición.</p>
<p>Así la condición puede ser, dame el primer bit de cierto campo. Y el then/else un elemento de diferenciación. Donde la &#8220;diferenciación&#8221; pueden ser varias cosas:</p>
<ul>
<li>Esperas de tiempo diferente</li>
<li>Variar la respuesta</li>
<li>Devolver error en uno y en otro no (Ejemplo: el campo a devolver es un numérico y en uno devolvemos 3 y en otro &#8216;caca&#8217; o más fácil: &#8220;select case when condición then 37 else 37/0&#8243;)</li>
</ul>
<p>Además pueden atacar a las tablas de metadatos donde se almacenan las descripciones de las tablas, etc.</p>
<p>Por tanto&#8230;</p>
<p><strong>Conclusión 3:</strong> Nuestro sistema no es invulnerable porque &#8220;ocultemos&#8221; los nombres de  tablas y campos.</p>
<p>Hay unos cuantos caracteres más que filtrar. SQL es un lenguaje y por tanto hay muchas formas de hacer las cosas, así que si usas Java<strong> lo mejor es utilizar Prepared Statements.</strong></p>
<p>Un presentación sobre el tema <a href="http://www.blackhat.com/presentations/bh-europe-05/bh-eu-05-litchfield.pdf">aquí</a>.</p>
<p><strong>UPDATE:</strong> Rubén me envía <a href="http://www.owasp.org/index.php/OWASP_Guide_Project">este enlace</a>. Guía para desarrollo Web seguro. Imprescindible.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/centuryminds.wordpress.com/32/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/centuryminds.wordpress.com/32/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/centuryminds.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/centuryminds.wordpress.com/32/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/centuryminds.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/centuryminds.wordpress.com/32/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/centuryminds.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/centuryminds.wordpress.com/32/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/centuryminds.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/centuryminds.wordpress.com/32/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/centuryminds.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/centuryminds.wordpress.com/32/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/centuryminds.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/centuryminds.wordpress.com/32/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/centuryminds.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/centuryminds.wordpress.com/32/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=centuryminds.wordpress.com&amp;blog=20696&amp;post=32&amp;subd=centuryminds&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://centuryminds.wordpress.com/2006/11/10/cuidado-con-el-sql-injection/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/84ec0ae167726c1eba48457abcd6b3ee?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">activez</media:title>
		</media:content>
	</item>
		<item>
		<title>Jetty Embebido</title>
		<link>http://centuryminds.wordpress.com/2006/11/08/jetty-embebido/</link>
		<comments>http://centuryminds.wordpress.com/2006/11/08/jetty-embebido/#comments</comments>
		<pubDate>Wed, 08 Nov 2006 10:07:47 +0000</pubDate>
		<dc:creator>Mikel Alcón</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://centuryminds.wordpress.com/2006/11/08/jetty-embebido/</guid>
		<description><![CDATA[Una característica muy interesante del servidor Jetty es que puede ser embebido en cualquier aplicación JAVA. Esto nos permite hacer diversas cosas: Desde dar una interfaz de configuración Web a una aplicación no Web, hasta cosas más exóticas como realizar testing de un cliente http. Lo mejor que tiene es que es facilísimo poner un [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=centuryminds.wordpress.com&amp;blog=20696&amp;post=31&amp;subd=centuryminds&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p class="MsoNormal">Una característica muy interesante del servidor Jetty es que puede ser embebido en cualquier aplicación JAVA. Esto nos permite hacer diversas cosas: Desde dar una interfaz de configuración <span> </span>Web a una aplicación no Web, hasta cosas más exóticas como realizar testing de un cliente http.</p>
<p class="MsoNormal"> Lo mejor que tiene es que es facilísimo poner un servlet a escuchar en una url, vamos, cosa de niños. Bueno, no me enrollo más, aquí va el código:</p>
<pre>import java.io.IOException;</pre>
<pre>import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;</pre>
<pre>import org.mortbay.jetty.Server;
import org.mortbay.jetty.servlet.Context;
import org.mortbay.jetty.servlet.ServletHolder;</pre>
<pre>...</pre>
<pre>server= new Server(8080);
Context root = new Context(server,"/contexto",Context.SESSIONS);
root.addServlet(new ServletHolder(new Servlet(){
 public void destroy() {}
 public ServletConfig getServletConfig() {return null;}
 public String getServletInfo() {return null;}
 public void init(ServletConfig arg0) throws ServletException {}
 public void service(ServletRequest request, ServletResponse response)</pre>
<pre>         throws ServletException, IOException {
     response.getOutputStream().write"HOLA MUNDO"getBytes());
 }
}), "/servlet");
server.start();</pre>
<pre> ...</pre>
<p>Y ya tenemos nuestro servlet escuchando en <em>http://localhost:8080/contexto/servlet. </em>Este servlet tampoco hace mucho, pero da una idea de lo fácil que puede ser poner a escuchar un servlet en un Jetty embebido.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/centuryminds.wordpress.com/31/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/centuryminds.wordpress.com/31/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/centuryminds.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/centuryminds.wordpress.com/31/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/centuryminds.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/centuryminds.wordpress.com/31/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/centuryminds.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/centuryminds.wordpress.com/31/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/centuryminds.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/centuryminds.wordpress.com/31/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/centuryminds.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/centuryminds.wordpress.com/31/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/centuryminds.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/centuryminds.wordpress.com/31/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/centuryminds.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/centuryminds.wordpress.com/31/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=centuryminds.wordpress.com&amp;blog=20696&amp;post=31&amp;subd=centuryminds&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://centuryminds.wordpress.com/2006/11/08/jetty-embebido/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/84ec0ae167726c1eba48457abcd6b3ee?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">activez</media:title>
		</media:content>
	</item>
		<item>
		<title>Planificando de forma Ágil (2)</title>
		<link>http://centuryminds.wordpress.com/2006/11/07/planificando-de-forma-agil-2/</link>
		<comments>http://centuryminds.wordpress.com/2006/11/07/planificando-de-forma-agil-2/#comments</comments>
		<pubDate>Tue, 07 Nov 2006 14:17:57 +0000</pubDate>
		<dc:creator>Mikel Alcón</dc:creator>
				<category><![CDATA[business]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Software Engineering]]></category>

		<guid isPermaLink="false">http://centuryminds.wordpress.com/2006/11/07/planificando-de-forma-agil-2/</guid>
		<description><![CDATA[Después de un breve descanso bloggero (manda narices, después de escribir solo un post ) prosigo con la segunda parte del post sobre planificación ágil. Si no leíste el primer post sobre planificación ágil, te recomiendo encarecidamente que lo leas. Lo puedes consultar aquí. Este post esta totalmente basado en uno de Joel Spolsky, concretamente [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=centuryminds.wordpress.com&amp;blog=20696&amp;post=29&amp;subd=centuryminds&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Después de un breve descanso bloggero (manda narices, después de escribir solo un post <img src='http://s0.wp.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> ) prosigo con la segunda parte del post sobre planificación ágil. Si no leíste el primer post sobre planificación ágil, te recomiendo encarecidamente que lo leas. Lo puedes consultar <a href="http://centuryminds.wordpress.com/2006/10/11/planificando-de-forma-agil-1">aquí</a>.</p>
<p>Este post esta totalmente basado en uno de <a href="http://www.joelonsoftware.com/">Joel Spolsky,</a> concretamente <a href="http://www.joelonsoftware.com/articles/fog0000000245.html">éste;</a> y mi experiencia de haberlo puesto en práctica. Te recomiendo leer no solo ese post, sino cada uno de los posts que tiene en su blog, ¡Son buenísimos!</p>
<p><span style="font-weight:bold;">La solución</span></p>
<p>¿Planificación Ágil? Sí, es lo que tiene el término &#8220;ágil&#8221;, ahora todo lo que tenga que ver con el desarrollo de software tiene que ser ágil: metodologías ágiles, testing ágil, agilidad ágil&#8230; Así que, ¡Qué demonios! Planificación ágil, o como no morir en el intento de planificar un proyecto.</p>
<p>¿Cómo planificamos? Pues de la forma más fácil&#8230;<span style="font-weight:bold;">¡Con Excel! </span>No necesitamos tener ninguna herramienta hipercompleja (leáse Ms Project), no necesitamos pagar miles de euros. Lo único que necesitamos es una mínima organización, y esto lo conseguiremos con Excel y una cierta disciplina.</p>
<p>Eres un fanático del Open Source, un vago y maleante que solo utiliza ese sistema operativo de hackers llamado Linux. ¿ Solo se puede planificar ágilmente con un producto de MS ? ¡No! <span style="font-weight:bold;">Todo lo que cuento se puede realizar perfectamente con Open Office</span>, de hecho tengo dos versiones, una para OO y otra para Excel. La única limitación es que, aunque OO permite tablas pivotadas, no permite gráficas pivotadas. Pero bueno, esto es un poco pijada (o no&#8230;), además supongo que en versiones posteriores de OO incluirán gráficas pivotadas. ¡Así que ya no hay excusa! ¡Arranca tu <a href="http://www.linuxfromscratch.org/">LFS</a> y planifica tus proyectos de forma ágil con OO!</p>
<p><span style="font-weight:bold;">La forma más sencilla de organizar las tareas de un proyecto sería realizar una lista de TO-DOs (Cosas por hacer)</span>, esto lo podemos hacer con un simple fichero de texto, ¡Incluso con papel y boli! (No olvidéis nombrar tan avanzada herramienta la próxima vez que os pregunten en una entrevista que utilizáis para planificar). Aunque una lista de TO-DOs es válido para proyecto pequeños, enseguida vemos que necesitamos &#8220;catalogar&#8221; dichas tareas, repartirlas entre los miembros del equipo, estimar horas, etc. Por tanto, en vez de utilizar un fichero texto conviene utilizar una hoja de cálculo, lo cual nos va a permitir extender nuestro &#8220;modelo de datos&#8221; del planificador.</p>
<p>Partiendo de la idea inicial de usar una lista de tareas podemos extender &#8220;el modelo&#8221; con los siguientes campos:</p>
<ul>
<li><strong>Funcionalidad:</strong> Una funcionalidad es algo visible para el cliente, una historia de usuario si nos ponemos XP-ianos. Una funcionalidad va a estar compuesta de tareas.</li>
<li><strong>Tarea:</strong> Nuestro elemento más básico, un elemento de nuestra primitiva lista de TO-DOs.</li>
<li><strong>Número secuencial</strong>: Útil para referenciar la tarea de forma unívoca. Imagina que tienes una tarea &#8220;Documentación módulo RSP&#8221; y otra &#8220;Documentación módulo SRP&#8221;, ¿Verdad que no querrás que haya una confusión porque alguien creyó leer otra cosa?</li>
<li><strong>Estado: </strong>¿La tarea ha comenzado? ¿Se terminó? Es importante guardar el estado de cada tarea. El estado debe ser catalogado (PENDING, STARTED, DONE) para permitir su filtrado. Si además incluimos un formato condicional (Si &#8220;PENDING&#8221; entonces color rojo) miel sobre hojuelas.</li>
<li> <strong>Criticidad:</strong> ¿Tiene el mismo riesgo poner una imagen en un jsp que la conexión con el backend de nóminas? Seguro que el cliente piensa que cambiar el jsp es más importante, pero esta tarea no tiene ninguna dificultad y la podemos afrontar en cualquier momento. Por tanto asignaremos una criticidad CATALOGADA (LOW, MID, HIGH) a cada tarea. Con esto podremos hacer preguntas tan útiles como: ¿Cuántas tareas críticas están pendientes o sin terminar? Vaya, parece que esto del Excel empieza a dar su juego ehh.</li>
<li><strong>Persona: </strong>Sería fantástico hacer como Juan Palomo: yo me lo guiso, yo me lo como. Pero normalmente tenemos un equipo de proyecto, y por tanto las tareas las realizarán diferentes personas. Por tanto, añadamos una columna que diga quién realizará la tarea x. Este campo también debe ser CATALOGADO. ¿Por qué? ¿Cuántas formas hay de escribir mi nombre? M. Alcón, Miguel Alcón, Mikel Alcón, Mikel Halcon ( Sí, estoy harto de  responder: <em>&#8220;Alcón, sin H</em>&#8220;). En definitiva, si tenemos un catálogo de desarrolladores, únicamente nos permitirá elegir entre los desarrolladores de la lista. Ahora ya podemos hacer unas cuantas preguntas más a nuestro planificador: ¿Cuántas tareas tiene pendientes el desarrollador X? ¿Quién tiene las tareas críticas?, etc.</li>
<li><strong>Estimación original:</strong> ¿Cuánto tiempo estimamos que durará la tarea? Planifica siempre en horas y no asignes más de 30 o 40 horas a una tarea, cuantas menos mejor ¿Por qué? Para obligarte a definir el plan con un nivel alto de detalle. Recuerda que huíamos de las planificaciones del estilo <em>&#8220;Diseño 2 semanas&#8221;</em>. Es más fácil acertar si sabemos exactamente qué vamos a realizar,  en esto consiste realmente la planificación ¿Verdad?</li>
<li><strong>Estimación real:</strong> El que tiene boca se <strike>esquivoca</strike> equivoca, y planificando te equivocarás, y al principio mucho más. Así que actualiza la estimación real a medida que avanza la tarea. Si pensabas que la tarea x iba a durar 10 horas, pero ahora, con el framework Hiberspring AOP Edition 3.0.1.5, lo puedes realizar en 5 horas; o al revés, te has encontrado con un imprevisto, ¡Actualiza la estimación real! Nos permitirá tener una visión real del estado de la tarea.</li>
<li><strong>Tiempo consumido:</strong> ¿Cuántas horas llevas consumidas en la tarea? Este campo nos permitirá preguntas tan interesantes como: ¿Cuanto le queda a esta tarea? (Estimación real &#8211; Tiempo Consumido) ¿Cuánto le queda al proyecto en general? (SUM (Estimación Real) &#8211; SUM (Tiempo Consumido)) ¿Cuántas horas le quedan en tareas asignadas al desarrollador X?</li>
<li><strong>Restante:</strong> Hemos visto que el tiempo que le queda a una tarea es<em> Est. Real &#8211; Tiempo Consumido</em>. Por tanto añadamos una columna con ese valor calculado automáticamente.</li>
<li><strong>Desvío: </strong>Entre la estimación original y la real hay una diferencia.  ¿Cuántas horas más ha costado esta tarea? Precalculemos el valor <em>Estimación real &#8211; Estimación original.</em></li>
<li><strong>Desvio %:</strong> ¿Es lo mismo retrasarse 2 horas en una tarea de 1 hora que en una tarea de 20? No. Pues entonces precalculemos este valor: <em>Estimación real / Estimación original </em>y lo pondremos en formato porcentual:
<ul>
<li>100 % : Estimación Real = Estimación Original. Perfecto</li>
<li>&lt;100 %: ¡Hemos tardado menos! Cliente contento y nosotros planificaremos de forma más precisa la próxima vez.</li>
<li>&gt;100% : Empiezan los problemas, ¿La tarea es crítica? ¿Quién la tiene asignada? Utilizaremos el formato condicional para asignarles colores de fondo dependiendo del desvío (Ej.: Amarillo 101% a 105%, Naranja 105% a 115%, Rojo &gt;115%)</li>
</ul>
</li>
</ul>
<p>Ahora ya podemos saber cuáles son las tareas que más retrasos están produciendo, tanto en niveles absolutos como porcentuales, sabemos cuáles son los desarrolladores que más se están retrasando, cuánto tiempo le queda al proyecto, etc. En definitiva, tenemos controlado el proyecto.</p>
<p align="left"> La cosa podría quedar más o menos así:</p>
<p><a href="http://centuryminds.files.wordpress.com/2006/11/planificacion.jpg" title="planificacion"><img src="http://centuryminds.files.wordpress.com/2006/11/planificacion.jpg?w=450" alt="planificacion" /></a></p>
<p>Como habrás podido comprobar la mayoría de los campos son catalogados. Esto nos permitirá realizar agrupaciones y filtrados de los datos.</p>
<p>¿Se pueden hacer cosas  más complejas ? Sí, poniendo fechas de inicio y de fin, tareas bloqueantes, etc. Lo único que tienes que tener en cuenta es que deberás utilizar macros de Excel, no pongas este tipo de campos para ser modificados manualmente, porque conseguirás que te dé pereza actualizar la planificación.<span style="font-weight:bold;"> Lo campos a rellenar deben ser los mínimos y que no requieran pensar más que en la planificación</span>. Nada de &#8220;en qué fecha me pongo si la tarea dura 30 días y hay un fin de semana de por medio&#8221;. O utilizas una macro o no utilices estas fechas. Además para la mayoría de proyectos este tipo de fechas no te van a servir para nada. Tu objeto de medida es <em>horas que quedan de desarrollo</em>.</p>
<p>Tampoco hay que emocionarse y empezar a añadir campos a diestro y siniestro. Añade según necesites. De la misma forma, solo añade métricas calculadas que realmente te sean útiles, no añadas algo del estilo <em>(Estimación Original &#8211; Estimación Real)*Número de letras del nombre del desarrollador/ PI. </em>Recuerda, puedes ir evolucionando el &#8220;modelo de datos&#8221; según lo necesites.</p>
<p>Una vez que tenemos la parte técnica resuelta queda la parte metodológica&#8230; ¿Cómo coño usamos esto!? Las directrices a seguir serían éstas:</p>
<ul>
<li> Que <span style="font-weight:bold;">los desarrolladores que van a realizar las tareas sean los que, generalmente, hagan la estimación original.</span> ¿Por qué? Por dos motivos, el primero que nadie sabe mejor cuanto va a costar hacer un trabajo que la propia persona que va a hacerlo. El segundo motivo es más psicológico: <strong>para que la persona asignada se responsabilice de su tarea.</strong> Nunca te podrá decir algo como ¡Me diste poco tiempo!.</li>
<li><span style="font-weight:bold;">Cada mañana actualiza la planificación</span>. Tu protocolo a seguir cada mañana debería ser el siguiente:
<ul>
<li>Café (Imprescindible, sustituible por té, colacaos, infusiones y bebidas calientes varias. Podrá ser acompañado de galletas, donuts o cualquier artículo de bollería industrial)</li>
<li><strong>Reunión con los miembros del equipo,</strong> de la siguiente forma:
<ul>
<li> <span style="font-weight:bold;">¡DE PIE!</span> ¿Por qué ? Las reuniones de pie tienden a ir a lo concreto, nadie aguanta mucho sin asentar las posaderas. Si no me crees,  compruébalo quedándote de pie 2 horas seguidas, es una experiencia única.</li>
<li><strong>Con pizarra. </strong>Ayuda a exponer lo que tenemos en mente sin perder el tiempo ni hacérselo perder a los demás. Todo queda más gráfico con un dibujo y minimiza el esfuerzo del resto del equipo para comprendernos.</li>
<li>Cada miembro expone el estado de sus tareas y las modificaciones a la planificación (Estimación real y consumido). El jefe de proyecto actualiza la planificación.</li>
<li>Se asignan nuevas tareas</li>
<li>¿Dudas? ¿Bloqueos entre tareas? Se comentan y se anotan en la hoja Excel.</li>
</ul>
</li>
<li><strong>El jefe de proyecto actualiza la  hoja Excel y recalcula las métricas</strong>.</li>
<li><strong>Consultar las métricas</strong> para ver el estado del proyecto, si no es periódicamente por lo menos hacerlo regularmente.</li>
</ul>
</li>
<li>Repito, <strong>planifica a nivel de horas</strong>, no caigas en la tentación de hacer planificaciones a nivel de días, semanas o incluso peor, meses. Perderás el control del proyecto y te estarás autoengañando.</li>
<li><strong>Evita los bloqueos entre tareas</strong>. No querrás tener desarrolladores parados porque la tarea x no ha terminado, ¿Verdad?</li>
<li><strong>Evita que los recursos compartidos se conviertan en elementos bloqueantes:</strong>
<ul>
<li>¿La BD, que usa todo el equipo, se ha caído? ¿Alguien ha cambiado el modelo y  los demás no tienen dichos cambios? Seguro que te suena este tipo de problemas. <strong>Pon una BD para cada desarrollador</strong>, si no puedes permitírtelo crea protocolos que eviten o minimicen estos problemas.</li>
<li><strong>Cada desarrollador debe poder ejecutar el código en su propia máquina</strong> (Sea un exe, un aplicación web con Apache o con un servidor de aplicaciones por cada desarrollador).  No hay excusas, el coste es ridículo.</li>
<li><strong>¡Usa control de versiones!</strong> Lo mismo, no hay excusas. <strong>Y que nadie, absolutamente nadie suba algo al repositorio sin haber probado tanto sus cambios como la integración con el resto.</strong></li>
<li>Relacionado con lo anterior. <strong>Genera pruebas unitarias</strong>, de regresión, validación, integración etc. Que puedan ejecutarse de manera automática. Imprescindible. Si lo unimos con el punto anterior tenemos que: Nadie, absolutamente nadie, suba algo en el repositorio sin que las pruebas pasen correctamente. He visto equipos de más de cinco personas paradas porque la versión en el SCM tenía un fallo bloqueante.</li>
</ul>
</li>
<li><strong>Evita los bloqueos dentro de tareas</strong>: Este es la principal fuente de retrasos en los proyectos (Además de los proyectos mal planificados, of course). Programadores que se quedan atascados durante horas con un problema. Haz ver a los miembros del equipo que no están solos en su cruzada, si alguien se bloquea durante más de 15 minutos con un problema <strong>¡Que solicite ayuda a alguien del equipo! </strong>Tampoco es cuestión de que el equipo entero se ponga a buscar durante dos horas el carácter &#8220;&lt;&#8221; que falta en un html, pero generalmente alguien conoce la solución porque ya se enfrentó con ella antes. Eso sí, con un límite, no es cuestión de que la misma persona esté ayudando todo el rato a los demás, dejando su trabajo de lado, o de que se pase dos días intentando solucionar el problema de otro.</li>
<li><strong>Añade una  tarea &#8220;debug&#8221;,</strong> que sirva de colchón ante imprevistos. Al final del proyecto haz la resta <em>Estimación Original Debug &#8211; Desviación Horas Total</em>  <em>Proyecto</em>, te ayudará a dar un tamaño correcto a la tarea colchón en siguientes proyectos. ¿Qué tamaño debe tener? Debería tener, al menos inicialmente, un tamaño no menor al 50% de horas del proyecto.</li>
<li>Utiliza las tablas pivotadas para calcular totales y subtotales (Total de horas por desarrollador, total de horas por tarea,etc.). Usa las gráficas pivotadas: de un vistazo podrás ver el estado del proyecto.</li>
</ul>
<p>Espero que estos consejos os permitan planificar mejor (o simplemente planificar). Lee el artículo de Joel, es mucho más completo. Además, yo intento escribir con gracia, pero solo él lo consigue <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>Queda pendiente de subir un fichero Excel de ejemplo como adjunto. Dada mi nulidad<span style="font-style:italic;"> blogeril, </span>tendré que investigar cómo hacerlo.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/centuryminds.wordpress.com/29/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/centuryminds.wordpress.com/29/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/centuryminds.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/centuryminds.wordpress.com/29/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/centuryminds.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/centuryminds.wordpress.com/29/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/centuryminds.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/centuryminds.wordpress.com/29/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/centuryminds.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/centuryminds.wordpress.com/29/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/centuryminds.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/centuryminds.wordpress.com/29/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/centuryminds.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/centuryminds.wordpress.com/29/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/centuryminds.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/centuryminds.wordpress.com/29/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=centuryminds.wordpress.com&amp;blog=20696&amp;post=29&amp;subd=centuryminds&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://centuryminds.wordpress.com/2006/11/07/planificando-de-forma-agil-2/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/84ec0ae167726c1eba48457abcd6b3ee?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">activez</media:title>
		</media:content>

		<media:content url="http://centuryminds.files.wordpress.com/2006/11/planificacion.jpg" medium="image">
			<media:title type="html">planificacion</media:title>
		</media:content>
	</item>
		<item>
		<title>JavaTM EE (J2EE) Programming (with Passion!)</title>
		<link>http://centuryminds.wordpress.com/2006/10/24/javatm-ee-j2ee-programming-with-passion/</link>
		<comments>http://centuryminds.wordpress.com/2006/10/24/javatm-ee-j2ee-programming-with-passion/#comments</comments>
		<pubDate>Tue, 24 Oct 2006 17:30:31 +0000</pubDate>
		<dc:creator>Rubén Barroso</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://centuryminds.wordpress.com/2006/10/24/javatm-ee-j2ee-programming-with-passion/</guid>
		<description><![CDATA[He comenzado este curso online de JavaEE, del koreano Sang Shin. Le vi en un par de presentaciones en la Java One en Madrid este año. La verdad que el tipo es impresionante dando presentaciones. Genial. Con respecto al curso, no puede recomendarlo, porque ha comenzado esta semana, así que si aún no te has [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=centuryminds.wordpress.com&amp;blog=20696&amp;post=28&amp;subd=centuryminds&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p align="justify">He comenzado este <a href="http://www.javapassion.com/j2ee/" title="JavaTM EE (J2EE) Programming (with Passion!)" target="_blank">curso online</a> de JavaEE, del koreano Sang Shin. Le vi en un par de presentaciones en la Java One en Madrid este año. La verdad que el tipo es impresionante dando presentaciones. Genial.</p>
<p align="justify">Con respecto al curso, no puede recomendarlo, porque ha comenzado esta semana, así que si aún no te has apuntado, estás a tiempo. Sólo te exige 2-4 horas como mucho a la semana. Nada como volver con aquello que crees saber para descubrir nuevas cosas y afianzar conocimientos.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/centuryminds.wordpress.com/28/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/centuryminds.wordpress.com/28/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/centuryminds.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/centuryminds.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/centuryminds.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/centuryminds.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/centuryminds.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/centuryminds.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/centuryminds.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/centuryminds.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/centuryminds.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/centuryminds.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/centuryminds.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/centuryminds.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/centuryminds.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/centuryminds.wordpress.com/28/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=centuryminds.wordpress.com&amp;blog=20696&amp;post=28&amp;subd=centuryminds&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://centuryminds.wordpress.com/2006/10/24/javatm-ee-j2ee-programming-with-passion/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b677956a8f95bbb95d02b5775eca6d15?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">centuryminds</media:title>
		</media:content>
	</item>
		<item>
		<title>Exceptions y JDK 1.3</title>
		<link>http://centuryminds.wordpress.com/2006/10/11/exceptions-y-jdk-13/</link>
		<comments>http://centuryminds.wordpress.com/2006/10/11/exceptions-y-jdk-13/#comments</comments>
		<pubDate>Wed, 11 Oct 2006 18:44:09 +0000</pubDate>
		<dc:creator>Rubén Barroso</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://centuryminds.wordpress.com/2006/10/11/exceptions-y-jdk-13/</guid>
		<description><![CDATA[Yo soy el primero al que le encantaría el poder utilizar las características de la versión 1.5 de Java, en concreto encuentro muy útiles los static imports y los generics, y por supuesto las annotations. Sin embargo, durante mi carrera, y por diversas razones, me he encontrado en situaciones de no poder utilizar siquiera la [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=centuryminds.wordpress.com&amp;blog=20696&amp;post=26&amp;subd=centuryminds&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Yo soy el primero al que le encantaría el poder utilizar las características de la versión 1.5 de Java, en concreto encuentro muy útiles los <em>static imports</em> y los <em>generics</em>, y por supuesto las <em>annotations</em>. Sin embargo, durante mi carrera, y por diversas razones, me he encontrado en situaciones de no poder utilizar siquiera la versión 1.4 del JDK. Es triste, pero cierto, y me temo que es muy habitual encontrarse con la restricción tan temida de: &#8220;<em>Tenemos que programar contra el JDK 1.3</em>&#8220;. Es algo así como una especie de maldición, cuando estás habituado a utilizar los métodos de la clase String añadidos a partir de la versión 1.4 -<code>replaceAll()</code>, <code>split()</code>, etc-, o la facilidad de la <a href="http://java.sun.com/j2se/1.4.2/docs/guide/lang/chained-exceptions.html" title="Chained Exceptions" target="_blank"><em>exception chaining</em></a>. Por fortuna, el proyecto <a href="http://jakarta.apache.org/commons/" title="Jakarta Commons" target="_blank">Commons</a> de la fundación Apache puede ayudarnos a solventar algunos de esos obstáculos. Vayamos con la <em>exception chaining</em>. Esta es la interfaz de la clase <code>java.lang.RuntimeException</code>* en la versión 1.4:</p>
<pre>public RuntimeException()</pre>
<pre>public RuntimeException(String message)</pre>
<pre>public RuntimeException(String message, Throwable cause)</pre>
<pre>public RuntimeException(Throwable cause)</pre>
<p>Como se puede observar, dos de los constructores de esta clase admiten un argumento <code>java.lang.Throwable</code>, por tanto cuando usemos esta clase en la versión 1.4 no perderemos la traza de llamadas de las excepciones. Ahora veamos las signaturas de los constructores de esta misma clase en la versión 1.3:</p>
<pre>public RuntimeException()</pre>
<pre>public RuntimeException(String message)</pre>
<p>Ahora ya sabemos que la exception chaining fue un añadido a la versión 1.4 del JDK a la clase <code>RuntimeException</code>. En el subproyecto <a href="http://jakarta.apache.org/commons/lang/" title="Commons Lang" target="_blank">Commons Lang</a> existe una jerarquía de clases que nos ayudan a establecer una pila de llamadas previa en el constructor de una excepción. En concreto, son las clases <code>NestableRuntimeException</code> y <code>NestableException</code> del paquete <code>org.apache.commons.lang.exception</code>:</p>
<p><a href="https://centuryminds.files.wordpress.com/2006/10/runtimeexceptions.png" title="Jakarta Commons Exception Hierarchy"></a></p>
<p style="text-align:center;"><a href="https://centuryminds.files.wordpress.com/2006/10/runtimeexceptions.png" title="Jakarta Commons Exception Hierarchy"><img src="https://centuryminds.files.wordpress.com/2006/10/runtimeexceptions.png?w=450" alt="Jakarta Commons Exception Hierarchy" /></a></p>
<p>Estos son los constructores de la clase <code>NestableRuntimeException</code>:</p>
<pre>public NestableRuntimeException()</pre>
<pre>public NestableRuntimeException(String message)</pre>
<pre>public NestableRuntimeException(String message, Throwable cause)</pre>
<pre>public NestableRuntimeException(Throwable cause)</pre>
<p>Equivalentes a los de la clase <code>RuntimeException</code>, de forma que funciona como tal y además mantiene una referencia a un objeto <code>Throwable</code>, con lo que simulamos la funcionalidad añadida a la versión 1.4 pero en un entorno compilado para la 1.3. Ahora simplemente podremos definir nuestras propias subclases de <code>NestableRuntimeException</code> o <code>NestableException</code>, sin miedo a que obtengamos errores de compilación debido al overriding de los constructores no existentes en la 1.3, pero sí en la 1.4. Ahora que lo digo, yo he sufrido dichos errores debido a que en mi IDE (Eclipse normalmente) no configuro el proyecto para compilar las fuentes contra la 1.3 (cuando ha de desplegarse en un entorno de JDK 1.3, claro). Aunque ya voy aprendiendo. Considero siempre una buena práctica configurar el entorno de desarrollo a semejanza del entorno destino, en la medida de lo posible.</p>
<p><em>* También se aplica a la clase java.lang.Exception</em></p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/centuryminds.wordpress.com/26/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/centuryminds.wordpress.com/26/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/centuryminds.wordpress.com/26/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/centuryminds.wordpress.com/26/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/centuryminds.wordpress.com/26/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/centuryminds.wordpress.com/26/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/centuryminds.wordpress.com/26/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/centuryminds.wordpress.com/26/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/centuryminds.wordpress.com/26/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/centuryminds.wordpress.com/26/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/centuryminds.wordpress.com/26/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/centuryminds.wordpress.com/26/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/centuryminds.wordpress.com/26/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/centuryminds.wordpress.com/26/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/centuryminds.wordpress.com/26/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/centuryminds.wordpress.com/26/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=centuryminds.wordpress.com&amp;blog=20696&amp;post=26&amp;subd=centuryminds&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://centuryminds.wordpress.com/2006/10/11/exceptions-y-jdk-13/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b677956a8f95bbb95d02b5775eca6d15?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">centuryminds</media:title>
		</media:content>

		<media:content url="https://centuryminds.files.wordpress.com/2006/10/runtimeexceptions.png" medium="image">
			<media:title type="html">Jakarta Commons Exception Hierarchy</media:title>
		</media:content>
	</item>
		<item>
		<title>Planificando de forma Ágil (1)</title>
		<link>http://centuryminds.wordpress.com/2006/10/11/planificando-de-forma-agil-1/</link>
		<comments>http://centuryminds.wordpress.com/2006/10/11/planificando-de-forma-agil-1/#comments</comments>
		<pubDate>Wed, 11 Oct 2006 11:03:59 +0000</pubDate>
		<dc:creator>Mikel Alcón</dc:creator>
				<category><![CDATA[business]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Software Engineering]]></category>

		<guid isPermaLink="false">http://centuryminds.wordpress.com/2006/10/11/planificando-de-forma-agil-1/</guid>
		<description><![CDATA[El problema En una de las entrevistas de trabajo que hice hace tiempo me preguntaron que herramienta usaba para diseñar. Yo, ni corto ni perezoso, le respondí: Papel y boli. El entrevistador pareció sorprendido, quizás esperaba una respuesta del tipo &#8220;Uso Rational Rose junto con Together más {ponga aquí su herramienta favorita}&#8221;. Seguro que estas [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=centuryminds.wordpress.com&amp;blog=20696&amp;post=25&amp;subd=centuryminds&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><strong>El problema </strong></p>
<p>En una de las entrevistas de trabajo que hice hace tiempo  me preguntaron que herramienta usaba para diseñar. Yo, ni corto ni perezoso, le respondí: Papel y boli. El entrevistador pareció sorprendido, quizás esperaba una respuesta del tipo <em>&#8220;Uso Rational Rose junto con Together más {ponga aquí su herramienta favorita}&#8221;.</em> Seguro que estas herramientas son muy útiles, de hecho yo las he utilizado más de una vez, pero creo que en este mundillo hay una sobrevaloración de las herramientas frente a las personas. Parece que es más importante saber utilizar el Rational Rose que saber hacer buenos diseños.</p>
<p>¿Y por qué cuento todo esto?  Porque en el terreno de las planificaciones de software hay una herramienta, de esas &#8220;imprescindibles&#8221;, llamada MS Project que todo Jefe de Proyecto &#8220;debe&#8221; de conocer. Se usa para todo: Las ofertas llevan un project asociado, una vez iniciado el proyecto el jefe del proyecto se hace otro project, a su vez este pide a sus desarrolladores un project. ¡Y ya tenemos el belén montado! Nadie actualizará esas planificaciones en la vida, su único objetivo era el de aparecer en un papel para justificar que la entrega es sí o sí para el día X.</p>
<p>Las planificaciones con Project nacen viciadas desde su origen. Primero nos ponen una fecha y nosotros hacemos el paripé para calzar todo lo que tenemos que hacer en esa planificación.</p>
<p>Me encantan esas planificaciones del tipo:</p>
<ol>
<li> Análisis (2 meses) (Consultor Pepito)</li>
<li>Diseño (4 meses) (Analista de 2ª Juanito)</li>
<li>Desarrollo (4 meses)
<ol>
<li>Web (2 meses)
<ol>
<li>Gestión de usuarios (2 semanas) (Programador Menganito)</li>
<li>Portal de acceso al empleado (2 semanas) (Becario Fulanito)</li>
<li>Procesos de backend (1 mes) (¿Adivinan? ¡Fulanito y Menganito!)</li>
<li>etc.</li>
</ol>
</li>
</ol>
</li>
<li>etc.</li>
</ol>
<p>¡Que bien!, nuestra planificación está lista y milagrosamente cumple los plazos acordados con el cliente (O aquella moto que vendió el comercial de turno tomándose unas cañas plácidamente con el cliente).</p>
<p>Pero analicemos detalladamente esta planificación:</p>
<ul>
<li><strong>Nace viciada de origen. </strong>Nuestro único objetivo fue cumplir los plazos, por eso utilizamos una herramienta basada principalmente en fechas (Gantt).</li>
<li><strong>No está basada en criterios racionales</strong>:  ¿En que nos basamos para planificar los procesos de Backend en un mes? ¿Hemos tenido una revelación divina? ¿Rappel está en nuestro equipo de proyecto? Este tipo de planificaciones me recuerda a un tipo de mi barrio, un poco raro, que decía que iba a hacer un software de diseño de circuitos que iba a ocupar&#8230;¡ 14 diskettes! ¡Y no sabía programar! La diferencia entre esta persona y nosotros es que, nosotros no vemos una media de 5 ovnis al día cuando tomamos el café en la terraza, ni creemos en puertas interestelares (¿No dije que era un tipo raro!!??). Y por tanto debemos ser más serios con lo que hacemos.</li>
<li><strong>No es detallada:</strong> Por la causa anterior. Una planificación no se debe hacer nunca a semanas, ¡ Y menos a meses! Hacer una planificación no detallada es como decirle al cliente <em>&#8220;Mira, no tengo ni idea de cuanto vamos a tardar, pero te voy a mentir para que te quedes más tranquilo.  El proyecto ya se retrasará luego, como todos&#8221;</em> (¡Lo peor es que con muchos clientes funciona!).</li>
<li> <strong>Es una referencia/restricción, no una herramienta: </strong>Una vez hecho, rara vez se actualizará (siendo muy optimistas). Solo servirá como herramienta de presión para los integrantes del equipo (esto daría para otro post). ¿Cual es el estado del proyecto? ¿Cuanto falta para acabar? ¿Que desarrollador tiene más carga de trabajo? Nuestro project no nos responderá a ninguna de estas preguntas. No está actualizado y esta lleno de suposiciones (benditos eufemismos). Vaya paradoja, ¡La herramienta de planificación no nos sirve para planificar!</li>
<li><strong>No tenemos soporte para feedback:</strong> Al planificar nos vamos a confundir. Seguro. No existen las planificaciones que encajan como anillo al dedo. Solo podemos minimizar el desvío. ¿Crees que puedes hacer una planificación para el año que viene  el mismo día a la misma hora? Cuando planificamos a grandes escalas de tiempo es inevitable confundirse. Influyen muchos motivos: No conocemos bien los requisitos, la tecnología es nueva, etc. Aunque en los siguientes proyectos no podremos presagiar muchos de los problemas que encontraremos, si que podemos prever ciertos desvíos. Por ello es importante almacenar las horas que realmente se imputaron a cada tarea. Debemos aprender de nuestros errores.</li>
</ul>
<p>Entonces, ¿No vale para nada el MS Project? ¿Hay que huir de ellos como el demonio? Yo no llegaría a tanto, simplemente hay que tener en cuenta sus limitaciones y las implicaciones que tiene. En ciertos proyectos grandes, con muchas dependencias, puede estar justificado su uso. Pero para proyectos pequeños y medianos existen mejores herramientas. ¡Pero esto lo dejo para el siguiente post!</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/centuryminds.wordpress.com/25/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/centuryminds.wordpress.com/25/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/centuryminds.wordpress.com/25/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/centuryminds.wordpress.com/25/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/centuryminds.wordpress.com/25/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/centuryminds.wordpress.com/25/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/centuryminds.wordpress.com/25/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/centuryminds.wordpress.com/25/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/centuryminds.wordpress.com/25/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/centuryminds.wordpress.com/25/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/centuryminds.wordpress.com/25/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/centuryminds.wordpress.com/25/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/centuryminds.wordpress.com/25/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/centuryminds.wordpress.com/25/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/centuryminds.wordpress.com/25/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/centuryminds.wordpress.com/25/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=centuryminds.wordpress.com&amp;blog=20696&amp;post=25&amp;subd=centuryminds&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://centuryminds.wordpress.com/2006/10/11/planificando-de-forma-agil-1/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/84ec0ae167726c1eba48457abcd6b3ee?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">activez</media:title>
		</media:content>
	</item>
		<item>
		<title>¡Bienvenidos!</title>
		<link>http://centuryminds.wordpress.com/2006/10/10/%c2%a1bienvenidos/</link>
		<comments>http://centuryminds.wordpress.com/2006/10/10/%c2%a1bienvenidos/#comments</comments>
		<pubDate>Tue, 10 Oct 2006 22:04:03 +0000</pubDate>
		<dc:creator>Rubén Barroso</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Software Engineering]]></category>

		<guid isPermaLink="false">http://centuryminds.wordpress.com/2006/10/10/%c2%a1bienvenidos/</guid>
		<description><![CDATA[Mi buen amigo Mikel se ha animado a colaborar compartiendo en este blog sus conocimientos y experiencias en este mundo del desarrollo de software. ¡Me siento muy afortunado de tenerte por aquí! Además, y después de estar detrás de él durante una temporada para que abra un blog, otro amigo mío, Colin, se ha decidido [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=centuryminds.wordpress.com&amp;blog=20696&amp;post=24&amp;subd=centuryminds&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Mi buen amigo Mikel se ha animado a colaborar compartiendo en este blog sus conocimientos y experiencias en este mundo del desarrollo de software. ¡Me siento muy afortunado de tenerte por aquí! Además, y después de estar detrás de él durante una temporada para que abra un blog, otro amigo mío, <a href="http://blog.colinfleming.net" title="Random mumblings">Colin</a>, se ha decidido finalmente y ya he podido disfrutar de su <a href="http://blog.colinfleming.net/2006/10/10/exception-handling-101/" title="Exception Handling 101">primer post</a>. Excelente. Por cierto, el diseño del site muy chulo. ¡Calidad desde Nueva Zelanda!</p>
<p>Para acabar, como reza el título de este post &#8230; ¡Bienvenidos!</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/centuryminds.wordpress.com/24/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/centuryminds.wordpress.com/24/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/centuryminds.wordpress.com/24/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/centuryminds.wordpress.com/24/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/centuryminds.wordpress.com/24/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/centuryminds.wordpress.com/24/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/centuryminds.wordpress.com/24/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/centuryminds.wordpress.com/24/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/centuryminds.wordpress.com/24/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/centuryminds.wordpress.com/24/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/centuryminds.wordpress.com/24/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/centuryminds.wordpress.com/24/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/centuryminds.wordpress.com/24/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/centuryminds.wordpress.com/24/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/centuryminds.wordpress.com/24/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/centuryminds.wordpress.com/24/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=centuryminds.wordpress.com&amp;blog=20696&amp;post=24&amp;subd=centuryminds&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://centuryminds.wordpress.com/2006/10/10/%c2%a1bienvenidos/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b677956a8f95bbb95d02b5775eca6d15?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">centuryminds</media:title>
		</media:content>
	</item>
	</channel>
</rss>
