-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hola a todos,
Me gustar�a plantear algunas cuestiones sobre las presunciones habituales en
desarrollos Java.
Es curioso constatar que una de las primeras lecciones que aprende un
desarrollador de C, al enfrentarse con un proyecto en Java, es que lo
equivalente en Java a un "core" de C (una referencia a un lugar de la memoria
que no existe o es inv�lido), es una excepci�n del tipo NullPointerException.
No s�lo aprende eso, sino tambi�n a la poca trascendencia que se le da en
Java, en contraste con la gravedad cuando se trata de C.
Lamentablemente, no s�lo aprender� eso. Asumir� que no hay que preocuparse por
punteros, por gestionar la memoria, por memory leaks, y en general se
acostumbrar� a no dar importancia a nada que no sea los requisitos
funcionales. En este punto su c�digo ser� en cierta medida indistinguible de
un desarrollador que haya comenzado por Java directamente.
Una vez su grado de conformismo sea el adecuado, ser� capaz de escribir c�digo
como el siguiente (normalmente ser� en castellano, y por supuesto sin
javadoc):
public String buildEmailKey()
{
return
"" + Calendar.getInstance().getTime().getTime() +
ConfigurationManager.getInstance().getProperty("user.email").trim().length();
}
Y �se c�digo ser� aceptado como v�lido, hasta que por error no se especifique
la propiedad user.email. Si eso ocurriera, aparecer�a un
NullPointerException. En este punto, lo normal es que se "solucionara" el
error a�adiendo dicha propiedad, sin mayor an�lisis.
Sin embargo, si dicho fallo se produjera una vez el c�digo est� en producci�n,
se har�a la deducci�n: NullPointerException -> stack trace -> class -> Nombre
del desarrollador cuyo c�digo "no funciona".
El desarrollador es considerado a partir de ese momento el responsable de
ofrecer una soluci�n al problema. Independientemente de si la propiedad haya
sido omitida por descuido o decisi�n de otro, �l es el que debe constatar ese
hecho. El responsable real de dicha omisi�n no consciente de la misma hasta
que alguien le indica la existencia del error. En el caso peor, dicho
responsable lo arregla y figura como la persona que solucion� el problema. En
el caso mejor eso no es representativo.
Ese mismo desarrollador, que se fi� cuando le dijeron que podr�a suponer que
siempre dispondr�a de la propiedad "user.email", podr�a dejar de ser tan
confiado. Podr�a incluso modificar el c�digo para soportar las poco probables
situaciones en las que los supuestos impl�citos en su c�digo no se cumplan:
public String buildEmailKey()
{
String result = null;
String email =
ConfigurationManager.getInstance().getProperty("user.email");
if (email == null)
{
System.err.println("Fatal error: missing 'user.email' property");
}
else
{
"" + Calendar.getInstance().getTime().getTime() +
email.trim().length();
}
return result;
}
Ahora su c�digo ya es m�s robusto: si vuelve a ocurrir el mismo problema, no
s�lo no incurrir� en un error en ejecuci�n, sino que adem�s es capaz de guiar
en la soluci�n del mismo, escribiendo un mensaje que podr� ser inspeccionado.
Llega el momento en que se decide migrar de tecnolog�a. Supuestamente, es un
cambio que implica un riesgo muy bajo para su c�digo. Internamente, sabe que
ConfigurationManager es ahora un ejb de sesi�n o un MBean , o lo que sea,
pero le han garantizado que no le afectar� en nada.
Se desplega el c�digo en producci�n y eventualmente vuelve a aparecer la misma
excepci�n (antes carente de importancia): NullPointerException, en su c�digo.
Inspeccionando, ve que es la llamada a
ConfigurationManager.getInstance().getProperty("user.email"). Resulta que
ConfigurationManager.getInstance() devuelve un valor nulo. Sigue
inspeccionando, y ve que es consecuencia de una RemoteException que a su vez
escribe una traza en alg�na parte para indicar el error, pero que ha pasado
desapercibida.
Una vez m�s, ha ocurrido la misma situaci�n. Avisa al responsable de la clase
ConfigurationManager, pero decide asimismo volcer a cambiar el c�digo para
tener en cuenta estas situaciones:
public String buildEmailKey()
{
String result = null;
ConfigurationManager configurationManager =
ConfigurationManager.getInstance();
if (configurationManager == null)
{
System.err.println("Fatal error: ConfigurationManager not available");
}
else
{
String email =
configurationManager.getProperty("user.email");
if (email == null)
{
System.err.println("Fatal error: missing 'user.email' property");
}
else
{
result =
"" + Calendar.getInstance().getTime().getTime() +
email.trim().length();
}
}
return result;
}
Incluso duda de si defenderse contra la llamada a Calendar.getInstance().
Decide que no, pero no las tiene todas consigo.
Finalmente, su c�digo ahora incluye muchas m�s comprobaciones y acaba mucho
m�s indentado. Adem�s, plasma claramente la necesidad de un modo m�s l�gico
de representar y gestionar las situaciones inesperadas, en lugar de escribir
trazas.
Para permitir la legibilidad y simplicidad del c�digo "optimista" inicial, sin
sacrificar la robustez del c�digo "pesimista" final, se puede intentar a�adir
al lenguage caracter�sticas propias de lenguages con soporte para dise�o por
contrato, como Eiffel. He encontrado unas referencias de proyectos
relacionados:
http://csd.informatik.uni-oldenburg.de/~jass/
http://www.cs.iastate.edu/~leavens/JML/index.shtml
http://www.reliable-systems.com/tools/iContract/iContract.htm
Por diversas cuestiones, estoy implementando mi propia herramienta, que me
permita definir las precondiciones en tags javadoc. Dicha herramienta es
simple: un doclet que obtiene los nombres y tipos de los par�metros de cada
m�todo, y construye un aspecto que comprueba las condiciones especificadas en
tags @requires. Todo ello, recubierto en una tarea Ant que sustituye a
<javac>. Una de las bondades de este enfoque es que AspectJ me permite lanzar
una excepci�n en el c�digo del llamante, no en el del llamado, con lo cual se
clarifica qui�n incurre en la violaci�n del contrato (en el stack trace no
aparece el c�digo llamado).
Hasta ahora, las condiciones sobre los valores de los par�metros est�n
implementadas. Me surgen distintas cuestiones: por un lado, c�mo implementar
otras condiciones de contorno, como puede ser el requisito de que la
instancia devuelta por ConfigurationManager.getInstance() anterior no sea
nula; por otro, c�mo gestionar las violaciones de contrato, si con una
excepci�n por defecto, o una excepci�n personalizada, un assert, etc.
Agradecer�a vuestra opini�n.
Un saludo,
Jose.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (GNU/Linux)
iD8DBQE/6DBNCAvt6RF8M0cRAhR3AJ9vNj92Vfl06ZYQC8fnpM5cpS00RQCgmT1g
j4Lie0Yz1RqTAUsSNDNzVmI=
=NAqR
-----END PGP SIGNATURE-----
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]