jueves, 31 de marzo de 2011

[TALLER] Aplicación de patrones de diseño en proyectos individuales

Ahora la implementación de los patrones de diseño, primero comenzare con el Singleton, que recordemos, es para crear objetos solo dentro de la misma clase.

Si en el diagrama no se ve el constructor es por que en este patrón se declara con atributo privado. Aquí el código:

package Organidatabase;

import java.util.Scanner;

public class Notas{
 
 private Notas nuevo = new Notas();
 String nota;
  
  private Notas () {
          System.out.println("Escriba su nota: ");
          Scanner a = new Scanner(System.in);
          nota=a.next();
     }
  
  public Notas new_note() {
   return nuevo;
  }


}
Podemos ver en el código que la creación de un nuevo objeto se restringe solamente a su clase.

Ahora veremos la clase Eventos, donde pretendo utilizar el patrón de diseño Composite.

Puede notarse que en la clase Eventos se están aplicando dos patrones de diseño como lo había dicho en mi entrada de clase, aplican ambas.

package Organidatabase;   
import java.util.ArrayList;
   import java.util.Scanner;

   public abstract class Eventos extends Database{
    String dia;
    String mes;
    String año;
    String hora;
    String lugar;
     
     public Eventos (String dia, String mes, String año, String hora, String lugar) {
      this.dia = dia;
      this.mes = mes;
      this.año = año;
      this.hora = hora;
      this.lugar = lugar;
     }
     
     public abstract void new_event(Eventos e);
       
   }

   abstract class Ev_priv extends Eventos{
    
    private ArrayList hijo = new ArrayList();
    public Ev_priv(String dia, String mes, String año, String hora, String lugar){
     super(lugar, hora, año, mes, dia);
    }
    
    public void new_event(Ev_priv e){
      hijo.add(e);
      System.out.print("Introduzca un fecha: ");
    Scanner a = new Scanner(System.in);
    dia=a.next();
    mes=a.next();
    año=a.next();
    System.out.print("Introduzca la hora: ");
    hora=a.next();
    System.out.print("Introduzca el lugar: ");
    }
}

   abstract class Ev_pub extends Eventos{
     
     ArrayList hijo = new ArrayList();
     public Ev_pub(String dia, String mes, String año, String hora, String lugar){
      super(lugar, hora, año, mes, dia);
     }
     
     public void new_event(Ev_pub e){
       hijo.add(e);
       System.out.print("Introduzca un fecha: ");
     Scanner a = new Scanner(System.in);
     dia=a.next();
     mes=a.next();
     año=a.next();
     System.out.print("Introduzca la hora: ");
     hora=a.next();
     System.out.print("Introduzca el lugar: ");
     }
   }
Por ahora estos son los patrones de diseño que utilizo, sin embargo me he dado cuenta que podemos utilizar muchos patrones en un mismo proyecto por lo que tal vez estos no sean los unicos.

Patrones de diseño


Esta semana hablamos sobre patrones de diseño. Primero que nada, un patrón de diseño es una base para alguna solución especifica para problemas típicos en el desarrollo de software. 

Existen tres tipos de patrones de diseño, los creacionales, los estructurales y los de comportamiento.

Patrones creacionales.

Los patrones creacionales soportan la tarea mas común que tiene la programación orientada a objetos: La creación de las instancias de objetos en un sistema.

Ejemplo - Singleton:
Segun wikipedia:

"El patrón de diseño singleton (instancia única) está diseñado para restringir la creación de objetos pertenecientes a una clase o el valor de un tipo a un único objeto.
Su intención consiste en garantizar que una clase sólo tenga una instancia y proporcionar un punto de acceso global a ella."

El patrón Singleton se implementa mediante una clase con un constructor privado. Existirá un método que creará una instancia del objeto llamando al constructor sólo si todavía no existe ninguna.

A pesar de que es ampliamente utilizado, existe una corriente contraria al uso de este patrón debido a los problemas que introduce.

  • Los Singletons normalmente se usan para proporcionar un punto de acceso global para un servicio.
  • Los Singletons permiten limitar la creación de los objetos.
  • Los Singletons promueven el acoplamiento fuerte entre clases.
  • Los Singletons mantienen el estado hasta la finalización del programa.


Patrones estructurales.

Los patrones estructurales están relacionados con cómo las clases y los objetos se combinan para dar lugar a estructuras más complejas.

Ejemplo - Composite:
Segun wikipedia:

"El patrón Composite sirve para construir objetos complejos a partir de otros más simples y similares entre sí, gracias a la composición recursiva y a una estructura en forma de árbol.
Esto simplifica el tratamiento de los objetos creados, ya que al poseer todos ellos una interfaz común, se tratan todos de la misma manera."

Compone objetos dentro de unas estructura arborescente con el que se representa una jerarquía parte-todo. El uso de este patrón permite tratar objetos individuales y composiciones uniformemente.

La utilización de recursos podría ser un problema, utiliza una estructura de tipo recursiva que podría generar un alto consumo de memoria, sin embargo fue pensado para tareas no repetitivas.

Esto ultimo debido a que el objeto complejo es independiente de los mas simples una vez creado.

Patrones de comportamiento.

Estos patrones de diseño están relacionados con algoritmos y asignación de responsabilidades a los objetos. Los patrones de comportamiento describen no solamente patrones de objetos o clases sino también patrones de comunicación entre ellos.

Ejemplo - Command:
Según wikipedia:

“Este patrón permite solicitar una operación a un objeto sin conocer realmente el contenido de esta operación, ni el receptor real de la misma. Para ello se encapsula la petición como un objeto, con lo que además se facilita la parametrización de los métodos.”

Encapsula peticiones como objetos, así permite parametrizar clientes con diferentes peticiones, auditar peticiones y deshacer operaciones. El Patrón permite:
  • Encapsular un mensaje como un objeto, con lo que podemos gestionar colas o registros de mensajes y deshacer operaciones.
  • Soportar restaurar el estado a partir de un momento dado.
  • Ofrecer una interfaz común que permita invocar las acciones de forma uniforme y extender el sistema con nuevas acciones de forma más sencilla.
Proyecto.


De estos patrones, puedo utilizar perfectamente el patrón Singleton:


La clase Eventos.java se utiliza para crear eventos del usuario, mediante el Singleton aseguramos que solo exista una sola instancia, ya que mantiene su estado asta la finalización del programa, los eventos se mantienen, y el uso limitado de objetos asegura su creacion y despues guardarlo en la base de datos.


La clase Notas.java aplica perfectamente, ya que su unico proposito es el de guardar texto en una base de datos.


Oviamente el patrón Composite queda perfectamente en la clase Eventos.java, puedo generar objetos de distintos tipos como lugar, fecha, hora, cada uno de estos objetos se obtienen de algun metodo, basandose en la fecha actual del sistema o la hora, o bien seleccionando de una lista el lugar. Unidos estos puedo generar un objeto de tipo evento compuesto de varios objetos mas simples.


Algunas clases mas complejas como Database.java (encargada de conección con la base de datos) o el propio main, pueden utilizar de una manera sencilla el patrón Command, ya que mantiene en memoria el usuario activo, de esta manera al seleccionar otra materia no habra que introducir de nuevo un usuario ni contraseña, ni volvera a reconectar a la base de datos para obtener información.

jueves, 24 de marzo de 2011

Presentaciones de diagramas de proyectos

Video explicativo sobre los diagramas de clases y de secuencia de mi proyecto:

[TALLER] Implementación de proyectos individuales

En esta entrada, explicare la función de mi programa a estas alturas, despues de un tiempo logre que funcionara, aunque para esta ocación, he modificado un poco el diseño para que funcione adecuadamente, ya que aún falta código.

Bueno, para empezar queria comentar que mi programa puede funcionar solo con la clase "Database", que es la que se encarga de conectar la base de datos, ya que la mayoria de las clases son solo para acomodar la información de una manera más organizada, por lo que necesita más código y tiempo, sin embargo utilizar la consola me ahorra ese codigo y mi programa sigue igual de funcional.



En esta imagen se muestra la ruta de mi programa, como pueden ver es un .jar, una ventaja de tener un .jar es que no necesita una orden específica, solo es correr el ejecutable y ya.



Como muestra la imagen antrior, la primer función de este programa es buscar un usuario y contraseña para acceder a los datos, el programa compara los strings dados por el usuario con la columna ya designada, puesto que el nombre de usuario es un número único, solo habra una coincidencia.

Lo siguiente sera comparar el string de contraseña, que para esto deberá esta en la misma fila que el nombre de usuario.


Seleccionamos un día de la semana que aparece en el programa y lo introducimos, lo siguiente sera seleccionar el horario de la materia. Se supone que esto es respetando minusculas y mayusculas, pero por alguna razón aveces no es necesario hacer esto, podemos introducir el dia y el horario sin respetar mayusculas.


Se puede observar que se ven todos los datos al dar enter, y despues pide si queremos repetir el proceso,
utilizando un while, una variable booleana y un switch logré hacer esto.

Aqui esta el código utilizado para este programa:

package Organidatabase;

import java.io.Console;
import java.io.IOException;

import javax.swing.UIManager;

public class Main {

 public static void main(String[] args) throws IOException{
  
  boolean selec=true;
  
  Console terminal = System.console();
        if (terminal==null ) {
            System.err.println("No puedo obtener la consola.");
            return;
        }
        
  Database db = new Database();
  String mat = new String (terminal.readLine("Ingresar Usuario: "));
  String pass= new String (terminal.readPassword("Ingresar contraseña: "));
  
  while(selec == true|| selec ==true){
   db.showAll(mat, pass);
   System.out.print("¿Desea ver otra materia?(S/N): ");
   char sel= (char) System.in.read();
   
    switch(sel) {
    case 's': 
     selec = true;
        break;
        
    case 'S':
     selec=true;
     break;
    
    default:
     selec = false;
        break;
   }
   
   
  }
 }
 
}
package Organidatabase;

import java.sql.*;
import java.util.Scanner;

public class Database {
 
 Alias a = new Alias();
 
 String aux;
 String aux2;
 
 PreparedStatement stmt = null;
 ResultSet rs=null;
 
 public final static String drv ="com.mysql.jdbc.Driver";
 public final static String db ="jdbc:mysql://localhost:3306/Organischema";
 public final static String user ="???";
 public final static String pword="???";
 
 Connection ct;
 public Statement st;

 public String dayselection;
 public String subselection;
 
 public Database(){
  try{
   Class.forName(drv);
   ct =DriverManager.getConnection(db, user, pword);
   st =ct.createStatement();
   System.out.println("Conección exitosa.");
  }catch(Exception e){
   System.out.println("No se pudo conectar a la base de datos.");
  }
 }
 
 public void showAll(String matt, String pass) {
  String dia = new String();
  Scanner a = new Scanner(System.in);
  System.out.println("Introduzca un dia (Lu, Ma, Mi, Ju, Vi, Sa): ");
  dia = a.next();
  dayselection = dia;
  try{
   do{
    stmt = ct.prepareStatement("SELECT * FROM Alumnos, "+dia+" WHERE  Alumnos.idAlumnos = ? AND Alumnos.idPass = ? AND Alumnos.idAlumnos = "+dia+".idAlumnos");
    /*String matt = a.next();
    String pass = a.next();*/
    stmt.setString(1,matt);
    stmt.setString(2, pass);
    rs = stmt.executeQuery();
    if(rs.next()){
     System.out.println("Seleccione Horario: ");
     String sub = a.next();
     System.out.println(rs.getString(sub));
     subselection=rs.getString(sub);
     fill_data();
     rs.close();
    }
    else{
     System.out.print("Error");
     rs.close();
    }
   }while(rs.isClosed()==false);
  }catch(Exception e){
   System.out.println("No se pudo realizar la consulta.");
  }
 }
 
 public void fill_data(){
  try{
   stmt = ct.prepareStatement("SELECT * FROM "+subselection+", "+dayselection+" WHERE "+dayselection+".idAlumnos = "+subselection+".idAlumnos");
   rs = stmt.executeQuery();
   while(rs.next()){
    for(int i=2; i<=9; i++){
     a.phrs(i);
     if(rs.getString(i) == null){
      System.out.println("Sin Datos");
     }
     else{
      System.out.println(rs.getString(i));
     }
    }

   }
  }catch(SQLException i){
   i.printStackTrace();
  }
 }
 
 public Statement getSt(){
  return st;
 }

}
Las palabras como "Profesor" o "Calificación" son distintos alias, esto quiere decir que los nombres de las columnas en la base de datos tienen nombres cortos, y con una clase temporal logre colocar estos alias a base de condiciones.
package Organidatabase;

import java.util.*;

public class Alias {
 Database d;
 int dia;
 public Alias(){
  
 }
 
 public void phrs(final int a){
  
  if(a==2)
   System.out.print("Profesor: ");
  if(a==3)
   System.out.print("Examen 1: ");
  if(a==4)
   System.out.print("Examen 2: ");
  if(a==5)
   System.out.print("Faltas: ");
  if(a==6)
   System.out.print("Tareas: ");
  if(a==7)
   System.out.print("Tareas no cumplidas: ");
  if(a==8)
   System.out.print("Total de tareas: ");
  if(a==9)
   System.out.print("Promedio: ");
 }

 public int day(){
  final Calendar calendario = Calendar.getInstance();
  dia =calendario.get(Calendar.DAY_OF_WEEK);
  return dia;
 }
 

}
Esta clase temporal vendria sustituyendo las clases que ya tenia planteadas, ya que lo unico que se supone que harían es mostrar información en una interfaz grafica y acomodarla.
Aqui hay un video demostrando el funcionamiento del programa: