100 likes | 247 Views
0 . Desarrollo de Programas: técnica del refinamiento. Idea. Objetivos: Facilitar el proceso de solución de un problema Orden y Claridad del código Distribución de tareas entre programadores
E N D
Idea • Objetivos: • Facilitar el proceso de solución de un problema • Orden y Claridad del código • Distribución de tareas entre programadores • Estrategia bottom-up: “partir” un problema en sub-problemas, solucionar los sub-problemas desarrollando código “encapsulado” y luego escribir el programa principal usando el código encapsulado • Estrategia top-down: Escribir el código del programa principal en forma gruesa, dejando para después la solución de sub-problemas. Luego se desarrollan los sub-problemas. • Distribución del trabajo: para distribuir el trabajo es necesario establecer claramente como se usarán y cual será el comportamiento del código encapsulado
Ejemplo Problema: desarrollar el programa que implementa el siguiente diálogo con el usuario: Suma, resta de 2 tiempos Primer tiempo (HHMMSS) ? 013040 Segundo tiempo (HHMMSS) ? 104530 Suma = 12:16:10 Resta = 09:14:50 Mayor = 10:45:30 Menor = 01:30:40
Solución sin estrategia: import java.util.*;class T { public static void main(String[] args) { Scanner C = new Scanner(System.in); System.out.println(“Sumar y resta de 2 tiempos”); System.out.print(“Primer instante(HHMMSS)?”); intt1=C.nextInt(); ht1=t1/10000; mt1=t1%10000/1000; st1=t1%1000; System.out.print(“Segundo instante(HHMMSS)?”); intt2=C.nextInt(); ht2=t2/3600; mt2=t2%20000/60; st2=t2%60; intsum = (ht1+ht2)*3600+(mt1+mt2)*60+st1+st2; System.out.print(“Suma= “+(sum/3600)+”:”+(sum%3600/60)+”:”+(sum%60)); int res = (ht1-ht2)*3600+(mt1-mt2)*60+st1-st2; System.out.print(“Resta= “+(res/3600)+”:”+(res%3600/60)+”:”+(res%60)); if (t1 > t2) System.out.print(“Mayor=“+ht1+”:”+mt1+”:”+st1); else System.out.print(“Mayor=“+ht2+”:”+mt2+”:”+st2); } }
Solución top down: import java.util.*;class T { public static void main(String[] args) { Scanner C = new Scanner(System.in); System.out.println(“Sumar y resta de 2 tiempos”); System.out.print(“Primer instante(HHMMSS)?”); int t1=Tiempo.totalSegundos(C.nextInt()); System.out.print(“Segundo instante(HHMMSS)?”); int t2=Tiempo.totalSegundos(C.nextInt()); System.out.print(“Suma=); Tiempo.escribir(t1+t2); int mayor=Math.max(t1,t2), menor=Math.min(t1,t2); System.out.print(“Mayor=); Tiempo.escribir(mayor); System.out.print(“Menor=); Tiempo.escribir(menor); System.out.print(“Resta=); Tiempo.escribir(mayor-menor); } } class Tiempo{ static public inthoras(int x){return x/10000;} static public intminutos(int x){return x/100%100;} static public intsegundos(int x){return x%100;} static public inttotalSegundos(int x){ return horas(x)*3600+minutos(x)*60+segundos(x);} static public void escribir(int x){ System.out.println(x/3600+”:”+x%3600/60+”:”+x%3600%60);} }
Solución bottom-up: class Tiempo { int segundos; //conviene guardar el total de segundos no mas Tiempo (intx) { segundos = x; } publicintcompareTo(Tiempo x) { // retorna un entero < 0, == 0, > 0 según si x es mayor igual o menor return segundos – x.segundos; } public Tiempo suma(Tiempo x) { //retorna un objeto tiempo nuevo con la suma return new Tiempo(segundos+x.segundos); } public Tiempo resta(Tiempo x) { //retorna un objeto tiempo nuevo con la resta returnnew Tiempo(segundos-x.segundos); } publicStringtoString() { //retorna un string “HH:MM:SS” return segundos/3600+”:”+(segundos%3600/60)+”:”+segundos%60; } }
Programa class T { publicstaticvoidmain(String[] args) { Tiempo t1 = new Tiempo(C.readInt(“Primer instante(HHMMSS)?“)); Tiempo t2 = new Tiempo(C.readInt(“Segundo instante(HHMMSS)?”); Tiempo t3 = t1.suma(t2); System.out.print(“Suma=”+t3.toString()); if (t1.compareTo(t2) > 0){ mayor = t1; menor = t2; } else { mayor = t2; menor = t1; } U.println(“Mayor=“+mayor.toString()); U.println(“Menor=”+menor.tostring()); U.print(“Suma =“+(t1.suma(t2)).toString()+ ”Resta=”+(t1.resta(t2)).toString()); } }
Pensamientos • Es importante definir claramente la interfaz entre el programa principal y los sub-programas • El enfoque de llamado a funciones es más antiguo que el de diseñar y construir objetos pero ambos persiguen los mismos objetivos • El enfoque orientado a objetos responde a la necesidad de desarrollar software de grandes dimensiones con menos errores • Permite encapsular mejor el código y los datos de un subprograma • Apoya desarrollo de “Tipos de Datos Abstractos”
Estructura de Dato y su invariante • Cada estructura de datos que implementa un TDA tiene un invariante • Conjunto de condiciones que se cumplen siempre • Cada operación que se define sobre la estructura tiene el derecho de suponer que se cumple el invariante al principio y dejarlo cumpliéndose al final • Ej. Implementar un TDA conjunto con la siguiente estructura de datos a0 a1 . . . an-1 an . . . n
Estructura de Dato y su invariante classConjunto { privateint[] a; privateint n; Conjunto(intx) { a = new int[x]: n = 0; } publicbooleanagragar(intx) { if (esta(x)) return false a[n++] = x; return true; } publicboolean sacar(intx) { } publicboolean esta(intx) { //retorna true si esta x en el conjunto } . . . } }