Issuu on Google+

Programación II

Práctica del Taller de Reparaciones (Abril 2011)

pág:1

Programación II  Práctica del Taller de Reparaciones  Dpto. LSIIS. Unidad de Programación  Objetivo: El objetivo de esta práctica es la familiarización del alumno con la programación orientada a objetos en Java y el uso de TADs clásicos. Evaluación: La práctica se podrá realizar en grupos de dos alumnos o de forma individual. La nota que se obtenga en esta práctica tendrá un peso de 25% en la nota final de la asignatura. Se mantendrá el mismo enunciado de la práctica para la convocatoria extraordinaria. Entrega: La práctica se entregará a través de la página web: http://maui.ls.fi.upm.es/entrega/ La práctica entregada debe compilar en la versión 1.6 del J2SE de Oracle/Sun. En el momento de realizar la entrega, la práctica será sometida a una serie de pruebas que deberá superar para que la entrega sea admitida. El alumno dispondrá de un número máximo de diez entregas. Ahora bien, si el alumno realiza más de cinco entregas, se le restará un punto en la nota final de la práctica. Asimismo, por el hecho de que la práctica sea admitida, eso no implicará que la práctica esté aprobada. El fichero a entregar será practica.jar con la estructura dada y sólo con el código fuente y la documentación generada por javadoc. Grupos: Los grupos estarán formados por dos alumnos. Los alumnos deben estar matriculados y dados de alta en el sistema de entrega (maui) antes de proceder a realizar el registro del grupo. Ninguno de los dos alumnos deberá haber realizado entrega alguna de la práctica antes de definir el grupo. El grupo se crea por medio de la URL:

http://maui.ls.fi.upm.es/entrega/CrearGruposTallerReparaciones.html Una vez creado el grupo sólo podrá realizar la entrega el alumno que se pone en primer lugar en el grupo. Fecha límite: Es el día 18‐05‐2011 a las 10:00 AM. Código Auxiliar: La realización de esta práctica requiere la utilización de los ficheros auxiliares que se pueden encontrar dentro del fichero practica.jar que acompaña a este enunciado. Las implementaciones de los TADs que se pueden utilizar se encuentran en el fichero TADS.jar que podrán encontrar en moodle en materiales de la asignatura/lib/TADs. Autoevaluación: El alumno debe comprobar que su ejercicio no contiene ninguno de los errores explicados en el apartado 5 de este enunciado. Si el ejercicio contiene alguno de estos errores, se calificará como suspenso. Detección Automática de Copias: Cada práctica entregada se comparará con el resto de prácticas entregadas en todos los grupos de la asignatura. Esto se realizará utilizando un sofisticado programa de detección de copias. Consecuencias de haber copiado: Todos los alumnos involucrados en una copia, bien por copiar o por ser copiados, quedan inhabilitados para presentarse a todas las convocatorias de examen del presente curso, además de la posible apertura de expediente académico.


Programación II

Práctica del Taller de Reparaciones (Abril 2011)

pág:2

En esta práctica se pide implementar una simulación del funcionamiento de un taller de reparaciones de coches. Más concretamente, se pretende simular la asignación de reparaciones a los mecánicos y el trabajo realizado por los mecánicos al reparar los coches. Dentro de esta simulación destacan los siguientes dos tipos de objetos: el taller propiamente dicho, y los mecánicos que trabajan en él. El taller es el principal objeto de esta simulación, y es el encargado de asignar reparaciones a sus mecánicos. A grandes rasgos, el funcionamiento del taller que se pretende simular será el siguiente. Cuando llegue al taller un coche que requiere una reparación, el (objeto) taller debe intentar asignar dicha reparación a un (objeto) mecánico. Si, por los motivos que veremos a continuación, no existe ningún mecánico disponible para hacerse cargo de esa reparación, la reparación quedará en una cola de espera hasta que un mecánico pueda hacerse cargo de ella. Si, por el contrario, existe un mecánico disponible (bajo las condiciones que se explicarán más adelante), el taller asignará la reparación a dicho mecánico. A continuación, se va a explicar de manera más detallada en qué orden se van a realizar las reparaciones que vayan llegando al taller.

1. Asignación y Realización de Reparaciones  El taller distingue entre dos tipos de reparaciones, normales y con prioridad. Una reparación normal va a ser un tipo de reparación cuya realización puede llevar muchas horas. Por otro lado, una reparación con prioridad es un tipo de reparación que, al contrario que una reparación normal, se puede realizar en poco tiempo. Una reparación con prioridad tendrá asociada una prioridad que representaremos mediante un valor numérico comprendido entre 1 y MAXPRIORIDAD, en donde el valor 1 representará la prioridad mínima, y el valor MAXPRIORIDAD la máxima. Esta prioridad será tenida en cuenta por los mecánicos y el taller a la hora de decidir si una reparación es más urgente que otra. El tiempo requerido (ciclos de trabajo) por una reparación con prioridad P es igual a (MAXPRIORIDAD+1) ‐ P. Las reparaciones tienen un coste en función del número de ciclos que lleva la reparación, y la prioridad de la misma. En la siguiente tabla se detallan los costes de las reparaciones según su tipo: Tipo de

Tiempo requerido

Reparación

(en ciclos de trabajo)

R. con Prioridad P

MAXPRIORIDAD+1‐P

R. Normal

ciclos (dependen de cada 15*ciclos/3+25*2*ciclos/3 reparación)

Coste en € 30*ciclos*P/2+25*ciclos/2+P*10


Programación II

Práctica del Taller de Reparaciones (Abril 2011)

pág:3

La asignación y realización de una reparación que llega al taller se tratará de la siguiente manera atendiendo al tipo de la reparación: 

Si la reparación es normal, el taller comprobará primero si ya hay otras reparaciones normales o con prioridad pendientes de ser asignadas y, si es así, guardará la reparación en la cola de reparaciones normales. En caso contrario, buscará un mecánico que esté desocupado y le asignará dicho mecánico. Si hay más de un mecánico desocupado, se le asignará al que tenga menor identificador. En cambio, si no hay ningún mecánico desocupado, la reparación se guardará en la cola de reparaciones normales en el objeto taller. Si la reparación es con prioridad, el taller actuará de la siguiente manera: 1. Comprobará primero si ya hay otras reparaciones con una prioridad igual o mayor pendientes de ser asignadas y, si es así, guardará la reparación en la cola de reparaciones que tienen su misma prioridad. 2. En caso contrario, buscará un mecánico para asignarle la reparación que cumpla una de las siguientes condiciones por el orden de preferencia en el que se enumeran a continuación: a. Que esté desocupado. Si hay más de uno, se le asignará al que tenga menor identificador. b. Que esté realizando una reparación normal. Si hay más de uno, se le asignará al que tenga menor identificador. c. Que esté realizando una reparación con una prioridad menor que la que se pretende asignar. Si hay más de un mecánico que cumple esta condición, se le asignará al que esté realizando una reparación de menor prioridad y, en caso de empate, al que tenga menor identificador. Ahora bien, si todos los mecánicos están realizando una reparación más urgente que la reparación que se pretende asignar, esta reparación se guardará en una cola para reparaciones con su misma prioridad existente en el objeto taller. Si un mecánico estaba ocupado y recibe la asignación de una nueva reparación (siempre más urgente que la que estaba realizando), pospondrá la reparación que esté realizando, y se pondrá a trabajar inmediatamente en la reparación que se le acaba de asignar.

2. Simulación del trabajo de los mecánicos  La jornada laboral de un mecánico estará dividida en un cierto número de ciclos de trabajo. En un ciclo de trabajo cada mecánico ocupado con una reparación progresará en la realización de dicha reparación. Cada reparación requerirá un cierto número de ciclos de trabajo para ser completada. Dentro de cada objeto reparación se mantendrá su estado de progreso, que será decrementado en cada ciclo de trabajo. Por lo tanto, cuando dicho progreso alcance el valor cero, eso significará que la reparación ha sido completada.


Programación II

Práctica del Taller de Reparaciones (Abril 2011)

pág:4

Con el fin de que todos los mecánicos ocupados avancen un ciclo de trabajo en sus respectivas reparaciones, el taller le pedirá a cada mecánico ocupado que trabaje un ciclo de trabajo en la reparación que tenga entre manos. Si tras trabajar un ciclo el mecánico termina la reparación, se lo indicará al objeto taller. Entonces, el taller comparará la siguiente reparación pendiente de asignar R1, si existe, con la siguiente reparación R2 que tiene pendiente el mecánico (pospuesta previamente), si existe. Se podrá dar entonces uno de estos tres casos:  

Si no le quedan reparaciones por asignar al taller, o R1 es igual de prioritaria o menos prioritaria que R2, se dejará que el mecánico realice R2, es decir, la reparación más prioritaria que tiene pendiente. Si le quedan reparaciones pendientes al mecánico, y R1 es más prioritaria que R2, se la asignará al mecánico y éste pospondrá la que iba a iniciar (R2). Si el taller tiene que elegir entre varias con el mismo nivel de prioridad, asignará al mecánico la que lleve más tiempo esperando, es decir, la primera de la cola de espera asociada a este nivel de prioridad. Si no le quedan reparaciones pendientes al mecánico, entonces el taller le asigna R1 al mecánico, sea R1 normal o prioritaria.

3. Diseño de la aplicación  El simulador del taller es una aplicación que toma su entrada de un fichero de eventos de entrada, y genera como salida un fichero de salida que contendrá los eventos de entrada y las salidas generadas por el programa para esos eventos de entrada. Cada evento de entrada que se lee, se escribe en el fichero de salida y, a continuación, se procesa dicho evento de entrada. Como resultado de ese procesamiento, se generan uno o más eventos de salida, que se escriben en el fichero de salida. En el apartado “Formato de los Ficheros de eventos” se explica el formato de estos dos ficheros.

SupervisorTrabajo Interfaz que establece los servicios que se utilizarán para supervisar el trabajo de los mecánicos. Declara los servicios: 

notificarReparacionFinalizada(mecanico : taller.Mecanico, reparacion : Reparacion) : void: Que será invocado por un mecánico cuando concluye una reparación, para avisar a su supervisor de que ha terminado con la reparación pasada como parámetro. Este método se encarga de generar la factura y mandarla al HistoricoReparaciones y de asignar una nueva reparación al mecánico si hubiera reparaciones pendientes y fuera posible. notificarProgresoReparacion(mecanico : taller.Mecanico, reparacion : Reparacion) : void: Método al que llama el mecánico cada vez que concluye un ciclo de trabajo y no ha terminado la reparación en ese ciclo.

Taller Clase que implementa la gestión de las reparaciones y los mecánicos asignados al taller. Proporciona una serie de servicios. Estos son:


Programación II   

Práctica del Taller de Reparaciones (Abril 2011)

pág:5

Constructor: Recibe como parámetros el número de mecánicos que hay en el taller y la prioridad máxima de una reparación que puede admitir. avanzarTrabajo: Método que se invoca para indicar que empieza un nuevo ciclo de trabajo. Debe indicar a cada mecánico ocupado que realice un ciclo de trabajo. recibirReparacionPrioritaria: Método que se encarga de recepcionar una reparación con prioridad y asignársela a un mecánico, o ponerla en espera si no hay mecánicos disponibles. La asignación de mecánico se explica en el apartado “Asignación y Realización de Reparaciones”. recibirReparacionNormal: Método que se encarga de recepcionar una reparación normal y asignársela a un mecánico, o ponerla en espera si no hay mecánicos desocupados. La asignación de mecánico se explica en el apartado 1.

Mecanico Clase que representa a un mecánico del taller. Proporciona los siguientes servicios:         

Constructor: Recibe como parámetros el identificador del mecánico y el supervisor que tiene asignado. asignarReparacion: Se le asigna la reparación al mecánico. PRE: El mecánico puede atender esta reparación según lo estipulado en “Asignación y Realización de Reparaciones”. getCiclosPendientesReparacionAsignada: Retorna los ciclos pendientes de la reparación asignada al mecánico. PRE: Mecánico ocupado getEstado: Método que retorna el estado del mecánico. getIdMecanico: Retorna el identificador del mecánico getIdReparacionAsignada: Retorna el identificador de la reparación asignada. PRE: Mecánico ocupado. getPrioridadReparacionAsignada: Método que retorna la prioridad de la reparación que está haciendo. Retorna 0 si la reparación es normal, en otro caso retorna la prioridad. PRE: Mecánico ocupado. tratarCiclo: Si el mecánico está ocupado, trabaja sobre la reparación que tiene asignada y llama al método del supervisor correspondiente. En caso contrario no hace nada, por estar libre. puedoHacerReparacion: Método que se utiliza para consultar al mecánico si puede realizar la reparación que recibe como parámetro. Si puede realizarla retorna cierto, en caso contrario retorna falso.

Reparacion Esta clase define la generalización de las reparaciones que se pueden realizar en el taller. Es una clase abstracta, de la que existen dos especializaciones: ReparacionNormal y ReparacionPrioridad. Esas dos últimas proporcionan la implementación específica del servicio calcularCoste, según la fórmula descrita en el apartado “Asignación y Realización de Reparaciones”. Los servicios que proporciona son:


Programación II   

Práctica del Taller de Reparaciones (Abril 2011)

pág:6

calcularCoste: Método abstracto que determina el coste de la reparación. Este método se encuentra implementado en ReparacionNormal y ReparacionPrioridad. getCiclosPendientes: Retorna los ciclos pendientes de la reparación. realizar: Indica a la reparación que se trabaja sobre ella un ciclo de trabajo. Si tras realizar el ciclo de trabajo se completa la reparación, devuelve cierto, y en caso contrario devuelve falso. PRE: Quedan ciclos pendientes.

Se van a distinguir dos tipos de eventos de entrada: 1. Llegada de un coche al taller para ser reparado: debe ser procesada mediante una llamada al método recibirReparacion() o al método recibirReparacionNormal(). 2. Orden a los mecánicos para ejecutar un ciclo de trabajo: debe ser procesada mediante la correspondiente llamada al servicio de mecánico:  tratarCiclo: Si el mecánico está ocupado, trabaja sobre la reparación que tiene asignada. En caso contrario no hace nada, por estar libre. Si al tratar el ciclo concluye la reparación, pasa al estado que corresponda, para lo cual debe analizar las reparaciones pendientes si las tuviera y notifica a su supervisor que ha terminado la reparación asignada (NotificarReparacionFinalizada(mecanico : taller.Mecanico, reparacion : Reparacion) : void). Tras notificar al supervisor pasará al estado que le corresponda: Libre (no se le han asignado reparaciones y no tiene reparaciones pendientes) u Ocupado (tiene reparaciones pendientes o le acaba de asignar una nueva el supervisor). Por otra parte, si al tratar el ciclo no concluye la reparación, notifica a su supervisor que ha progresado con la reparación (NotificarProgresoReparacion (mecanico: taller. Mecanico, reparacion : Reparacion) : void). El supervisor cuando recibe una notificación de una reparación concluida emite la factura de la reparación, y si quedan reparaciones por asignar, comprueba si se le puede asignar al mecánico que ha concluido la reparación. Es posible que el supervisor no pueda asignarle la reparación porque el mecánico tiene reparaciones más prioritarias pendientes. Por otro lado, tanto los eventos de entrada como los de salida se registrarán en el fichero de salida mediante llamadas a métodos de la clase HistoricoReparaciones. Todas estas llamadas se deben realizar desde la clase Taller. En el diagrama de clases que se incluye a continuación se muestran en color amarillo las clases que se proporcionan junto con el enunciado, y que el alumno no tendrá que implementar. Se han omitido a propósito en el diagrama ciertos atributos de las clases Taller y Mecanico.


Programaciรณn II

Prรกctica del Taller de Reparaciones (Abril 2011)

pรกg:7

Visual Paradigm for UML Community Edition [not for commercial use]

Simulacion

HistoricoReparaciones

<<Interface>> SupervisorTrabajo

Notifica

#notificarReparacionFinalizada(mecanico : Mecanico, reparacion : Reparacion) : void #notificarProgresoReparacion(mecanico : Mecanico) : void

TEstado = (desocupado, ocupado) 1 1

<<realize>>

Mecanico -estado : TEstado -idMecanico : int -supervisor : SupervisorTrabajo ~tratarCiclo() : void +asignarReparacion(rep : Reparacion) +getEstado() : TEstado +getIdMecanico() : int +puedoHacerReparacion(r : Reparacion) +getIdReparacionAsignada() : int +getCiclosPendientesReparacionAsignada() +getPrioridadReparacionAsignada() +Mecanico(id : int, supervisor : SupervisorTrabajo) 1

1

~terminaReparacion(reparacion : int, mecanico : int) : void ~trabaja(reparacion : int, mecanico : int, ciclosPendientes : int) : void ~asignaReparacion(reparacion : int, mecanico : int, ciclosPendientes : int) : void ~llegaCoche(reparacion : Reparacion) : void ~avanzaCicloTrabajo() : void ~registraEstadoMecanico(mecanico : int, estado : TEstado) : void ~emiteFactura(idTecnico : int, idReparacion : int, coste : double) : void

1

asigna reparaciones 1

registra evento

Taller

1 -mecanicos : Mecanico[] -historico : HistoricoReparaciones

+avanzarTrabajo() +recibirReparacionPrioritaria(idReparacion : int, prioridad : int) +recibirReparacionNormal(idReparacion : int, ciclosRequeridos : int) #notificarReparacionFinalizada(mecanico : Mecanico, reparacion : Reparacion) : void +Taller(mecanicosEnTaller : int, prioridadMaxima : int, ficheroLog : string) #notificarProgresoReparacion(mecanico : Mecanico) : void

1

1 tiene pendientes sin asignar 0..*

TReparacion = (normal, prioritaria)

Reparacion realiza

tiene pendientes

-ciclosPendientes : int 0..1 -id : int -ciclosRequeridos : int 0..*

+realizar() : boolean +getCiclosPendientes() : int +calcularCoste() : double

ReparacionNormal +calcularCoste() : double

ReparacionPrioridad -prioridad : int +calcularCoste() : double


Programación II

Práctica del Taller de Reparaciones (Abril 2011)

pág:8

4. Formato de los Ficheros de eventos  El fichero de eventos de entrada está dividido en dos partes. La primera parte está formada por las siguientes dos líneas: Mecanicos=3 Prioridades=4 En las cuales se establece para la ejecución de la simulación que se va a iniciar: el número de mecánicos que van a participar y el número de prioridades que se van a utilizar. La segunda parte del fichero contiene una secuencia de eventos de entrada separados por saltos de línea. Se van a distinguir dos tipos de eventos de entrada: 1. Llegada al taller de un coche que necesita ser reparado: Coche id tipoReparacion (prioridad | ciclos)1

En donde el id es un entero que representa el identificador de la reparación, y tipoReparacion es un valor del tipo enumerado (normal, prioritaria). Si tipoReparacion es igual a prioritaria, entonces se utilizará el argumento opcional prioridad, que es un entero comprendido entre 1 y la prioridad máxima. Si tipoReparacion es igual a normal, entonces se utilizará el argumento opcional ciclos, que es un valor entero mayor que cero . 2. Generación de un ciclo de trabajo: Trabajar2

El fichero de salida contiene un registro de los eventos de entrada y de salida ordenados cronológicamente y separados por saltos de línea. Se van a distinguir los siguientes tipos de eventos de salida: 1. El taller asigna la reparación con id1 al mecánico con id2: Asigna reparacion id1 a mecanico id2. Ciclos de reparación: c3

2. El mecánico con id1 ha terminado la reparación con id2. En este caso se registran dos salidas: Termina mecanico id1 reparacion id24 La reparacion id2 realizada por el mecanico id1 tiene un coste de f €5

1 Se utiliza el método llegaCoche de la clase HistoricoReparaciones 2 Se utiliza el método avanzaCicloTrabajo de la clase HistoricoReparaciones 3 Se utiliza el método asignaReparacion de la clase HistoricoReparaciones 4 Se utiliza el método terminaReparacion de la clase HistoricoReparaciones 5 Se utiliza el método emiteFactura de la clase HistoricoReparaciones


Programación II

Práctica del Taller de Reparaciones (Abril 2011)

pág:9

3. Cada vez que se procese un evento de entrada Trabajar, para cada mecánico se mostrará la siguiente información:  Si el mecánico está desocupado, se mostrará el siguiente evento de salida: Estado mecanico id1 esta (LIBRE | OCUPADO)6

Si el mecánico está ocupado, se mostrará el siguiente evento de salida tras terminar el ciclo de trabajo, y siempre y cuando no se haya concluido la reparación: Trabaja mecanico id1 reparacion id2 ciclos pendientes c7

Si hay más de un mecánico, se muestran los eventos ordenados de menor a mayor id de mecánico.

5. Errores graves a evitar  En esta sección se enumeran algunos errores que el alumno debe evitar. Esta lista no es exhaustiva en el sentido de que no recoge todos los posibles errores que el alumno debe evitar cometer. 1. Se declaran atributos públicos. 2. Utiliza atributos de clase o static (para esta práctica no son necesarios). 3. Se realizan operaciones de entrada/salida en alguna de las clases implementadas por el alumno, excepto en las ramas catch en donde sí que se permite.

6. Consideraciones a la hora de entregar la práctica  Se deben comentar las clases y los métodos utilizando comentarios reconocidos por javadoc. Los comentarios javadoc de los métodos deben tener la misma estructura que los utilizados en las implementaciones de los TADs vistos en clase. Se debe entregar un fichero jar con la estructura dada en el código de apoyo. No debe incluir ficheros .class. Se deben entregar los html generados por medio de javadoc Sólo se pueden usar los TADs que hay disponibles en TADS.jar que se encuentra disponible en moodle. Se valora positivamente: 1. La utilización de nombres significativos para los identificadores, así como la utilización de los convenios de Java. 2. La utilización de métodos auxiliares que implementen tareas comunes a varios métodos, y que de esa forma eviten la duplicidad de código. 6 Se utiliza el método registraEstadoMecanico de la clase HistoricoReparaciones 7 Se utiliza el método trabaja de la clase HistoricoReparaciones


Programación II

Práctica del Taller de Reparaciones (Abril 2011)

pág:10

3. La correcta indentación del código. Se recomienda la utilización en eclipse del atajo de teclado CTRL + i. 4. La implementación de un código eficiente que no realice operaciones innecesarias.


taller