miércoles, 30 de abril de 2014

consejos para programación en java – jsp

Una lista de tips que he ido aprendiendo con el tiempo y me han sido funcionales.
1) utilizar solo lo que se necesite: ya sea en java o en jsp las personas tienden a importar el paquete completo en vez de importar la o las clases necesarias; por ejemplo:
mala practica
import java.ultil.*;
buena practica
import java.ultil.List;
import java.ultil.HashMap;
import java.ultil.Date;
lo que sucede es que al decir * el carga todas las clases aunque sea muy poco utiliza mas tiempo del necesario.
2) utilizar solo lo que se necesite: ya sea en java o en jsp o en cualquier otro lenguaje evitar usar el * en las consultas a la bd ; por ejemplo:
mala practica
select * from Departamento;
buena practica
select campo1,campo2,campo3,campo4,campo5,campo6 from Departamento;
aunque tardemos un poco mas al usar el * el motor de base de datos hace una sub-consulta para conocer los campo, y en vez de ser una consulta son 2, ademas si la tabla tiene 20 campos los trae todos así necesitemos 1 o 2 y la consulta tardará mas.
3) en java o jsp, llamar los resultados de la BD por su nombre ejemplo:
mala practica
 public static Departamento load(ResultSet rs) throws SQLException {
  Departamento departamento = new Departamento();
  departamento.setId(rs.getInt(1));
  departamento.setNombre(rs.getString(2));
  departamento.setDescripcion(rs.getString(3));
  return departamento;
 }
buena practica
public static Departamento load(ResultSet rs) throws SQLException {
  Departamento departamento = new Departamento();
  departamento.setId(rs.getInt("ID"));
  departamento.setNombre(rs.getString("NOMBRE"));
  departamento.setDescripcion(rs.getString("DESCRIPCION"));
  return departamento;
 }
si por alguna razón el orden de los campos de la tabla, cambia esto no afectará la forma de cargar los datos.
4) Cerrar las conexiones, ya sea a los puertos paralelos, bases de datos, archivos en el disco duro, sockets:
muchas veces las conexiones se manejan por una pila y si no se cierran será imposible usar otra.
hace algún tiempo en una trabajo que estaba haciendo olvide cerrar el puerto paralelo y toco reiniciar el pc y deep freeze hizo lo suyo y a comenzar de nuevo.
5) por pequeña que sea la aplicación realiza el diseño, utiliza un patrón de desarrollo y escribe la documentación, en caso de que la aplicación crezca, será mucho mas fácil adaptarla, es traumático modificar una aplicación después de un tiempo (digamos 6 meses) y no recuerdas lo que hiciste.
6) existe un concepto de llave natural y llave primaria digamos la clase Estudiante la llave natural seria el numero de identificación y la llave primaria seria un secuencial automático de la base de datos ¿Por qué? porque si usamos identificación como llave primaria al momento que cambiemos esta identificación tendríamos que hacer una actualización en cascada, lo cual ya no seria una sola sentencia SQL sino 1+N, siendo N el numero de registros relacionados, (Pagos, Materias, Notas, Cursos, etc…). por el contrario si usamos una llave primaria totalmente independiente del objeto Estudiante podríamos modificar la identificación y no afectaría en nada a la integridad referencial.
para mi caso cree una clase llamada DTO que primero se vio de así
DTO.java
package org.ingenio;
import java.io.Serializable;
import java.lang.Comparable;
import java.sql.ResultSet;
import java.sql.SQLException;

public abstract class DTO implements Serializable,Comparable{

 private Long secuencial;

 protected Long getSecuencial(){
  return secuencial;
 }

 protected void setSecuencial(Long secuencial){
  this.secuencial=secuencial;
 }

 public abstract DTO load(ResultSet rs) throws SQLException;
 public abstract String toString();
}
y el ejemplo del DTO Estudiante seria:
Estudiante.java
package org.ingenio;

import java.io.Serializable;
import java.lang.Comparable;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Date;

public class Estudiante extends DTO{

 private String nombre = "";
 private String  apellido = "";
 private Integer identificacion = 0;
 private String codigo = "";
 private String curso = "";
 private Date fdn = new Date(new java.util.Date().getDate());
 private String foto="sinfoto.jpg";

 public Estudiante(){
   super();
 }

 public String getNombre(){
  return nombre;
 }
 public String  getApellido(){
  return apellido;
 }
 public Integer getIdentificacion(){
  return identificacion;
 }
 public String getCodigo(){
  return codigo;
 }
 public String getCurso(){
  return curso;
 }
 public Date getFdn(){
  return fdn;
 }
 public String getFoto(){
  return foto;
 }

 public void setNombre(String nombre ){
   this.nombre=nombre;
 }
 public void setApellido(String  apellido ){
   this.apellido=apellido;
 }
 public void setIdentificacion(Integer identificacion ){
   this.identificacion=identificacion;
 }
 public void setCodigo(String codigo ){
   this.codigo=codigo;
 }
 public void setCurso(String curso ){
   this.curso=curso;
 }
 public void setFdn(Date fdn ){
   this.fdn=fdn;
 }
 public void setFdn(java.util.Date fdn ){
   this.fdn=new Date(fdn.getTime());
 }
 public void setFoto(String foto ){
   this.foto=foto;
 }

 public String toString(){
  return(
  "DATOS:::EMPLEADO:::...\n"+
  "SECUENCIAL     : "+this.getSecuencial()+"\n"+
  "NOMBRE         : "+nombre+"\n"+
  "APELLIDO       : "+apellido+"\n"+
  "IDENTIFICACION : "+identificacion+"\n"+
  "DEPARTAMENTO   : "+codigo+"\n"+
  "CURSO          : "+curso+"\n"+
  "FDN            : "+fdn+"\n"+
  "FOTO           : "+foto+"\n"+
  "");
 }

 public DTO load(ResultSet rs) throws SQLException {
  Estudiante estudiante = new Estudiante();
  estudiante.setSecuencial(rs.getLong("SECUENCIAL"));
  estudiante.setNombre(rs.getString("NOMBRE"));
  estudiante.setApellido(rs.getString("APELLIDO"));
  estudiante.setIdentificacion(rs.getInt("IDENTIFICACION"));
  estudiante.setCodigo(rs.getString("DEPARTAMENTO"));
  estudiante.setCurso(rs.getString("CURSO"));
  estudiante.setFdn(rs.getDate("FDN"));
  estudiante.setFoto(rs.getString("FOTO"));
  return estudiante;
 }

 public int compareTo(Object estudiante){
  return (this.apellido).compareTo(((Estudiante)estudiante).getApellido());
 }
}
7) hablando de no afectar en nada a la integridad referencial, en aplicaciones donde varios usuarios tienen acceso y poder de edición sobre la misma información al mismo tiempo.
Digamos que varias personas se disponen a realizar cambios sobre un mismo registro al momento de realizar los cambios los primeros en guardar podría ver su trabajo afectado ya que el ultimo en guardar podría eliminar los cambios hechos por los anteriores.
para solucionar eso al momento de realizar la consulta Select que nos trae el registro adicionar pedimos el MD5 del registro:
Select
 secuencial,
 nombre,
 apellido,
 identificacion,
 codigo,
 curso,
 fdn,
 foto,
 md5(
   secuencial+
   nombre+
   apellido+
   identificacion+
   codigo+
   curso+
   fdn+
   foto
  ) as MD5
from
 Estudiantes
where
 secuencial=?
y al momento de realizar un delete o un update verificar este MD5
ejemplo
delete
from
 Estudiantes
where
 secuencial=?
 and
 md5(
   secuencial+
   nombre+
   apellido+
   identificacion+
   codigo+
   curso+
   fdn+
   foto
  )=?
y esto también afecto la clase DTO dejándola de esta manera:
DTO.java
package org.ingenio;
import java.io.Serializable;
import java.lang.Comparable;
import java.sql.ResultSet;
import java.sql.SQLException;

public abstract class DTO implements Serializable,Comparable{

 private Long secuencial;
 private String MD5;

 protected Long getSecuencial(){
  return secuencial;
 }
 protected String getMD5(){
  return MD5;
 }

 protected void setSecuencial(Long secuencial){
  this.secuencial=secuencial;
 }
 protected void setMD5(String MD5){
  this.MD5=MD5;
 }

 public abstract DTO load(ResultSet rs) throws SQLException;
 public abstract String toString();
}
y el DTO estudiante:
Estudiante.java
package org.ingenio;

import java.io.Serializable;
import java.lang.Comparable;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Date;

public class Estudiante extends DTO{

 private String nombre = "";
 private String  apellido = "";
 private Integer identificacion = 0;
 private String codigo = "";
 private String curso = "";
 private Date fdn = new Date(new java.util.Date().getDate());
 private String foto="sinfoto.jpg";

 public Estudiante(){
   super();
 }

 public String getNombre(){
  return nombre;
 }
 public String  getApellido(){
  return apellido;
 }
 public Integer getIdentificacion(){
  return identificacion;
 }
 public String getCodigo(){
  return codigo;
 }
 public String getCurso(){
  return curso;
 }
 public Date getFdn(){
  return fdn;
 }
 public String getFoto(){
  return foto;
 }

 public void setNombre(String nombre ){
   this.nombre=nombre;
 }
 public void setApellido(String  apellido ){
   this.apellido=apellido;
 }
 public void setIdentificacion(Integer identificacion ){
   this.identificacion=identificacion;
 }
 public void setCodigo(String codigo ){
   this.codigo=codigo;
 }
 public void setCurso(String curso ){
   this.curso=curso;
 }
 public void setFdn(Date fdn ){
   this.fdn=fdn;
 }
 public void setFdn(java.util.Date fdn ){
   this.fdn=new Date(fdn.getTime());
 }
 public void setFoto(String foto ){
   this.foto=foto;
 }

 public String toString(){
  return(
  "DATOS:::EMPLEADO:::...\n"+
  "SECUENCIAL     : "+this.getSecuencial()+"\n"+
  "NOMBRE         : "+nombre+"\n"+
  "APELLIDO       : "+apellido+"\n"+
  "IDENTIFICACION : "+identificacion+"\n"+
  "DEPARTAMENTO   : "+codigo+"\n"+
  "CURSO          : "+curso+"\n"+
  "FDN            : "+fdn+"\n"+
  "FOTO           : "+foto+"\n"+
  "");
 }

 public DTO load(ResultSet rs) throws SQLException {
  Estudiante estudiante = new Estudiante();
  estudiante.setSecuencial(rs.getLong("SECUENCIAL"));
  estudiante.setNombre(rs.getString("NOMBRE"));
  estudiante.setApellido(rs.getString("APELLIDO"));
  estudiante.setIdentificacion(rs.getInt("IDENTIFICACION"));
  estudiante.setCodigo(rs.getString("DEPARTAMENTO"));
  estudiante.setCurso(rs.getString("CURSO"));
  estudiante.setFdn(rs.getDate("FDN"));
  estudiante.setFoto(rs.getString("FOTO"));
  estudiante.setMD5(rs.getString("MD5"));
  return estudiante;
 }

 public int compareTo(Object estudiante){
  return (this.apellido).compareTo(((Estudiante)estudiante).getApellido());
 }
}
8) usar logs, que la aplicación lleve un registro de quien hace que en que momento, cosas que recomiendo guardar en logs:
  • Excepciones (cualquier excepción guardarla en el log)
  • Errores (cualquier error guardarla en el log)
  • Operaciones exitosas (registros, eliminaciones, ediciones, inicios de sesión)
de esta manera el administrador podrá conocer quien realizo una operación y en que momento la realizo, también es una herramienta que sirve para conocer el desempeño del software.
estaré actualizando, ahora no tengo tiempo para poner más
9) romper relaciones entre objetos:
en el modelo siempre hay relaciones:
  • 0…*
  • *…*
la idea es que esas relaciones no dependan de nuestros objetos de negocios y manejarlas a nivel de restricciones en la base de datos, ejemplo:
en este ejemplo un Departamento tiene muchos Empleados lo que nos dice que el código podría ser:
Departamento.java
package org;

public class Departamento{
 private Integer id;
 private String nombre;
 private String descripcion;
}
Empleado.java
package org;

public class Empleado{
 private Integer id;
 private String nombre;
 private String  apellido;
 private Integer identificacion;
 private Integer departamento_id;
 private Double sueldo = 0.0;
 private Double transporte = 0.0;
 private Date fdn = new Date(new java.util.Date().getDate());
}
Lo que busco resaltar es la linea 8 del POJO Empleado hay se almacena la referencia al Departamento lo que implica que si un mismo Empleado trabaja parte del tiempo en un Departamento y otra parte del tiempo en otro Departamento sería imposible de hacer y tocaría replantear el modelo.
lo correcto en este caso es hacer:
  • una clase extra que no hace parte de nuestro modelo
  • esta clase tendrá las referencias de correspondencia tanto como de departamento y empleado
  • manejamos la cantidad de relaciones entre empleado y departamento por restricciones en la base de datos
  • si en el caso que sea solo una: decimos que el id de empleado en la tabla departamento_empleado es único
  • en caso que sea más solo sería quitar esa restricción
nuestro código sería algo como
Departamento.java
package org;

public class Departamento{
 private Integer id;
 private String nombre;
 private String descripcion;
}
Empleado.java
package org;

public class Empleado{
 private Integer id;
 private String nombre;
 private String  apellido;
 private Integer identificacion;
 private Double sueldo = 0.0;
 private Double transporte = 0.0;
 private Date fdn = new Date(new java.util.Date().getDate());
}
DepartamentoEmpleado.java
package org;

public class DepartamentoEmpleado{
 private Integer id;
 private Integer departamento_id;
 private Integer empleado_id;
}
Lo que se pretende es que nuestro modelo sea un poco más escalable y menos restrictivo.

No hay comentarios.:

Publicar un comentario