Download 13 de SEPTIEMBRE de 2007

Document related concepts
no text concepts found
Transcript
INGENIERÍA DEL SOFTWARE. 4º ING. INFORMÁTICA (UPV/EHU)
13 de SEPTIEMBRE de 2007
NOMBRE:
GRUPO:
1ª PREGUNTA: ARQUITECTURAS EN 3 NIVELES) (2.5 ptos.) (Tiempo estimado: 45 minutos)
A continuación se presenta la implementación usando una arquitectura en 3 niveles físicos del caso
de uso PEDIR BILLETE que se ha utilizado durante este cuatrimestre (es exactamente el que
aparecía en la página web de la asignatura).
package ejsA3N;
import java.rmi.*;
public interface GestorBilletes extends Remote
{ public Billete getBillete(String nom) throws RemoteException; }
package ejsA3N;
import java.util.Date;
public class Billete implements java.io.Serializable
{ private int num; private String nomb; private Date fecha;
public Billete(int n,String nom){num=n; nomb=nom; fecha=new Date(); }
public int getNum(){return num;}
public String getNombre(){return nombre;}
public Date getFecha(){return fecha;} }
package ejsA3N;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.rmi.*;
public class PedirBillete extends JFrame {
JPanel jPanel1 = new JPanel(); JLabel jLabel1 = new JLabel();
JTextField jTextField1 = new JTextField();
JButton jButton1 = new JButton();
JTextArea jTextArea1 = new JTextArea();
GestorBilletes gestorBilletes; // Objeto con la lógica del negocio
public PedirBillete() {
super();
try {jbInit();} catch (Exception e) {e.printStackTrace();}}
private void jbInit() throws Exception {
this.getContentPane().setLayout(null);
this.setSize(new Dimension(400, 300));
jPanel1.setLayout(null);
jPanel1.setBounds(new Rectangle(0, 0, 392, 273));
jLabel1.setText("Nombre:");
jLabel1.setBounds(new Rectangle(54, 58, 64, 17));
jTextField1.setBounds(new Rectangle(124, 50, 163, 33));
jButton1.setText("Pedir Billete");
jButton1.setBounds(new Rectangle(103, 189, 156, 44));
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
jButton1_actionPerformed(e);} });
jTextArea1.setBounds(new Rectangle(88, 94, 189, 76));
this.setTitle("Pedir Billetes");
this.getContentPane().add(jPanel1, null);
jPanel1.add(jLabel1, null); jPanel1.add(jTextField1, null);
jPanel1.add(jButton1, null); jPanel1.add(jTextArea1, null); }
public void setGestorBilletes(GestorBilletes g) { gestorBilletes=g; }
void jButton1_actionPerformed(ActionEvent e) {
try{int res =
gestorBilletes.getBillete(jTextField1.getText()).getNum();
if (res<0) jTextArea1.append("Error al asignar billete");
else jTextArea1.append("Asignado. \nReferencia: "+res+"\n");
} catch (Exception er) {System.out.println("Error: "+er.toString());
jTextArea1.append("Error al asignar billete");}}
public static void main (String []arg) {
PedirBillete b = new PedirBillete();
System.setSecurityManager(new RMISecurityManager());
String servicioRemoto = "rmi://localhost:1099/gestorBilletes”;
GestorBilletes objetoRemoto;
try{objetoRemoto = (GestorBilletes)Naming.lookup(servicioRemoto);
b.setGestorBilletes(objetoRemoto); }
catch (Exception e) {System.out.println("Error: "+e.toString());}
b.setVisible(true); }}
package ejsA3N;
import java.rmi.*;
import java.sql.*;
import java.io.*;
import java.rmi.server.UnicastRemoteObject;
import java.util.*;
public class ServidorGestorBilletesBD extends UnicastRemoteObject
implements GestorBilletes
{
private static Connection conexion;
private static Statement sentencia;
public ServidorGestorBilletesBD() throws RemoteException{
try {Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
conexion=DriverManager.getConnection("jdbc:odbc:Billetes");
conexion.setAutoCommit(false);
sentencia=conexion.createStatement(); }
catch(Exception e){System.out.println("Error:"+e.toString());}}
public Billete getBillete(String nom)
throws RemoteException {
// Devuelve billete con nº billete, -1 si no hay, -2 problemas
String pregSQL = "SELECT NUMERO FROM BILLETES"+
" WHERE ESTADO=\'LIBRE\'";
try{ ResultSet rs = sentencia.executeQuery(pregSQL);
if (rs.next()) {
String num = rs.getString("NUMERO");
int act = sentencia.executeUpdate("UPDATE BILLETES"+
" SET ESTADO='OCUPADO', NOMBRE = '"+nom+
"' WHERE NUMERO="+num+" AND ESTADO='LIBRE'");
conexion.commit();
int n= Integer.parseInt(num);
if (act>0) return new Billete(n,nom); // N. bill asignado
return new Billete(-2,""); } // Otro ha OCUPADO billete
else return new Billete(-1,"");; } // No había libre
catch (SQLException e){System.out.println(e.toString());}
return new Billete(-2,""); } // Que prueben otra vez a llamar
public static void main(String[] args) {
System.setSecurityManager(new RMISecurityManager());
try { java.rmi.registry.LocateRegistry.createRegistry(numPuerto);
} catch (Exception e) {System.out.println(Rmiregistry exist");}
try { ServidorGestorBilletesBD objetoServidor =
new ServidorGestorBilletesBD();
String servicio="//localhost:1099/gestorBilletes";
Naming.rebind(servicio,objetoServidor);
} catch (Exception e){System.out.println(e.toString());}}}
Se trata de desarrollar un caso de uso complementario al anterior llamado “DEVOLVER
BILLETES” donde se puede devolver un número de billetes indicado a nombre de una persona.
Además, se puede decir si se quiere devolver EXACTAMENTE es número. En tal caso, o se
devuelven todos los billetes o ninguno. Si no, se devolverán todos los billetes que se pueda hasta el
número indicado. Como resultado se mostrará el número de billetes devuelto.
Se pide:
1) Diseñar en UML una solución para el caso de uso “DEVOLVER BILLETES” que utilice
una arquitectura física en 3 niveles.
2) Indicar TODOS LOS CAMBIOS que hay que hacer en la IMPLEMENTACIÓN con
respecto a la solución anterior del caso de uso “DEVOLVER BILLETES”. Cuando se trate
de un método nuevo hay que hacer la implementación completa del método.
2ª PREGUNTA: PRUEBAS) (1,5 ptos.) (Tiempo estimado: 15 minutos) Diseñar el siguiente caso
de prueba para el caso de uso anterior e implementar un componente de prueba en JUNIT que lo
pruebe.
// OBJETIVO DEL CASO DE PRUEBA: comprobar que “si se quiere devolver un número de
billetes a nombre de una persona superior al número de billetes que tiene y no se quiere
devolver exactamente ese número, entonces deja devolver el número de billetes que tiene”
Entrada:
Condiciones de entrada:
Salida:
NOTA: Si para el componente de prueba se usa alguna otra clase auxiliar, describirla usando
UML.
import junit.framework.*;
public class ComponentePruebaDevolverBilletes extends TestCase
{ public ComponentePruebaDevolverBilletes (String nombre)
{ super(nombre); }
protected void setUp() { }
protected void tearDown() { }
// assertTrue(b) falla si y solo si b es false
public static Test suite() {
return new TestSuite(ComponentePruebaDevolverBilletes.class);
public static void main(String args[]) {
junit.textui.TestRunner.run(suite()); }}
}
3ª PREGUNTA: JGL (2 ptos.) (Tiempo estimado: 30 minutos1. Se desea añadir a la librería JGL,
otra nueva interfaz de "objetos funcion" (ActionObject), de tal forma que la función no
devuelva NADA, es decir,
f(x)=void
y únicamente modifique el contenido del objeto referenciado por x. Cómo definirías esta nueva
interfaz?
2. Define una clase función que implementa la interfaz de punto anterior, que para objeto de
tipo Nota(valor, calificación), rellene el campo calificación a partir del atributo valor.
3. Define un algoritmo que a partir de un contenedor JGL y un objeto función de tipo
ActionObject, aplique la función a todos los elementos del contenedor
4. Realizar un programa que cree un contenedor con Notas, rellenando su valor, y aplique la
funcion del punto 2 para rellenar su calificación
4ª PREGUNTA: PATRONES DE DISEÑO (2 ptos.) (Tiempo estimado: 45 minutos)
Un satélite de comunicaciones distribuye (entre otras cosas) las noticias de varias agencias de
noticias (p.ej Reuters, EFE, etc...). La agencia la constituyen una serie de reporteros distribuidos
en diferentes lugares, y envían sus noticias a la agencia cada vez que acontece una noticia.
Por otro lado los usuarios de la televisión por satélite, a través de su decodificador pueden enviar
al satélite una solicitud de suscripción a alguna de las agencias de noticias que distribuye. Esto
conlleva que cada vez que llega una nueva noticia a alguna agencia de noticias, se reenvía dicha
noticia a todos los clientes abonados a dicho canal.
De pide:
1. Realiza un modelo de clases que recoja los requisitos descritos anteriormente, indicando
claramente si has utilizado algún patrón de diseño.
2. Implementa los métodos que estimes oportunos para llevar a cabo las funcionales descritas en
los requisitos.
5ª PREGUNTA: EJB (2 ptos.) (Tiempo estimado: 45 minutos) Una empresa quiere desarrollar
una aplicación para jugar al ajedrez entre un usuario y el computador, donde las jugadas que se
vayan realizando se vayan plasmando en un tablero real donde las piezas son movidas por un
brazo de un robot. Para realizar esta aplicación nos proporcionan lo siguiente:
Un componente EJB TebleroEJB. Este componente gestiona un tablero(en memoria) y dispone
de los siguientes métodos:
void inicializarTablero()
boolean esPosibleJugada(Jugada j);
void mover(Jugada j);
boolean fin();
int quienHaGanado(); //1:User 2: Computador
Jugada mejorJugada(); //Cual es la mejor jugada por parte de la maquina
Un componente EJB RobotEJB que controla el brazo del robot y tiene los siguientes métodos:
void inicializarPartida() // Coloca las piezas en la posición inicial
void mover(Jugada j) // El brazo del robot aplica la jugada j en el tablero.
RobotEJB
PartidaEJB
TableroEJB
Con estos componentes implementados, nos piden:
1. Desarrollar un componente PartidaEJB,
implemente los siguientes métodos:
que utilizando los componentes anteriores
//inicializa ambos componentes
void inicializar();
//Aplica la jugada j del usuario y a continuación aplica la jugada del computador
si no ha terminado la partida.
int jugadaUsuario(Jugada j);
boolean esFin(); //true si ha terminado la partida, y falso en caso contrario
String ganador(); //devuelve "Enhorabuena, has ganado" si ha ganado el usuario o
"Lo siento, inténtalo de nuevo", si ha ganado la computadora.
2. Realiza un programa principal, que inicialice una partida, y realice la ejecución de una
partida. (Tenemos un método Jugada leerJugada(); que lee de la entrada estándar una jugada por
parte del usuario).