DEFINICIón y cumplimiento de responsabilidades
Nychol Bazurto Gómez




Asignación de responsabilidades
Nivel
4
Manejo de las excepciones
Contrato de un método
Diseño de las signaturas de los métodos
VEREMOS lo siguiente
-
Asignación de responsabilidades
- Técnica del experto
- Dividir y conquistar
- ¿Qué es una excepción?
-
¿Cómo se maneja una excepción?
- Anunciar
- Atrapar
- Ejecutar acción
- ¿Por qué usar excepciones?
- Contratos
- Quien escribe el cuerpo de un método puede hacer ciertas suposiciones sobre los parámetros o sobre los atributos, y esto puede afectar en algunos casos el resultado.
Dichas suposiciones sólo quedan expresadas como parte de las instrucciones del método
No son necesariamente visibles por el programador que va a utilizarlo.

- Quien llama un método necesita saber cuáles son las suposiciones que hizo quien lo construyó, sin necesidad de entrar a estudiar la implementación.
Si no tiene en cuenta estas suposiciones, puede obtener resultados inesperados

CONTRATO
La solución a este problema es establecer claramente un contrato en cada método, en el que sean claros sus compromisos y sus suposiciones.
Asignación de responsabilidades
Técnicas
DEl experto
DESCOMPOSICIón de requerimientos
DEl experto
El dueño de la información es el responsable de esta
– El dueño debe permitir:
• el acceso a la información.
• modificar su valor
Se definen qué métodos hay por cada atributo:
- Para permitir a otras entidades acceder a la información se crean los métodos dar.
- Para permitir a otras entidades modificar la información se crean otros métodos como: modificar, aumentar, reducir, etc.

DESCOMPOSICIón de requerimientos
– Descomponer los RF en pasos (subproblemas).
– Construir un método por cada paso.
- Para cada sub-problema identificar que entidad (clase) lo resuelve (si es que ya existe un método se utiliza, si no existe se crea e implementa)
- Se resuelve cada sub-problema llamando a los métodos que lo resuelven y el requerimiento queda resuelto.

DESCOMPOSICIón de requerimientos
– Descomponer los RF en pasos (subproblemas).
– Construir un método por cada paso.
- Para cada sub-problema identificar que entidad (clase) lo resuelve (si es que ya existe un método se utiliza, si no existe se crea e implementa)
- Se resuelve cada sub-problema llamando a los métodos que lo resuelven y el requerimiento queda resuelto.

¿Qué es una excepción?
Es la indicación de que se produjo un error en el programa.
Se produce cuando un método termina de manera excepcional debido a una situación anormal: ERROR.
Si no se maneja dicho error el programa termina su ejecución abruptamente y es probable que el usuario no entienda qué pasó.





EJEMPLOS

public double dividir(int a, int b) { return a/b;
}

dividir(13,0);
Exception in thread "main" java.lang.ArithmeticException: / by zero at uniandes.cupi2.club.mundo.Membresia.main(Membresia.java:7)
EJEMPLOS

public double dividir(int a, int b) { return a/b;
}
Integer denominador = null;
dividir(13,denominador);
Exception in thread "main" java.lang.NullPointerException at uniandes.cupi2.club.mundo.Membresia.main(Membresia.java:8)
CARRITO DE COMPRAS

Supongamos que estamos comprando en una página.
Vamos añadiendo artículos a nuestro "carrito" de compras.
Cómo se maneja una
EXCEPCIón
Se dispara
Se atrapa
Se ejecuta una acción



Cómo se maneja una
DISPARA
EXCEPCIón
Cuando se detecta una situación anormal, se debe disparar una excepción:

Cómo se trata una excepción: Disparar
El método que lanza la excepción debe advertir (anunciar) que puede producirse una.
public void descontarUnidades(int idProducto, int cantidad) throws Exception Cuando se detecta una situación anormal, se debe disparar una excepción:

Cómo se trata una excepción: Disparar
También quiere decir que este método está dejando pasar una excepción que generó una instrucción interna.
public void descontarUnidades(int idProducto, int cantidad) throws Exception 
Cómo se trata una excepción: Disparar
public void descontarUnidades(int idProducto, int cantidad) throws Exception
{
int cantidadDisponible = obtenerInventarioProducto( idProducto );
int unidadesRestantes = cantidadDisponible - cantidad;
if( unidadesRestantes < 0)
{
// Se actualiza las unidades del producto
actualizarUnidades( idProducto, unidadesRestantes );
}
else
{
throw new Exception("No hay suficientes unidades");
}
}
Revisar que haya suficientes unidades en el inventario.

Cómo se trata una excepción: Disparar
public void descontarUnidades(int idProducto, int cantidad) throws Exception
{
int cantidadDisponible = obtenerInventarioProducto( idProducto );
int unidadesRestantes = cantidadDisponible - cantidad;
if( unidadesRestantes < 0)
{
// Se actualiza las unidades del producto
actualizarUnidades( idProducto, unidadesRestantes );
}
else
{
throw new Exception("No hay suficientes unidades");
}
}
En caso de que hayan suficientes unidades, actualizar las unidades del producto.

Cómo se trata una excepción: Disparar
public void descontarUnidades(int idProducto, int cantidad) throws Exception
{
int cantidadDisponible = obtenerInventarioProducto( idProducto );
int unidadesRestantes = cantidadDisponible - cantidad;
if( unidadesRestantes < 0)
{
// Se actualiza las unidades del producto
actualizarUnidades( idProducto, unidadesRestantes );
}
else
{
throw new Exception("No hay suficientes unidades");
}
}
En caso de que no hayan suficientes unidades, generar una excepción

Cómo se trata una excepción: Disparar
public void descontarUnidades(int idProducto, int cantidad) throws Exception
{
...
else
{
throw new Exception("No hay suficientes unidades");
}
}
Se crea un objeto de la clase Exception
Se lanza la excepción con la instrucción throw

Cómo se trata una excepción: Disparar
public void descontarUnidades(int idProducto, int cantidad) throws Exception
{
...
else
{
throw new Exception("No hay suficientes unidades");
}
}
public void descontarUnidades(int idProducto, int cantidad) throws Exception
{
...
else
{
Exception e = new Exception("No hay suficientes unidades");
throw e;
}
}Cómo se maneja una
ATRAPA
EXCEPCIón
Se debe atrapar una excepción antes de que el programa deje de funcionar. Para ello tenemos la instrucción try-catch.
Cómo se trata una excepción: Atrapar

try
{
instruccion1;
instruccion2;
instruccion3;
}
catch (Exception e)
{
instruccion4;
}Delimita la porción de código dentro de un método en el que necesitamos desviar el control si una excepción ocurre allí.
Se debe atrapar una excepción antes de que el programa deje de funcionar. Para ello tenemos la instrucción try-catch.
Cómo se trata una excepción: Atrapar

try
{
instruccion1;
instruccion2;
instruccion3;
}
catch (Exception e)
{
instruccion4;
}Definir el código que manejará el error o atrapará la excepción.
Se debe atrapar una excepción antes de que el programa deje de funcionar. Para ello tenemos la instrucción try-catch.
Cómo se trata una excepción: Atrapar

try
{
carrito.descontarUnidades(producto,cantidad);
carrito.actualizarPrecioTotal();
}
catch (Exception e)
{
JOptionPane.showMessageDialog( this,
"Problema actualizando carrito:", e.getMessage( ),
JOptionPane.ERROR_MESSAGE);
}Si todo funciona bien, no se ejecutan las instrucciones del bloque catch.
Cómo se maneja una
ejecuta acción
EXCEPCIón
try
{
carrito.descontarUnidades(producto,cantidad);
carrito.actualizarPrecioTotal();
}
catch (Exception e)
{
JOptionPane.showMessageDialog( this,
"Problema actualizando carrito:", e.getMessage( ),
JOptionPane.ERROR_MESSAGE);
}Código que maneja el error. A través de la variable e podemos obtener información detallada del error
Cómo se trata una excepción: Ejecutar una acción

Recuperación de una situación anormal
Cómo se trata una excepción: Ejecutar una acción

m4() throws Exception {
...
}
m3() throws Exception {
c.m4();
}
m2() throws Exception{
b.m3();
}
void m1(){
try{
a.m2();
}
catch(...){
}
...
}
Atrapa la excepción
y se recupera
Dejan pasar la excepción
Dispara la excepción
POR QUé usar excepciones
POR QUé usar excepciones
¿Y por qué no usar booleanos para indicar si no hubo errores?
Las excepciones al ser un objeto, nos proveen mayor detalle y permiten tomar acciones más precisas.

¿Y por qué no usar booleanos para indicar si no hubo errores?
Cada instrucción podría arrojar una excepción, además existen diferentes tipos de excepciones que pueden ser manejadas en un mismo catch.
try
{
carrito.descontarUnidades(producto,cantidad);
carrito.actualizarPrecioTotal();
}
catch (NullPointerException e)
{
JOptionPane.showMessageDialog( this,
"Error por null:", e.getMessage( ),
JOptionPane.ERROR_MESSAGE);
}
catch (Exception e)
{
JOptionPane.showMessageDialog( this,
"Problema actualizando carrito:", e.getMessage( ),
JOptionPane.ERROR_MESSAGE);
}CONTRATOS

CONTRATO
Bajo qué condiciones (suposiciones) el método tendrá éxito.
Cuál será el resultado una vez que se termine su ejecución
Se agrega un nuevo elemento a la lista de estudiantes de la central.
La lista de estudiantes está inicializada.
El nombre no es null ni vacío.
El código es valido
public void agregarEstudiante( String pNombre, int pCodigo ) throws ExceptionSe produjo un error y se informó el problema con una excepción. El estudiante no fue agregado.
PRECONDICIón
POSTCONDICión
EXCEPción

Contrato
PRECONDICIón

Contrato
Conjunto de suposiciones, expresadas como condiciones que deben ser verdaderas para que el método se ejecute con éxito.
Pueden referirse a:
El valor de los atributos
El estado de una asociación
Condiciones sobre los parámetros de entrada
codigo
Estudiante
pNombre
Postcondicion

Contrato
Conjunto de condiciones que deben ser verdaderas después de que el método ha sido ejecutado, siempre y cuando no se haya lanzado una excepción.
Pueden referirse a:
Valor de retorno
(si el método retorna algo)
Estado del objeto (valor de sus atributos) después de la ejecución del método
boolean
int double
incrementó
actualizó ...
En otras palabras

Contrato
"si todas las condiciones de la precondición se cumplen antes de llamar el método, éste asume el compromiso de llegar a cumplir todas las condiciones incluidas en la postcondición"
El contrato es total, en el sentido de que si alguna de las precondiciones no se cumple, el método deja de estar obligado a cumplir la postcondición.

Cuando se define un contratoy se implementa un método que lo cumple, surgen algunas dudas

Contrato

¿Un método debe verificar en algún punto las condiciones que hacen parte de la precondición?

Contrato
Lo que aparece en la precondición se debe suponer como cierto y se debe utilizar como si lo fuera. Si algo falla en la ejecución por culpa de eso, es responsabilidad de aquel que hizo la llamada al método sin cumplir el contrato.

¿Cómo se manejan las excepciones en los contratos?

Contrato
Un contrato sólo debe decir que lanza una excepción cuando, aún cumpliéndose todo lo pedido en la precondición, es imposible llegar a cumplir la postcondición. Eso quiere decir que ninguna excepción puede asociarse con el no cumplimiento de una precondición.
¿Qué se incluye entonces en la precondición?

Contrato
- En la precondición solo se deben incluir condiciones que resulten fáciles de garantizar por parte de aquél que utiliza el método.
- Si se imponen verificaciones excesivamente costosas en tiempo antes de usar el método, terminamos construyendo programas ineficientes.
- Si se quiere asegurar de algo en la ejecución del método, basta con eliminarlo de la precondición y lanzar una excepción si no se cumple.
¿Por qué es inconveniente verificar todo dentro de los métodos ?

Contrato
- Por eficiencia. Es mucho mejor repartir las responsabilidades de verificar las cosas entre el que hace el llamado y el que hace el método.
- Si en el contrato queda claro quién se encarga de qué, es más fácil y eficiente resolver los problemas.
Documentación de los contratos con javadoc

Contrato

Contrato
JAVADOC
Herramienta de generación automática de documentación
- Un contrato se expresa como un comentario Javadoc, delimitado con los caracteres /** ... */. Dicho comentario debe ir inmediatamente antes del método.
- El contrato comienza con una descripción general del método. Esta descripción debe dar una idea general del servicio que éste presta.

Contrato


Contrato

Cómo generar y leer el archivo en formato html

signatura
Diseño de la
de métodos

Qué es diseñar un método
Decidir:
Precisar su contrato:
- Cuáles serán los parámetros del método
- Cuál será su valor de retorno
- Qué excepciones puede disparar
- Definir precondición y poscondición
De dónde viene la información para diseñar la signatura de un método ?
Identificación de entradas y salidas de los requerimientos funcionales
Tipos de atributos utilizados en el modelaje del mundo del problema
Dos preguntas útiles …
¿Qué información externa al objeto se necesita para resolver el problema que se plantea en el método?
¿Cómo se modeló esa información dentro del objeto?
Parámetros de entrada
tipos de los Parámetros
¿PREGUNTAS?
¿PREGUNTAS?
Text
GRACIAS
- J. Villalobos and R. Casallas, Fundamentos de Programación. https://cupi2.virtual.uniandes.edu.co/libro-del-curso-pdf/libro-completo
- Icons made by wanicon from Flaticonis licensed by Creative Commons BY 3.0
Nivel4
By nychi713
Nivel4
- 593