jueves, mayo 10, 2012

MVC en Java - Model View Controller - Modelo Vista Controlador

Bueno, un tema complicado para escribir ya que se ha escrito demasiado, sobre algo que a mi parecer no tendría mucha relevancia, bueno sí, pero personalmente prefiero otras estructuras de organización de software. En fin, uno de mis amigos, me ha pedido que explique este Patrón de Diseño. Y que por su fama, y buen marketing  de software ha dado origen a otros patrones como el MVP (Model View Presenter)  y todos los model +view +something, Observer, etc. Además, este tópico, ha dado origen a las discusiones de café más apasionadas sobre los patrones de diseño de software y su utilidad real en el desarrollo actual.
Recuerdo haber leído algunos libros y ver representaciones del MVC, pero todos ellos mostraban en sus clases de la capa vista, una referencia a alguna clase de la capa modelo, o viceversa. Pero… y entonces…. tengo una duda; no era que el MVC era una “¿programación en 3 capas?”, y si hablamos de capas, por que existen referencias cruzadas.  Bueno, después de exhaustivos y apasionales debates sobre si el modelo debía considerarse una capa transversal a toda la arquitectura (y algunos otros argumentos más alocados), descubrimos, que el MVC  no fue igual toda la vida (es más hasta el día de hoy encuentro tantos MVC como arquitectos). Pero no todo es tan relativo, se mantiene algunos principios de responsabilidad de las capas.
Inicialmente y a grande rasgos, podemos decir que existen dos formas de MVC. Y la diferencia básica entre el primero y el segundo, es que en el primero (versión inicial), no se tiene una variable de referencia a alguna clase del “Modelo” en la capa de la vista, como mencione anteriormente.
Realizaré la presentacion en dos post, el primero, será el MVC inicial y el segundo el que tome en cuenta las relaciones entre el modelo, y la vista, y por que evoluciono de esta forma.

MVC + V1

La comunicación de cada capa con la inmediata superior, es lo que llevó a mucha gente a llamar a esto “programación en tres capas”. Como se distingue en las relaciones del diagrama, no existe una comunicación directa entre el modelo, y la vista.  Las referencias a interfaces y no directamente hacia las clases, nos permitirán un crecimiento por agregación (crear una clase y agregarla a nuestro software) y no por modificación. Así por ejemplo si en lugar de instanciar en el controlador un JFrame, instanciaramos un JInternalFrame, solo tendríamos que crear un Internal Frame e implementar la interfaz, sin tener que modificar el controlador mas que para cambiar la referencia.  En esta forma de orgenizar el código, solo se utilizan “objetos del lenguaje” (Map), y no "objetos del modelo" (Persona), y es esta característica, la que le dá la pureza de la separación entre capas.

El codigo fuente Java de esta Ejemplo se puede encontrar aquí!

Algunas consideraciones

Como vemos cada una de las clases tienen una referencia a una interfáz, y no a una clases concreta. También se lo puede hacer con clases abstractas, pero debido a la posibilidad de herencia múltiple de interfaces (Una interfaz puede heredar varias interfaces) e implementación múltiple que tienen las clases (Una clase puede implementar varias interfaces), en Java, nos conviene utilizarlo de esta forma para ganar en flexibilidad para agregar y sacar métodos

  ...
  private IControlable controler; 
  public FrmPersona(IControlable controler) {
    super();
    this.controler = controler;
    initGUI();
   }
  ... 
CtrlPersona.java
  ...
  private IDatable myView;
  private IActualizable myModel;
  ... 
Persona.java
  ...
  private IControlable controlador;
  public Persona(IControlable controlador){
 this.controlador = controlador;
  }
  ...

Vista - "Las pantallitas"1

La vista tiene como responsabilidad mostrar  y tomar datos. Las vistas no conocen nada de enteros, o tipos de dato. Todo para ellas son Strings. Con el desarrollo de las tecnologias web, se pensaba en poner validaciones de formato en esta capa (numerales, etc) para no tener que ir hasta los servidores y disminuir tanto performance como experiencia de usuario, pero con las tecnologias asincronas como ajax, esto pronto dejó de ser nacesario. No realiza ningún tipo de validación de negocio, ya que es el modelo el encargado de realizar dichas validaciones. Cada una de las acciones realizadas es una llamada al controlador para que él sea el encargado de tomar cualquier decisión.
  ...
  @Override
  public void setData(Map data) {
      this.txtNombre.setText(data.get(CtrlPersona.NAME));
      this.txtApellido.setText(data.get(CtrlPersona.SURNAME));
      this.txtEdad.setText(data.get(CtrlPersona.AGE));
  }
  ...
 @Override
 public Map getData() {
   Map data = new HashMap();
   data.put(CtrlPersona.NAME, this.txtNombre.getText());
   data.put(CtrlPersona.SURNAME, this.txtApellido.getText());
   data.put(CtrlPersona.AGE, this.txtEdad.getText());
   return data;
 }
 ...
 @Override
 public void actionPerformed(ActionEvent arg0) {
   if(arg0.getSource() == this.btnCancel){
     controler.cacelAction();
   }
   if(arg0.getSource() == this.btnOK){
     controler.oKAction();
   }
 }
 ...

Controlador - "Eso que entedes vos y nadie más... ponelo si querés...pero no pierdas tiempo.. bla bla...bla... cerveza!"1

En la capa de controlador, podemos encontrar que es donde se instancia las interfaces y modelos que el controlador quiere manejar. Una alternativa a esto ultimo, es que las instancias (Tanto de la vista, como del Modelo) sean pasadas como parametros al constructor del controlador.
Algunas de las responsabilidades de esta capa podrían ser las siguientes:
  • Realizar validaciones de formato
  • Subir y bajar variables de sesión
  • Redireccionar y hacer el forwared de las pantallas  y manejar el ciclo de vida de las Interfaces de usuario o sistemas.
  • Capturar tanto las excepciones de negocio, como de formato.
  • Tomar y poner información en las interfaces
  ...
  {
    myView = new FrmPersona(this);
    myModel = new Persona(this);
  }
  ...
  public void oKAction() {
    Map data = myView.getData();
    try{
        ParameterTool.checkMandatoryFields(data);
        ParameterTool.checkInteger(AGE, data.get(AGE));
        myModel.save(data);
    }catch(MenorDeEdadException e){
        setReturningMessage(e.getMessage());
    }catch(IllegalArgumentException e){
        setReturningMessage(e.getLocalizedMessage());
    }
  }
 ...

Modelo - "El diagramita de clases"1

La capa del modelo, es aquella que representa el negocio de la aplicación. Son aquellas clases con estructura de Java Beans que tanto conocemos. En un MVC la lógica de guardado de la base de datos suele estar en las clases del modelo, por supuesto haciendo llamadas a métodos de alguna librería o un paquete de utilidades para conectarnos con las bases. Es la capa que con las sucesivas iteraciones (y evoluciones a stacks de software) ha ido subdividiéndose, en subcapas, como por ejemplo la de repositorios de objetos.
Una responsabilidad de implementación definida e interesante de destacar es la de chequear las reglas del negocio.

Bueno, existe mucho más que se puede decir de este patrón, ya que como dije al principio, se ha hablado mucho. Pero esto es lo que considero importante para poder aplicarlo, no solo de una forma académica, si no también implementable.  En el próximo post escribiré de la evolución del MVC y esto será en los próximos N días.  (O tal vez  N a la M días).
Mi pasión siempre ha sido no solo hablar teóricamente de algo, porque de eso seguro hay mucha gente que puede hablar más y mejor, pero al final del día… siempre soy solo un programador… y quiero ¡ver pantallitas funcionando!

1) Nota: traducidos a lenguaje "jefe" para la fácil adaptacion a todo tipo de públicos.

jueves, septiembre 22, 2011

Arquitectura de Software vs. el Caos

La verdad que he tenido ganas de escribir sobre este apartado hace un largo rato ya, pero bueno, es tan larga la tela para cortar que no sé bien por donde comenzar. Hoy... acá... más bien definiré cuales son mis impresiones particulares sobre este tema a nivel general, otro día definiré cuales son, bajo mi puto de vista, las formas de organización de los proyectos más adecuados, y una que otra técnica que nos puede ayudar.
Definir una arquitectura, es casi tan difícil como definir que quiere decir arquitectura. Si la misma IEEE, establece sobre arquitectura que no sabe a priori que es, pero que cuando se la vé se la reconoce. Escuchamos, por ahí, a diario en nuestras empresas, que nos dicen: “esto es problema de arquitectura” o “no se puede escalar... la arquitectura no nos lo permite” o algún que otro enunciado apocalíptico que nos deja pensando.
En el mundo informático, o por lo menos acá en argentina, existe una alta rotación de personal en las empresas informáticas, y tenemos que cambiar de entorno laboral con frecuencia. Y cada vez que que nos sumergimos en un nuevo proyecto, encontramos que abrimos el IDE, hacemos un check out de la aplicación y cuando volvemos con taza de café en mano, empezamos a achinar los ojos y a escrolear el árbol de paquetes en el explorador de proyectos, de la misma manera que un peluquero novato mueve el pelo de un lado al otro sin tener idea de por donde comenzar.
Punto para el caos.
Luego después de unos primeros días de total incertidumbre, y de esfuerzos vanos de nuestros instructores por explicar los inexplicable, realizando capacitaciones teóricas, de lo que escasas veces vamos a encontrar en en la aplicación, nos empezamos a preguntar por que no utilizamos algún ultra-mega-re-contra-probado componente que existe ya en el mercado en lugar de tratar de reinventar la rueda trabajando con nuestro rustico-humilde-eterno-beta componente para realizar la misma tarea?
Punto para el caos.
Bien, ya superamos nuestra angustia, y nuestro sentimiento inicial de junior--, ahora es tiempo de realizar el aporte que dejaremos para siempre como una impronta, como una marca de hierro, en nuestra empresa. ¡Vamos a desarrollar un nuevo modulo de negocio para nuestra empresa! ¡Vamos a sentirnos productivos! ¡Ya estamos en condiciones!. Empezaremos por leer la documentación para entender a que APIs le vamos a “pegar” y las capas sobre las cuales nos “pararemos” para construir. Abrimos el repositorio de documentación, si existe, y ...¡WTF!...vemos que está totalmente vacío o con documentación desactualizada.
Otro punto para el Caos, y podría seguir así por un largo rato.
A esta altura del post, podes estar sintiéndote frustrado, ya que no ves una linea de código, ni documentación técnica que diga como hacer tu arquitectura infalible. Solo viste problemas humanos, sentimientos, emociones, frustraciones. Nada técnico. Púes bien. La mayoría de los arquitectos que he conocido, era personas sumamente capacitadas técnicamente, gurues de la tecnología, hombres que se juntaban a tomar mate con neo en la misma matrix. Pero con, con escasos skills de comunicación y poco human-oriented. Hombres que se sentaban en su propio box en un estado de autismo del cual sacarlo sería pecado capital. Lapidación!
Dies puntos para el caos!

“El silencio de un arquitecto, es el peor enemigo de la escalabilidad de un software”

Somos arquitectos, queremos arquitectear!

Bajo mi puto de vista, cada una de las palabras que vaya a citar acá debe ser tomada en cuenta como un test case, el cual cada diseño que realicemos, cada aporte, cada linea, cada acción debe superar.

¡Responsabilidad!

Todo tiene que tener una responsabilidad acotada y definida, cada clase, cada paquete, cada método, cada proceso, cada documento. Se tiene que poder definir rápidamente los inputs y los outputs, y a que se dedica. Esta es la principal palabra de una arquitectura soñada. Si hacemos un método, nos tenemos que preguntar antes de la primera linea de código, ¿a que se va a dedicar este método? En lugar de escribir una cascada de ifs de 100 lineas de código. Ningún método, clase, paquete, etc, etc, debe ser superman, y hacerlo todo. Si tenemos métodos de 300 lineas de código, algo estamos haciendo mal. ¿Estamos trabajando Orientado a objetos, o estamos estoreando lineas de código en un archivo? ¿Cada capa se ocupa de lo que tiene que hacer?

¡Narcisismo!

¿Es nuestro arquitectura narcisista? A la cual podemos ver como un espejo y decirnos lo buen programadores que somos. Lo genios, intelectuales, que utilizamos reflection, recursividad o algún otro recurso “mágico” para realizar una tarea. ¿Son estas tecnologías necesarias? Imaginemos que después de nosotros va a venir otro programador que se va a tener que que pelar los dedos con F5 para poder debuggear nuestro código, en idas y vueltas. ¿Tenemos una arquitectura de 100 capas que nos dará una futura y muy lejana escalabilidad y reutilización? Pero si nuestra empresa tiene una alta rotación de personal, y los requerimientos siempre corren contra el reloj... “the new guy”... va a realizar todos esos métodos? Primero que eso... va a conocerlos? O va a buscar un workaround de código que le permitirá cumplir con los plazos del burndown?. Estudiando nuestra empresa, y sus características, sabremos como se comportará nuestra arquitectura en el futuro. Complejidad innecesaria = narcisismo.

¡Aburrimiento!

Toda idea que se nos cruce para realizar un componente, es probable que ya haya sido pensada. Debe existir por ahí. Bien, frente a una cuasi igualdad de características técnicas, ¿cual de todos los componentes utilizar? ¡el más nuevo, lo nuevo es mejor!
10 punto más para el caos!
Trabajamos en una empresa inmersa en un mercado laboral, con un conocimiento circundante, ¿debemos realmente malgastar tiempo de un recurso en capacitación sobre ese nuevo componente, que desconocemos, del cual existe escasa documentación, o que no tiene una comunidad de soporte amplia al rededor del mundo? O debemos escoger, ese que en una entrevista laboral al preguntar al postulante si ya tiene experiencia en el, nos conteste con una sonrisa y un rotundo - ¡Si! Es probable que ese componente tenga una comunidad amplia al rededor del mundo, con actualizaciones constantes, con documentación en nuestro idioma y cientos de blogs con tips para realizar una tarea. Lo demás, lo nuevo, lo aprendamos en casa, allí podremos hacer pruebas en nuestro sandbox personal sin afectar el proyecto. No agreguemos factores de riesgo, por mas aburridos que estemos.

Comunicativa

¿Es nuestra arquitectura capaz de darse a entender por si misma? De tal forma que solo nos necesite como meros heraldos de presentación. Que al abrir el proyecto nos brinde una idea general de donde esta cada cosa. Que a la hora de que alguien tenga que escribir un método sepa cual es la clase, o la capa en la cual debe ir. ¿Documentamos lo que hacemos? Los frameworks y componentes que mayor éxito tienen en el mercado son aquellos que mejor documentados están. Nadie quiere perder preciosas horas de investigación averiguando que tenia en la cabeza el programador a la hora de hacer el código. Siempre nos repetimos a nosotros mismos, y muchas veces sin razón alguna, más allá de la falta de documentación, que sería mas fácil hacerlo de nuevo que continuar el trabajo de otros. Las wikis suelen ser herramientas muy útiles a la hora de mantener tan “viva” nuestra documentación como nuestro código.
El conocimiento es una de las bases del poder, y teniendo en cuenta esto, existen personas en las empresas que buscan ser los “únicos” que entiendan la forma de hacer las cosas. Pero después, estas personas se marchan buscando nuevos horizontes laborales, y el conocimiento se pierde, y la semilla del caos ha sido sembrada. Es por ello, que documentar no solo se transforma en una ventaja competitiva, si no también en una necesidad de supervivencia.

Autocrítica

Nada es perfecto, todo es perfectible en el tiempo. Pero al igual que un rió, el código fluye. Los requerimientos cambian, el conocimiento se actualiza. Debemos criticar con periodicidad nuestro código. Lo que la industria llama “Refactorizar”. Esto es como agregarle agua a un pozo tapado con tierra. Siempre nos va a dar lugar para agregar un poco más, y va a hacer a nuestro código mas solido. De lo contrario, la deuda técnica se incrementará dia a día, y solo nuestro esfuerzo servirá para pagar los intereses de esta deuda. Nos debemos preguntar, esta clase se tendría que llamar así? ¿Estos métodos subclaseados, podrían subirse al parent en el árbol de herencia? Estos métodos de la misma clase comparten muchos código, ¿no debería sacarlo a uno private y parametrizarlo? Debemos crear ciclos de desarrollo-refactorizacion-desarrollo etc. Es como el chequeo médico para determinar la salud de nuestra arquitectura.

Eutanasica

Debemos entender que cualquier arquitectura que diseñemos tendrá un ciclo de vida. Se realizará para un momento determinado del tiempo. Con un conocimiento sobre el mercado, una visión empresarial y un nivel de conocimiento técnico determinado. Las grandes arquitecturas viven por años, aquellas que son chequeadas, analizadas, y tratadas periódicamente ante cualquier síntoma. Otras, no soportan la deuda técnica y se cancerizan rápidamente en el lapso de uno o dos años. Nos debemos preguntar, ¿donde estaremos en seis meses a este paso? ¿Podemos liderar el mercado técnico con esta arquitectura?¿podemos alcanzarlo?¿Ha cambiado la visión de la empresa? ¿hemos aprendido suficiente? Si estas preguntas no pueden ser resueltas rápidamente, o si no nos gusta la respuesta, es hora de ir preparando una “muerte digna” de nuestra arquitectura. Ir planificando una migración, dejar un grupo de soporte, mientras una nueva esta en camino. No esperar hasta que el agua nos llegue al cuello.

Son varios los items de la check list, pero es un principio.

Conclusión

Pensar en una arquitectura como algo meramente técnico, es partir desde bases erróneas. Por supuesto que un arquitecto debe ser una persona técnicamente idóneo, ya que debe entender lo que su equipo técnico esta sugiriendo, y saber tomar decisiones técnicas todos los días. Pero pensar que eso es los más importante, o que es lo único que debe tener, es concebir que el mejor albañil que conocemos es capaz de diseñar el empire state. Debemos entender que en este edificio abstracto que vamos a diseñar será habitado por personas, y no mayoritariamente por clientes, si no más bien por los desarrolladores, y toda clase de staff informático con lo que convivimos diariamente. Abramos las puertas, preguntemos como quieren vivir. Revisemos nuestra empresa, nuestro proyecto.

martes, junio 08, 2010

UML: Diagrama de Clases, ejercicio 1

Acá les dejo un ejercicio que le preparé para un amigo. Por si lo quieren realizar. La respuesta la voy a postear en algunos días.

Ejercicio:


El objetivo, es realizar el código java del diagrama que figura a continuación. Los métodos, salvo aquellos de la agregación, pueden contener solo la firma, no hace falta la lógica.


Respuesta

by Charli Quiroga

Clase Vehículo



import java.util.List;

public abstract class Vehiculo implements Desplazable {

private double velocidadPromedio;
private int velocidadMaxima;
private List ruedas;
public Vehiculo() {
super();
}

public double getVelocidadPromedio() {
return velocidadPromedio;
}
public void setVelocidadPromedio(double velocidadPromedio) {
this.velocidadPromedio = velocidadPromedio;
}
public int getVelocidadMaxima() {
return velocidadMaxima;
}
public void setVelocidadMaxima(int velocidadMaxima) {
this.velocidadMaxima = velocidadMaxima;
}
public List getRuedas() {
return ruedas;
}
public void setRuedas(List ruedas) {
this.ruedas = ruedas;
}
public void agregarRueda(Rueda rueda) {
if(!ruedas.contains(rueda))
ruedas.add(rueda);
}
public boolean quitarRueda(Rueda rueda) {
return ruedas.remove(rueda);
}
public abstract void romperInercia();
}

Interfaz Desplazable



public interface Desplazable {
public abstract void esquivarObstaculo();
}

Clase Rueda



public class Rueda {}

Clase Barco



public abstract class Barco extends Vehiculo{}

Clase Auto



public abstract class Auto extends Vehiculo{
public static final int N_RUEDAS = 4;
}

Clase Moto



public abstract class Moto extends Vehiculo {
public static final int N_RUEDAS = 2;
public void esquivarObstaculo() {}
}

Clase Boing747



public class Boing747 extends Vehiculo{
private static int viajes;
@Override
public void romperInercia() {}
@Override
public void esquivarObstaculo() {}
public static int getViajes() {
return viajes;
}
public static void setViajes(int viajes) {
Boing747.viajes = viajes;
}
public void despegar() {}
public void aterrizar() {}
public static void agregarViaje() {}
}

Clase BarcoAVela



public abstract class BarcoAVela extends Barco {}

Clase FordFalcon



public class FordFalcon extends Auto {
@Override
public void romperInercia() {}
@Override
public void esquivarObstaculo() {}
}

Clase HondaXR600



public class HondaXR600 extends Moto {
@Override
public void romperInercia(){}
@Override
public void esquivarObstaculo(){}
}

Clase HondaXR25



public class HondaXR25 extends Moto{
@Override
public void romperInercia(){}
public void esquivarObstaculo(int metros){}
}

Más info sobre Diagramas de Clases en la etiqueta Diseño

viernes, mayo 21, 2010

UML, Asociacion y Agregacion

El post de la Agregación y Composición despertó otra pregunta más (Como siempre suele suceder, ya dije que el debate siempre dá para algo más). La duda viene por el lado de la diferencia entre asociación y Agregación en código. Se sostiene que es algo conceptual, que no se representa en código. Mi respuesta es que esto es 50% correcto. Ya que, como mencione antes (la etiqueta Diseño tiene mas sobre esto), la Asociación surgió primero, y la Agregación vendría a ser un tipo particular de Asociación. Ergo ...Agregacion "IS-A" Asociación ¡punto para ud! . Primero veamos el diagrama UML

Ahora veamos el codigo de la clase Persona (Nota: imagínense los generics por que blogspot los toma como tags, así que no aparecen)

import java.util.List;

public class Persona {

private String nombre;
private String apellido;

private Foto foto;
private List lugaresFrecuentes;
private List comunicaciones;

public String getNombre() {return nombre;}
public void setNombre(String nombre) {this.nombre = nombre;}
public String getApellido() {return apellido;}
public void setApellido(String apellido) {this.apellido = apellido;}

//Asociacion Foto
public Foto getFoto() {return foto;}
public void setFoto(Foto foto) {this.foto = foto;}

//public List getLugaresFrecuentes() {return lugaresFrecuentes;}
//public void setLugaresFrecuentes(List lugaresFrecuentes) {this.lugaresFrecuentes = lugaresFrecuentes;}

//Agregacion
public void agregarLugar(Lugar lugar){
lugaresFrecuentes.add(lugar);
}
public boolean quitarLugar(Lugar lugar){
return lugaresFrecuentes.remove(lugar);
}
//Asociación
public void setComunicaciones(List comunicaciones) {
this.comunicaciones = comunicaciones;
}
public List getComunicaciones() {
return comunicaciones;
}

}

Las diferencias principales son que:
  1. ¡La Agregación son siempre colecciones, o arrays! O algo que sirva de contenedor para "agregar" más de un objeto, aunque agreguemos uno solo. (si no sería settear y no agregar, add)
  2. La Agregación cuenta con dos métodos: uno para "agregar" un solo objeto a la lista, y el otro para quitarlo de la misma.
  3. La agregación puede, como no, tener los metodos setter y getter, mientras que la Asociación siempre los tiene, que ponen y obtienen una variable de referencia del mismo tipo de la variable de instancia o de clase, en este caso List.

Bueno, espero haber limpiado alguna duda, y abrir otras ;) Saludos.

jueves, mayo 13, 2010

UML, Agregacion y Composicion

He visto demasiadas discusiones vicentinas sobre las diferencias entre la agregación y la composición en los diagramas de clases de UML. Es más, cada cierto tiempo, alguien surge y me pregunta cual es la diferencia en el código y me explica sus propias teorías sobre esta cuestión, este debate es casi tan extenso como el de los extends y los includes de los casos de uso.
Empecemos, debemos recordar siempre que una de las mayores criticas que recibe UML, es que ha logrado salvar muchas ambigüedades... Pero no todas!!! aun quedan conceptos que se prestan a dobles interpretaciones, no se si este será uno de ellos, pero por lo discutido parece que sí. Por otro lado, podemos hacer un poco de historia, recordando que primero existió la asociación, después surge la Agregación para representar un relacion estructural contenedor/contenido y luego como una "extensión" de esta ultima nace la Composición.
Para explicar mi punto de vista voy a echar mano, al diagrama de clases que ya he utilizado en otro post y después voy a poner el código de la clase Persona, que es la que se lleva toda la carga de la discusiónEl código hace referencia, solo a este modelo, y es bien detallado, hasta con cosas innecesarias, o meramente teóricas, pero lo que busco es fijar una posición, concreta y definitiva, en el tema de las relaciones.
Algo importante a tener en cuenta, es que un objeto existe (digamos que esta vivo, pero esto no es técnicamente correcto por que no es un hilo) mientras existe una variable de referencia que "apunte" (tampoco correcto, por que java no tiene punteros, je) a dicho objeto en memoria. Es decir que se convertirá en elegible para ser borrado por el garbage collector, cuando no exista una variable que "apunte" a dicho objeto.


import java.util.LinkedList;
import java.util.List;

public class Persona {
private String nombre;
private String apellido;
private List perfiles = new LinkedList();
private List lugaresFrecuentes = new LinkedList();

//Setters and Getters
public String getNombre() {return nombre;}
public void setNombre(String nombre) {this.nombre = nombre;}
public String getApellido() {return apellido;}
public void setApellido(String apellido) {this.apellido = apellido;}

// OJO no confundir estos son solo setters y getters de las propiedades
public List getPerfiles() {return perfiles;}
public void setPerfiles(List perfiles) {this.perfiles = perfiles;}
public List getLugaresFrecuentes() {return lugaresFrecuentes;}
public void setLugaresFrecuentes(List lugaresFrecuentes) {this.lugaresFrecuentes = lugaresFrecuentes;}

La clase comienza normalmente con la declaración de las variables de instancia. Donde perfiles y lugaresFrecuentes son dos colecciones, pero tranquilamente podrían ser arrays. que se transformarán en contenedores de elementos. Al ser propiedades tienen getters y setters (accessors y mutators), que nada tienen que ver con la agregación y la composición.
Ahora veamos cuales son los métodos que caracterizan a la relación de AGREGACIÓN


public void agregarLugarFrecuenta(Lugar lugar){
if(!lugaresFrecuentes.contains(lugar)){
lugaresFrecuentes.add(lugar);
}
}
public void removerLugarFrecuenta(Lugar lugar){
if(lugaresFrecuentes.contains(lugar)){
lugaresFrecuentes.remove(lugar);
}
}

La primera característica es que la clase contiene dos métodos uno que agrega elementos a la coleccion y otro que los elimina de ella. He acá algo importante... los objetos son pasados por parametro, no han sido instanciados dentro del método, es decir no hemos realizado el new del objeto. Ha "nacido" en cualquier otra parte y se lo hemos pasado por parámetro al método para ser agregado a la lista lugaresFrecuentes. En otras palabras, el objeto Persona podria morir, y el objeto ahun podría mantener una referencia activa en alguna otra parte de nuestro codigo por lo tanto sus ciclos de vida no estrían atados. No nace ni muere, dentro de la Persona.

¿Cual es la Diferencia con la COMPOSICIÓN?


public void agregarPerfil(){
Perfil p = new Perfil();
perfiles.add(p);
}
//sobrecarga
public void agregarPerfil(String nombre){
Perfil p = new Perfil(nombre);
perfiles.add(p);
}
public void removerPerfil(int index){

perfiles.remove(index); // aca lo quitamos de la lista

}
Bueno... la composición también tiene los métodos para agregar y borrar. Pero...

"el new del objeto se realiza dentro del método agregar"


la instanciación del objeto p se realiza dentro del método agregar y la referencia no se devuelve (es void o boolean), la variable de referencia local va a dejar de existir una vez que el método se termine de ejecutar, y el ciclo de vida de esa instancia en particular va a quedar atada a la lista, y por ende a la Persona. Una vez que el objeto Persona no se referencie más, (o sea muera, aunque técnicamente esto no es así) el objeto lista, quedará sin referencia, y por lo tantos sus elementos también. Además como el método no es estático, se deberá crear primero una instancia de Persona, para después poder agregar un Perfil. Empezando así a "atar" el ciclo de vida de un Perfil, al de una Persona.
En cuanto al método remover, no existe nada de extraordinario, simplemente quitamos un elemento de la lista.

Volviéndonos Paranoicos de la Teoría


Profundizando la paranoia y jugando con la teoría; para que atemos definitivamente los ciclos de vida, la variable lugaresFrecuentes no debería ser una propiedad, y la clase Perfil debería ser una Inner Class.
En el caso de la Inner class, hacemos esto para que se tenga que utilizar una instancia de la clase "Outer" para luego obtener una instancia de la clase Inner. Por ejemplo si en nuestro codigo, la clase Perfil, fuera una Inner class de la clase publica Persona (Se entiende no?, es decir que esta dentro del archivo Persona.java), para obtener una instancia de Perfil fuera de la clase persona tendríamos que hacer:

Persona persona = new Persona();
Persona.Perfil perfil = persona.getPerfil(...);

El new de creación esta dentro del metodo agregarPerfil. La clase Perfil existiría mientras exista la instancia de persona. (ciclos de vida atados)
En el caso de que la variable de instancia lugaresFrecuentes no debería tener getters y setters públicos, esto se debe a que ningún otra clase, con excepción de la clase Persona, debería tener la oportunidad de mantener una referencia viva a un objeto del contenedor. Y mucho menos obtener toda la Lista desde afuera! Un objeto Perfil, vive y muere con la Persona!
También de esto se pueden desprender otros delirios, como cuestiones de herencia y cosas así.
Pero de nuevo, y no me voy a cansar de decirlo... esto es un extremo!!, es solo para conversar entre amigos, o vanagloriarse con algún profesor, no tiene nada de practico, ni de real, salvo para casos específicos.

Paranoia de la Paranoia


¿Creían que ya habíamos terminado? aun se puede ser más paranoico!!!! mucho se ha discutido sobre estos temas, y mucho fue paranoia teórica. Lo siguiente, es algo que les llevará a sus amigos o profesor a decir, "...bueno pero eso ya es una locura":
Sobreescribiremos el método finalize() de la Clase Persona, que es un método que todas las clases heredan de Object, y que se invoca justo antes de que un objeto sea borrado de la memoria por el garbage collector de java.

public void finalize(){
for(Perfil p : perfiles){
p = null;
}
}

En el desreferenciamos cada uno de los elementos de la lista un segundo antes de que el objeto de tipo Persona desaparezca de la memoria, una milésima de segundo, o algo asi!!! atando definitivamente el nacimiento y muerte, el ciclo de vida, de un elemento contenido con su contenedor.
Pero de nuevo!!! LA PARANOIA EN EL CÓDIGO NO ES BUENA!!! solo sirve en aquellas noches de borrachera entre programadores, en las cuales el boliche cerró y pinta quedarse en casa con amigos.

Yo rescataría de todo este biri-biri aquello de "el new se realiza dentro del método" y nada más!!!

miércoles, mayo 12, 2010

SCJP 1.6 de Java


Hace unas semanas a tras he decidido rendir la certificación SCJP 1.6 de Java. La verdad es que en un principio, me resultaba medio confusa y bastante difícil. Pero después a medida que estudiaba el libro, y lo traducía de apoco, por que la única versión que existe es en ingles, y además el examen es en inglés, fui adquiriendo un mayor ritmo para la resolución de los ejercicios. Creo haber aprendido un montón de cosas que desconocía a cerca del lenguaje. Esta muy buena y es super aconcejable, así qué, cuando tengan un tiempo (notece que dije tiempo y no tiempito) se pueden encomendar a esta campaña. Existe info de sobra en la web de como rendirla, o sea vasta googlear "SCJP 1.6 de Java" para toparce con foros, blogs y paginas que contienen PDFs con manuales, algununos simuladores, jugos etc. Lo que no se encuentra a simple vista es tips y estrategia para afrontar el examen.
En mi caso personal, y al conversar con algunos amigos que ya la habían rendido, me dí cuenta que la clave principal, es el TIEMPO, repito en mi caso personal, ya qué no sé si todas las versiones del examen serán iguales, pero contaba con 60 preguntas, y un tiempo máximo de resolución de 3hs. Que si contamos con los deditos nos da un total de 3 minutos por pregunta. Bien, existen preguntas que exeden por lejos ese tiempo, ya que tienen codigo largo, confuso y si además le sumamos que hay demaciadas preguntas tramoposas en el examen, por lo que por más que seamos "don java" si nos dormimos por un segundo, se nos va a pasar algun import o punto y como o algo así. Yo no sabía cual sería la duración, ni cuantas preguntas tendría, por que cada pagina daba una duracion diferente, por lo que decidí entrenarme con un timpo de resulución de 4 minutos por pregunta, con las preguntas del libro, y ni ahun así lograba resolverlas a todas. Llegado el dia, y al darme cuenta que solo tenia 3 minutos, decidí, no escarbar tanto en las preguntas, y si tenian "trampa" que así sea. La hipotesis fué que serían las menos. Y para ser mi primer intento, logré certificar. Es más me quedo unos 15 minutos para hacer una rápiada repasada del examen donde logre reveer un 30% de las preguntas y salvar 2.
Algunos datos utiles en argentina:

- Tiempo de duración: 3hs (180 min)
- Total de Preguntas: 60
- Score para aprobar: 58% (35 Preguntas)
- Ojo con las preguntas de arrastrar y soltar se pueden resetear
- Codigo del examen: 310-065
- Libro (PDF): Sun Certified Programmer for Java 6 - Study Guide
- Libro en Papel: Sun Certified Programmer for Java 6 - Practice Exams (No se molesten en buscarlo en PDF, solo sale la versión en papel, Y NO LO TENGO, por lo que si alguien lo tiene en PDF me lo podría habilitar.
- Simuladores: Wizlabs, Sybex, intrepid
- 1 Blog: http://scjp-sun.blogspot.com/
- Juegos para practicar: http://faq.javaranch.com/java/ScjpMockTests
- info sobre la certificacion: http://osum.sun.com/
- Donde inscribirse para rendir: www.prometric.com



Lic Ariel Diaz Molina
Java Certified Programmer

martes, diciembre 01, 2009

Con ubuntu 9.4

En realidad desde que me compre "Esta notebook Dell" he tenido como sistema operativo por defecto ubunto 8.10. Digo "esta" por que mi antigua Dell me duro solo dos días gracias a unos entusiastas chicos que saltaron una ventana con un par de 38s en mano, y que deben haber cambiado una máquina de unos $usd 2000 por unos $500 argentinos. Pero en fin... lo mío no es el mercado negro de la computadoras. Ojala que estés conectada a una linda wifi amiga mía.
Con respecto a ubuntu, la verdad que el soft libre me ha traído un poco más de alergias que de tristezas. Alegrías a la hora de programar, por la instalación de servidores, casi plug and play, además de algunas otras buenas aplicaciones que existen dando vuelta por ahí en la compuosfera. Tristezas, por algunas cuestiones de configuración del hardware e instalación de aplicaciones que en win son del tipo "siguiente-siguiente-terminar", en el caso de linux representaba una batalla sangrienta de 2 o 3 noches completas contra las hordas de Atila el Huno y Breno el galo, juntos
El otro día al tener que realizar una teleconferencia con un amigo que se encuentra en españa por skype, descubrí que mi micrófono incorporado no estaba funcionando, por lo que me decidí a buscar los drivers que pudieran realizar el milagro de hacerme funcionar el tan preciado micrófono. El remedio fue peor que la enfermedad y el "nuevo driver" me termino por desconfigurar algunas otras cosas. Resultado del experimento fallido: Año nuevo SO operativo nuevo... bienvenido Ubunto 9.4!!! Ojala... el no tener que reiniciar, tus hermosos pears, tus servidores, y tu parches de seguridad me auguren un muy buen año!!! Driver pasado, pisado y olvidado!

domingo, octubre 11, 2009

Degree

Gracias a todos mis amigos que me acompañaron en este proceso. Me llegaron un montón de saludos, incluso de aquellos que hace mucho tiempo que no veía o escuchaba algo de ellos. Gracias a todo mi mundo. Sip uno más, a otra cosa mariposa.
Ariel Diaz Molina, Licenciado en Informatica

martes, septiembre 22, 2009

Agradecimientos de mi Tesis

Para esas dos almas, una allá y la otra acá. Cuyo valor e infinito amor me obsequiaron el mayor de los dones; el poder pensar en libertad. La posibilidad cazar sueños, solo mirando al cielo.

Para ella, y ella que lo soportaron todo.

viernes, agosto 07, 2009

Programacion - Buenas Practicas - Nombres

Bien, vi por ahí un comentario sobre términos en ingles. La verdad es que a mi también se me dá mucho lo de poner los términos en ingles. En cuanto al idioma a utilizar, tanto en el código, como en los modelos, es mi opinión que principalmente debemos tener en cuenta el publico al que va dirigido. Es decir que si mi equipo de desarrollo esta compuesto básicamente por personas que hablan español debemos proponernos utilizar nombres o notaciones en español, ya que algunos podran hablar ingles, pero la mayoria hablara español, se entiende?. El utilizar el ingles, tiene su razón cuando el cliente es de habla inglesa y nuestro código es de su propiedad (tercerización), o los "stakeholders" (no tiene una traducción directa al español, pero es algo así como los interesados, gente que pone la plata, etc) son de habla inglesa.
En cuanto al código, algunas buenas practicas no dicen nada del lenguaje pero sugieren (En lo que recuerdo.no?) para:

-Constantes: nombres descriptivos, completamente escritos en mayúsculas remplazando los espacios es blanco con guiones bajos.

- Variables: nombres descriptivos de la misma. En java, se utiliza la notación "camelCase" donde se escribe todo junto y cada palabra comienza con una mayúscula menos la primera. Y no se suelen utilizar prefijos. En el caso de php se utiliza las notación que incluye guiones bajos (no recuerdo bien el nombre, es un poquito complicado). Ejem nombre_variable. Además de ello, y a diferencia de java, se suelen utilizar prefijos. Por ejem: obj_nombre_variable para hacer referencia a que la varible es un objeto.

-Metodos: similares a las variables, pero no se utilizan prefijos tanto para php como para java. su nombre se forma con la estructura verbo + objeto. Ejemplo publicarNoticia (java) o publicar_noticia (php). A excepcion de los metodos de acceso a los atributos o propiedades que si o si deben tener la estructura getPropiedad(), setPropiedad(TipoPropiedad propiedad), isPropiedad().

- Clases: Nombres camelCase en singular y que comiencen en mayuscula, para java y PHP5, C++, etc. En php4- se pueden escribir con minúscula.

-Interfaces: los nombres se deben escribir camelCase con la primera palabra en mayúscula y ser adjetivos (PHP5,java). Por ejemplo, publicable, votable, etc.

-Paquetes: (php5, java). Los nombres se escriben en minúscula separando las palabras por puntos. y su estructura es de la forma siguiente: dominio.alreves.[empresa/equipo/proyecto].nombrepaquete. Por ejemplo Si es para el sitio www.mipagina.com y trabajamos en la empresa arosoft podría ser com.mipagina.arosoft.utilidades

Por ultimo Los nombres, según la capa de arquitectura en la cual se ubique, es otro tema, a desarrollar después. Pero podría adelantar que si es una clase que formará parte de una capa de servicios en un presenter de un MVP o algo asi, es decir una capa intermedia en la codificación, podría tener por nombre un gerundio. Por ejemplo: Publicando y cada metodo que implemente un caso de uso tener el mismo nombre que en la ficha de caso de uso escrito en camelCase, para facilitar el seguimiento y las pruebas funcionales del mismo.


Saludos, nuevamente espero que despierte algunas ideas.

Una guerra que está cambiando su rumbo

Por fin esta guerra que comenzó en tiempos mas allá de mi conciencia parecería tornar su rumbo. Por primera vez en la vida, creo que la universidad no la ganará. Pájaros negros circundan sus posibilidades.
Que aquello que empecé cuando todavía mi cara angulaba, está llegando a su fin. Ya no se trata de los deseos de realización de una madre, ni el alma penante de un padre que vela por la felicidad y el futuro de su hijo. No se trata de una promesa. No se trata del respeto que infunde la palabra que precederá a mi nombre, ni de un papel impreso con un cero de más. No se trata de las presiones que abuelos, familiares, amigos, allegados, etc, ejercen sobre mi persona al rededor de una mesa.
Se trata de una guerra que ni el mismisimo Pirro hubiera estado dispuesto a librar. A donde quedaron en el camino, un gran afecto, un hijo no nacido, un padre no acompañado, un sueño no cumplido, una carrera abandonada. Soldados que se contaron como lágrimas, sueños, noches en vela, compañeros de camino; han quedado a trás por sostener una bandera.

Pero la guerra está llegando a su fin! Está cambiando su rumbo.

Solo resta la madre de todas las batallas, aquella que definiría todo. El todo o la nada. Y estoy más preparado que nunca, la experiencia me ha nutrido, he bebido de sus tetas hasta quedar rechoncho, mi armadura brilla tanto bajo el sol como bajo la luna, mi espada corta y bloquea por igual y mi caballo atraviesa tempestades.
Que te queda a ti?
Solo tus harapos teñidos de vergüenzas, tus magulladuras, tus puños que tantas veces supieron rechinar contra mis huesos, que quebraron mi intestino, hoy hacen huellas en el suelo junto a tus rodillas. Te has quedado sola en tu castillo, pues uno a uno tus ejércitos han caído.
Si he de festejar el dia que sucumbas?
No, amiga mia, no, enemiga mia. Te guardo el derecho al respeto. Ese respeto que se guarda a aquellas cosas que esculpen tu alma a base de la educación más espartana y sádica. Pero la vida se encargo de que ambos ocupásemos dos bandos diferentes en este desierto donde no hay nada que ganar y mucho he perdido. No será la montaña lo que ha de pagar, será la lucha por ella . Con el tiempo y solo con el tiempo, beberé en tu nombre, reiré con nostalgia de las grandes batallas y recordaré sacrificios. Pero tu día, será un día más en mi vida, y ese ha sido tu mérito.
Puedes sonreír, pero la irónica se transformará en sordónica, pues tu era ha terminado y ahora comienza la mía.

jueves, junio 11, 2009

UML Relaciones, Asociacion, Compocicion, Agregacion II



Aclaración


He tratado de explicar, muy generalmente, cual es la diferencia entre asociación, composición, y agregación, pero creo haber pecado de los mismo que criticaba a los post que leía. No he sido los suficientemente claro, además se me ha solicitado que explique un poco mas.. je.
Debo de destacar que cada modelo diseñado no es prescriptivo, ni intenta ser absoluto hay otras formas de diseñarlo, o por lo menos a mi se me ocurren otras además de estas.
Pero creo que la pricipal, duda viene por lado de la Composición y la Agregación. Cabe destacar, que la composición, surge como un refinamiento de la Agregación, en la búsqueda de implementar la buena practica de programación de hacer a las clases mas "coercitivas", es decir de asignarle responsabilidades.

Explicación del Modelo Representado


Asociacion: Es la relación que existe entre la clase Persona y la Clase Foto, es decir que que existe una variable de instancia (o atributo) en la clase Persona del tipo Foto. Solo un obeto, el cual se setea a partir del método setFoto(), como variable de instancia a la cual se le crea un setter. Este puede ser instanciado (new Foto()) en cualquier otra parte del código.
Agregación: Es la relación que existe entre la clase Persona y la clase Lugar atravez del atributo "lugaresFrecuentes", que es una colección (array, colection, vector, etc) de objetos Lugar. Y que además, la clase Persona cuenta con un método "agregarLugaresFrecuentes(Lugar lugar)" Mediante el cual se agregan un solo objeto del tipo Lugar a la colección "lugaresFrecuentes". Estos objetos, que son pasados como parámetros a dicho metodo, son instanciados fuera de la clase Persona. No debe confundirse con el método setLugaresFrecuentes(Lugar[] lugaresFrecuentes), que tiene solo por ser un propiedad.
Composición: Es la relación que existe entre la clase Persona y la clase Perfil a travez de la propiedad "perfiles" que es una coleccion del tipo Perfil. Además, de ser una relación estructural, es meramente semántica, ya que lo que pretende es darnos la idea de la responsabilidad que tiene la clase Persona sobre el ciclo de vida del objeto de la clase Perfil. Es por ello que también en el ejemplo grafique una Dependencia (esta no se grafica generalmente, con la composición basta. Pero UML sirve para comunicarnos.)
Es idéntica a la agregación pero con la diferencia que la clase Persona se hace responsable de la creacion del objeto Perfil. Es decir que la instancia (new Perfil()) se crea dentro del método agregarPerfil(), y despues de ello, dicho objeto se guarda en la colección "perfiles". El modelo nos esta diciendo, que en ninguna otra parte del código deberíamos escribir un new Perfil() . Ya que coloquialmente, el perfil (sea este psicologico, personal, etc) de una persona solo existe a partir de la persona, muerta la persona el perfil no sirve de nada, y solo a partir de la existencia de la misma se puede crear uno, por lo que este metodo de creacion debe de ser un metodo de instancia.

Es todo una cuestión, de lo que la persona que escribió el modelo (y teniendo en cuenta que la misma sepa utilizar UML, nos quiso transmitir), si existe la duda, hay que preguntarle que quiso decir con lo que graficó.
Espero haber limpiado algunas dudas
Saludos
Ariel Diaz Molina.

lunes, enero 26, 2009

jueves, enero 22, 2009

La isla

Y las aguas del sur se juntaron con las que viajaban desde el norte. Y los vientos que soplaban fríos, silbaron canciones con los que traían calor. Tanto bailaban entre si, y tanta pasión había en aquel tango, que los cielos se agitaban y las nubes se hacían espirales. Nada había de parecido, era casi imposible, solo se dieron las condiciones para una tormenta perfecta.

Allí nació lo nuestro. En aquella exótica isla de lana y resortes. Allí comíamos, dormíamos, saltábamos. Allí vivíamos emociones, nos amábamos por las mañanas, discutíamos por las tardes y sudábamos por las noches. Realmente amé aquellos tiempos, especialmente cuando los primeros rayos de sol se colaban por las rendijas de la ventana para iluminar los paisajes de una geografía de piel y aromas. Rara vez, abandonábamos la isla para adentrarnos en la frialdad de los mosaicos, cumpliendo misiones a la heladera en busca de provisiones que aseguren frescas horas de energía que tanto las necesitábamos por aquellos tiempos. Galopamos sobre prados de 180 hilos, torsabamos nuestras carnes bajo cascadas de bronce cuando el calor agobiaba. Dormíamos profundamente formando las agujas del reloj a las diez y diez, cuando las confesiones acababan y el aire se recuperaba. Hablábamos del pasado, dibujábamos el futuro con ojos en brillo, pero básicamente vivíamos el presente. El día a día era nuestro sustento. Reíamos y corríamos libres de vergüenzas y tejidos como si el tiempo no persiguiese y las obligaciones perdieran su nombre, la gente nos vio amarnos, y los mortales envidiaron aquella inmortalidad.

Así nos devolvimos la fe, así nos perdonamos nuestros pecados. En aquella isla sobre el suelo pero cerca del cielo y lejos de la gente, encontramos nuestra paz.

miércoles, diciembre 03, 2008

Partiendo

Los pasos se tienen que dar, los ciclos se tienen que cerrar. La vida continúa.
Nos subimos a un tren, y de vez en cuando hacemos estación en algún lugar para vivir momentos de tarde y música. Para sacarnos fotos con aquellos personajes que, también, esperan la llegada de su tren. Conocemos personas que nos llenan de azares con historias de vidas, nos enaltecemos con grandes actos de valentía, actos que exaltan al imitarlos, y nos compadecemos de aquellos, cuyas cobardías los rigen.
Aprendemos, nos emocionamos, nos sentimos contenidos y también traicionados. Pero, al final, siempre el pie vuelve al estribo y el vapor hace rulos contra el viento.
Pero en esta partida, la cuadrada ventanilla dejo de ser un lienzo impresionista con paisajes, para convertirse en una pantalla de una película con final triste.
Hace un par de años a tras, me entristecía al pensar que las dirigencias y los mandos medios argentinos, estaban pateando todos sus penales a las tribunas. Que sus miedos los forzaban a tomar decisiones fuera de toda lógica y conciencia. Que la falsa seguridad triunfaba sobre la trascendencia. Que rendían sus prioridades a una boleta de luz antes que al brillo de lograr sus objetivos y visiones.
Hoy mi tristeza continúa. Por que esta miopía sigue emborrachando mentes. Jamás he hablado de idealismos, si no más bien, del más rígido de los pragmatismos. Ocultismo y traición no son religiones edénicas. Desconfiar, presionar, la severidad con aquellos que deben callar, y el silencio con aquellos que hablan gratis, no es valentía ni se le pareces. Pragmatismo no es adular, pragmatismo no es la obsecuencia. Por que a nadie con dos dedos de frente le gustaría tener a su lado un perico de buenos modales, todos preferimos a aquellos cuyo carácter nos evita problemas futuros. No he conocido a nadie, ni en el ambiente de las empresas, ni en el ambiente de la política, ni en ambiente alguno, que tenga éxito callando, ocultando, alejándose de aquellos que lo estiman y protegen.
Pero en fin, nadie enseña mejor que la vida misma, y aconsejar a un amigo más de una vez es terquedad y egoísmo.
Mi tren espera, y mi pie ya está sobre el estribo.

sábado, septiembre 27, 2008

UML Relaciones, Composicion, Agregacion, Asociacion, Dependencia, Generalizacion, Realizacion



Trabajando con los miembros de mi team de desarrollo me di cuenta que a los programadores le costaba interpretar los Diagramas de Clases que el analista realizaba. O existían interpretaciones ambiguas de lo que el realizaba, perdiendo asi la principal funcionalidad del lenguaje UML. Especialmente en cuanto a las relaciones que existían entre las clases. Por eso me dispuse a realizar este pequeño documento, donde voy a tratar de explicar que significa cada relación, en mis palabras, y como se traduce esto a código.
Asociación:
Es generalmente, una relación estructural entre clases, es decir, que en el ejemplo, existe un atributo de la clase medio de transportes, que es del tipo Conductor. La navegalidad nos muestra donde esta ubicado el atributo. Es decir cual es la clase que tiene contiene el atributo si ésta no lo mostrase. La multiplicidad en una Asociación dice bastante, ya que de eso dependerá si el atributo, es una colección o simplemente una variable de referencia a un objeto.
Agregación:
Es una relación que se derivó de la asociación, por ser igualmente estructural, es decir que contiene un atributo, que en todos los casos, será una colección, es decir un Array, Vector, Collections, etc, y además de ello la clase que contiene la colección debe tener un método que agregue los elementos a la colección. También se puede leer como que un medio de transporte tiene varios pasajeros.
Nos esta diciendo que los objetos pasajero forman parte del objeto medio de transporte. Pero, su ciclo de vida no esta atado al del objeto medio de transporte. Es decir si el Autobus se destruye los pasajeros pueden seguir existiendo independientemente, ( o por lo menos por eso rezaríamos)
Composición
Al igual que en la agregación, es una relación estructural pero se le suma, que tiene un método de destrucción de los objetos. Y a diferencia de la asociación, el ciclo de vida del objeto area está relacionado con el del objeto ruta. Es decir que si la ruta de viaje se levanta, las áreas que surgían a partir de ella desaparecen. También se puede leer como que una ruta tiene varias áreas de cobertura.
Mucho se ha discutido a cerca de las agregaciones y las composiciones, el debate es casi tan caliente como el de los include y extends de los casos de uso. Ya que algunos sostienen que los lenguajes orientados a objetos, tienen garbage collector, por lo que no necesitan métodos de destrucción de los objetos (relacionados a los ciclos de vida en la compocición). Y que la programación es la misma para las composiciones y las agregaciones, y que la diferencia es meramente conceptual entre una y otras. Es mas existen varias interpretaciones, pero la expuesta es a la cual yo adhiero.
Clase de Asociación
Es una Clase que surge de una multiplicidad de muchos a muchos, y fue incorporada en UML para dar soporte a este caso. Se sacan los atributos de las clases involucradas y se los incorpora a una clase a parte. Al igual que las anteriores hace referencia a una relación estructural. En el ejemplo son los objetos viaje y ruta
Realización
Es una relación de contrato con otra clase. Se la utiliza para implementar una interfaz. En lenguajes como java o php utilizamos la palabra reservada “implements”
public class Viaje implements Registrable{…}
Generalmente cuando no estamos seguros si “algo” es una interfaz o una clase abstracta, por que dibujaron los tag que hacen referencias a las interfaces, debemos ver la relación para saber.
Generalización
Es una relación de herencia. Se puede decir que es un relación “es un tipo de” ( IS-A ). En nuestro ejemplo: “un Autobus es un tipo de Medio de transporte”. Es entre una clase hija y su clase madre. En la codificación podemos encontrar la palabra “extends” que hace referencia a esta relación. Además podemos encontrar palabras claves tales como “this” y “super” ( Java ) o "self" y “parent” ( PHP ). Para darnos cuenta que existe una relación de este tipo involucrada.
public class Autobus extends MedioDeTransporte{…}
Dependencia
Es una relación de uso, es decir que una clase utiliza a otra. Y si esta ultima se altera, la anterior se puede ver afectada.
En código se suelen traducir principalmente como las clases donde se hace la instanciación de un objeto. En nuestro ejemplo la clase Viaje realiza los “new” de los distintos objetos. En este momento puede que te preguntes como puede hacer un new de una clase abstracta, jeje. No realiza los new de la clase abstracta, si no de sus hijas. Seria algo así como
MedioDeTransporte medio = new Autobus();
También se sostiene que este tipo de relación hace referencias, a los parámetros que se pasan en un método, bajo este concepto, en java, podría ser algo así como:
public void crearViaje(MedioDeTransporte medio){}
Por ultimo también se sostiene que podemos codificar esta relación realizando un “return” del tipo de dato en algún método.
Bueno espero haber limpiado algunas dudas, hay mucho para discutir sobre el asunto.
Saludos team.
Acá les dejo otro ejemplo, un poco más complejo y con los métodos de cada una de las clases para ser más especifico.
Anl. Ariel Diaz Molina.
Mas información sobre UML en la etiqueta Diseño.

jueves, mayo 29, 2008

Hora de izar velas

Cada cierto tiempo, los tambores empiezan a sonar en mi pecho. No se si es la necesidad de mantenerme en movimiento, o cobardía errante de aquel que se fuerza al desarraigo. Pero la verdad es que cuando suenan, es hora de marchar, de sacar mis uñas de aquello a lo cual me aferraba, es hora de armar bolsos, mirar hacia delante, hacia la esperanza, y dar ese paso de pie pasado.
Es por ello que unos días a tras presente mi renuncia en la empresa donde trabajaba. Y a la cual estaré agradecido. Más allá de los defectos que todas las organizaciones tienen, EDS me brindo la oportunidad de dar mis primeros pasos en la industria, de conocer gente muy pero muy interesante, de crecer. Pero no me voy por capricho, abulia, o cobardía. Me voy por que he recibido un reto por parte de la vida, me voy a liderar un proyecto, una gran oportunidad que los informáticos siempre esperamos, a otra empresa, a una más pequeña, más desafiante, mas calida, más arriesgada, más a mi medida.
Me voy para crecer, para aprender, para probarme a mi mismo, o simplemente para izar velas en el mar y marchar directo hacia la tormenta. Mi mano se levantó cuando alguien grito a lo lejos, entre desesperaciones y buscando un milagro.
No va a ser fácil, no tengo experiencia. Pero son estas las situaciones donde los hombres se convierten en bronce.
Tomaré la chancee.

viernes, mayo 16, 2008

¿Cual es nuestro miedo más profundo?

"Nuestro Miedo mas profundo no es el de ser inadecuados. Nuestro miedo más profundo es el de ser poderosos más allá de toda medida. Es nuestra luz, no nuestra oscuridad lo que más nos aterra. Nos preguntamos a nosotros mismos ¿Quien soy yo para brillar, para ser magnifico, talentoso, fabuloso? De hecho, ¿quien eres para no serlo? Tú eres un hijo de dios. El que te consideres menos no ayuda al mundo. No hay nada brillante en empequeñecerse para que otros no se sientan inseguros al lado tuyo. Todos estamos destinados a brillar, como brillan los niños. Nacimos para hacer manifiesta la gloria de dios a través de nosotros mismos. No yace solo en algunos, está en todos nosotros. Y cuando dejamos que nuestra propia luz brille, inconcientemente alentamos a otras personas para que hagan lo mismo. A medida que nos liberamos de nuestro propio miedo, nuestra sola presencia automáticamente libera a otros."

miércoles, marzo 26, 2008

El Campo y el Gobierno

Al igual que en todo conflicto surgen las síntesis superadoras ante las posturas encontradas. Esta es mi visión, no es la búsqueda de un amarillismo, o de una postura cobarde y mediera. Es que en relación al paro que nuestro campo esta llevando a cabo, no puedo darle la derecha total ni a unos ni a otros.
Por un lado el gobierno debería convertir en impuestos coparticipables, las retenciones que extrae de la industria agrícola. Por que sin ser esto, el dinero va a parar a agujeros negros, que solo contribuyen al sostenimiento de pesadas y deficitarias estructuras políticas. Además de ello debería diferenciar entre los pequeños y grandes productores, hablo como hombre que vino de una familia de campo, ya que los primeros trabajan contra el clima y los precios abusivos de una industria absorbida por gigantes. No es lo mismo aquel que tiene 500 o 1000 hectáreas con producciones millonarias, maquinaria de punta y seguro contra las contingencias climáticas, que aquel que produce a sombrero de mimbre y plegarias. Por que no se puede estar en tiempo de crisis asistiendo a los gigantes, y en los tiempos de abundancia, apresando a todos por igual. Es más, el estado debería, asistir al crecimiento de estos últimos para permitirles avanzar a lo largo del proceso productivo, ¡que los gigantes hagan lo que quieran!, que los pequeños se unan y procesen lo producido.
Por otro lado, el campo, a quien nuestra presidenta llamara plena de soberbia el piquete de la abundancia, no debe de olvidar los años malos, donde el estado asistía, y no debe perder de vista, que el resto de las personas, no somos solo rehenes, como siempre se dice a modo de muletilla, si no que estamos a la vanguardia en el campo de batalla. Éste tipo de cambio sojero y agrícola, ha dejado por debajo de la línea de la pobreza a millones de argentinos, y aún en día de hoy se hacen esfuerzos como país para mantenerlo competitivo a las exportaciones. El monocultivo especulativo y coyuntural esta destruyendo tanto los suelos, como las economías, ya que trae aparejado el desabastecimiento y la inflación, al intentar exportar absolutamente todo lo que se produce.
No tengo nada en contra del parque automotor de los piqueteros, ni de sus pañuelos de nostálgica oligarquía, es simplemente que al igual que el gobierno, ellos también son argentinos y su primer deber es con su país, ellos también deben responder, no es una relación de padres represivos he hijos conflictivos, es una relación de pares, de argentinos.
La salida no son políticas del momento, no son políticas de contingencia, no es pretender llenar las arcas de una, y atragantadas, en la abundancia, ni el gobierno, ni el campo. En el tironeo y el entrevero por el fruto, podemos terminar desplumando y matando a la gallina de los huevos de oro. Y allí todos vamos a terminar llorando el deceso.