Upload
dangdang
View
220
Download
0
Embed Size (px)
Citation preview
La Programación Orientada a Objetos:Introducción
Prof. Franco Guidi PolancoEscuela de Ingeniería Industrial
Pontificia Universidad Católica de Valparaíso, [email protected]
Actualización: 02 de agosto de 2007
02/08/2007Franco Guidi Polanco (PUCV-EII) 2
De Problemas a Soluciones
“Half the battle is knowing what problem to solve”
Data Structures and Algorithms(A.A. Aho, J.E. Hopcroft & J.D. Ullman)
De http://pbfcomics.com/
02/08/2007Franco Guidi Polanco (PUCV-EII) 3
De Problemas a Soluciones
Análisis: entender el problema y sus requerimientos
Diseño: determinar un modelo que nos permita resolver el problema.
Implementación: determinar la forma de representar el modelo que describe el problema (y la solución):
02/08/2007Franco Guidi Polanco (PUCV-EII) 4
Los Requerimientos
Los requerimientos:son incompletosusualmente están equivocadosson engañosos (y los usuarios también) no cuentan la historia completa
Por lo tanto, los requerimientos siempre cambian
02/08/2007Franco Guidi Polanco (PUCV-EII) 5
El Desarrollo de Proyectos
Lo que propuso el comité de proyecto
Lo que se especificócomo requerimiento
Lo que diseñó el analista
Lo que desarrollaronlos programadores
Lo que se instalóal usuario
Lo que necesitabael usuario
1 2 3
4 5 6
02/08/2007Franco Guidi Polanco (PUCV-EII) 6
Metodologías y Modelos
La Ingeniería de Software provee:
Metodologías de desarrollo.Desarrollo en cascadaProceso Unificadoetc.
Modelos para soportar el desarrolloEspecificación estructurada (DFDs, MER, etc.)UMLetc.
Lenguajes para la implementaciónC, C++Javaetc.
Se estudiaránen detalle
en curso de Modelamiento
de Sistemas
The Beatles
Cecilia Serrano(Miss Chile 1979)
Teleserie de Cara al Mañana(1982)
Grease
Antes de la Programación Orientada a Objetos
1a Teletón (1978) 02/08/2007Franco Guidi Polanco (PUCV-EII) 8
Divide et Impera: Descomposición Funcional
“Divide et Impera”
Descomposición en funciones: el analista descompone el problema en una serie de pasos que permiten resolverlo.
Los pasos son refinados sucesivamente, hasta llegar a funciones elementales.
¿Costo?
02/08/2007Franco Guidi Polanco (PUCV-EII) 9
Descomposición Funcional
... ingresarDatos(datos);calcularMedia(datos, media);calcularDE(datos, de);mostrarResultados(media, de);...procedimiento ingresarDatos(datos:arreglo){ i=0;mientras i <= 10 hacer{ leer datos[i]i = i + 1;}}procedimiento calcularMedia(datos:arreglo, media:float){ i=0;suma = 0;mientras i <= 10 hacer{ suma = suma + datos[i]i = i + 1;}media = suma / 10}...
02/08/2007Franco Guidi Polanco (PUCV-EII) 10
La Encapsulación como Agrupación de Funciones
La encapsulación permite la agrupación de ideas relacionadas en una unidad, la que posteriormente puede ser referida por un solo nombre.
El concepto surgió en la década del ’40 con la invención de la subrutina: los programadores se dieron cuenta de que un mismo patrón de instrucciones se podía repetir muchas veces en un programa.
02/08/2007Franco Guidi Polanco (PUCV-EII) 11
Descomposición Funcional: Reutilización de Código
..i=1mientras i<=10 hacer{ si a[i]=10 entonces a[i]=0i=i+1}..i=1mientras i<=10 hacer{ si b[i]=10 entonces b[i]=0i=i+1}..i=1mientras i<=10 hacer{ si c[i]=10 entonces c[i]=0i=i+1}.
..HacerCeros(a)...HacerCeros(b)...HacerCeros(c)...Procedimiento HacerCeros(x:arreglo)i=1mientras i<=10 hacer{ si x[i]=10 entonces x[i]=0i=i+1}
Programa con subrutinaPrograma original
02/08/2007Franco Guidi Polanco (PUCV-EII) 12
Ventajas de Funciones o Subrutinas
Ahorro de memoria de computador (código fuente de programas más corto).
Código fuente más “entendible”: una subrutina agrupa un conjunto de instrucciones en un “concepto” que una persona puede considerar y manejar como una sola idea (en el ejemplo, HacerCeros).
02/08/2007Franco Guidi Polanco (PUCV-EII) 13
Lenguajes de Programación
Antes de la POO los lenguajes de programación eran procedimentales.
Aproximación:
Imagine programar en Java, usando sólo métodos estáticos, con instancias de clases que no tengan métodos.
NOTA:NO LO INTENTE
02/08/2007Franco Guidi Polanco (PUCV-EII) 14
ADT(AbstractData Type)
Tipo de dato(No provisto por
el lenguaje deprogramación)
+ Operaciones
Por separado, pero asociadas.
Reutilización antes de la POO: Tipos Abstractos de Datos
La Programación Orientada a Objetos
Derrumbe Muro Berlín (09/09/1989)
Cecilia BoloccoMiss Universo (1987)
Tragedia Transbordador Challenger(1986)
Pulp FictionQ. Tarantino (1994)
Tim Berners-Lee(CERN-1989)
02/08/2007Franco Guidi Polanco (PUCV-EII) 16
La Programación Orientada a Objetos (POO)
El paradigma de la Orientación a Objetos es sucesor de la descomposición funcional
Se centra en el concepto de Objeto:
Objeto = Datos + Métodos
Los objetos:son responsables de si mismos.“saben” de qué tipo son.conocen su propio estado (datos).contienen el código que les permite actuar.
(Definición tradicional)
02/08/2007Franco Guidi Polanco (PUCV-EII) 17
POO versus Descomposición Funcional
El modelo de programación funcional mantenía centralizadas las responsabilidades:
Una cena en la cual un garzón pide a cada comensal lo que se servirá, y luego les trae los platos solicitados.
El modelo de programación OO provee delegación de responsabilidades:
Una cena en la cual a los comensales se les indica la distribución del buffet. Ellos se sirven a su propio gusto.
02/08/2007Franco Guidi Polanco (PUCV-EII) 18
¿Cómo identificar Objetos?
En problemas pequeños una técnica sencilla se basa en la identificación de sustantivos y verbos :
Los sustantivos pueden ser objetosLos verbos pueden ser métodos
02/08/2007Franco Guidi Polanco (PUCV-EII) 19
Objetos
Una buena forma de concebir un objeto es pensar en él como una entidad con responsabilidades. Las responsabilidades determinan el comportamiento del objeto.Debe existir una forma para comunicar a un objeto qué debe hacer.Esta comunicación se logra por medio del conjunto de métodos que un objeto ofrece para que otros puedan invocar. El conjunto de estos métodos se denomina interfaz públicadel objeto.
02/08/2007Franco Guidi Polanco (PUCV-EII) 20
Visión de Objetos
Martin Fowler identifica tres perspectivas para describir los objetos:
Nivel conceptual: un objeto es un conjunto de responsabilidades.
Nivel especificación: un objeto es un conjunto de métodos (comportamientos), que pueden ser invocados por otros objetos o por si mismos.
Nivel implementación: un objeto es código y datos, e interacciones computaconales entre ellos.
Martin Fowler
02/08/2007Franco Guidi Polanco (PUCV-EII) 21
Perspectivas para Describir Sistemas OO
Nivel Conceptual
Nivel Especificación
Nivel Implementación
Análisis
Diseño (Lenguajes de modelamiento e.g. UML)
Codificación (Lenguajes de programación e.g. Java, C++, C#, etc.)
02/08/2007Franco Guidi Polanco (PUCV-EII) 22
Perspectivas para Describir Sistemas OO: Ejemplo
Sistema de docencia, que mantiene datos de alumnos y registra sus inscripciones en cursos.
Nivel Conceptual
Nivel Especificación
Nivel Implementación
02/08/2007Franco Guidi Polanco (PUCV-EII) 23
Ejemplo: Nivel Conceptual
Responsabilidades:
Alumno:Mantener datos de un alumno (rol y nombre). Debe validar el rol del alumno.
Curso:Mantener datos de un curso (nombre)Mantener la lista de los alumnos que se inscriben en el curso, verificando que estos no se repitan al momento de agregarlos.Retornar alumnos, buscándolos por rol del alumno.
02/08/2007Franco Guidi Polanco (PUCV-EII) 24
Ejemplo: Nivel Especificación
Clase Alumno:
public setRol(numero: int, verificador: int)public setNombre( nombre: String)public getRol(): Stringpublic getNombre(): String
Clase Curso:
public setNombre(nombre: String)public addAlumno(alumno:Alumno):booleanpublic getAlumno(rol: String):Alumno
02/08/2007Franco Guidi Polanco (PUCV-EII) 25
Ejemplo: Nivel Implementación
public class Alumno{private String rol, nombre;public void setRol(int numero, int verificador){if( sumaDigitos(numero) == verificador )
this.rol = rol +”-”+verificador;}public void setNombre(Sting nombre){this.nombre = nombre;
}public String getRol(){return rol;
}public String getNombre(){return nombre;
}private int sumaDigitos(int numero){...
}}
public class Curso{private String nombre;private Vector alumnos;public void setNombre(String nombre){this.nombre = nombre;
}public boolean addAlumno(Alumno alumno){if( getAlumno( alumno.getRol() )== null ){
alumnos.add( alumno );return true;
}return false;
}public Alumno getAlumno(String rol){
...}
}02/08/2007Franco Guidi Polanco (PUCV-EII) 26
¿Es necesario tomar precauciones, si el análisis inicial está bien hecho?
“All systems change during their life cycles. This must be borne in mind when developing systems
expected to last longer than the first version.”
Ivar Jacobson.“Object Oriented Software Engineering a Use Case
Driven Approach”, Addison Wesley, 1992,
02/08/2007Franco Guidi Polanco (PUCV-EII) 27
POO y Encapsulación
Tradicionalmente se asocia a “ocultamiento de datos” (estado) de un objeto.
Sin embargo, se refiere además a ocultamiento de:
implementación de métodostipo, clases derivadasdetalles de diseñoreglas de instanciación
02/08/2007Franco Guidi Polanco (PUCV-EII) 28
Encapsulación como Ocultamiento de Datos
Ejemplo:
public class Punto{private int coordA, coordB;public void setXY(int x, int y){
coordA = x;coordB = y;
}public int getX(){
return coordA;}public int getY(){
return coordB;}
}
El “contexto” de la clase Punto no tiene visibilidad de cómo ésta almacena sus datos.
Consecuencia:Puede modificarse el conjunto de variables de la clase Punto, sin que esto afecte su contexto.
02/08/2007Franco Guidi Polanco (PUCV-EII) 29
Encapsulación en la Implementación de Métodos
Ejemplo:
public class Angle{private double angle;public void setAngle(double a){
angle = a;}public double getSin(){
// Cálculo mediante series de// Taylor...
}}
El “contexto” de la clase Angle no tiene visibilidad del algoritmo de cálculo del seno del ángulo
Consecuencia:Puede modificarse la implementación del método sin afectar al contexto.
02/08/2007Franco Guidi Polanco (PUCV-EII) 30
Encapsulación del Tipo
Ejemplo
Figura
+dibujar()+rellenar()+ocultar()
Rombo
+dibujar()+rellenar()+ocultar()
Cuadrado
+dibujar()+rellenar()+ocultar()
Círculo
+dibujar()+rellenar()+ocultar()
Contexto
El “contexto” de las figuras no tiene visibilidad de cuál de ellas está exactamente utilizando.
Consecuencia:El contexto puede implementar una lógica común para utilizar cualquiera de las figuras (o cualquier nueva subclase).
02/08/2007Franco Guidi Polanco (PUCV-EII) 31
Encapsulación de Detalles de Diseño
Ejemplo
Banco
+recibirCliente()+atenderSiguiente()
Cola
+agregar()+sacar()
Cajero
+atender()
Contexto
El “contexto” de la clase Banco no tiene visibilidad de las clases que soportan sus operaciones.
Consecuencia:Puede modificarse la “arquitectura” del Banco sin afectar el contexto.
02/08/2007Franco Guidi Polanco (PUCV-EII) 32
Encapsulación de Reglas de Instanciación
public class LeonardoDaVinci{private static LeonardoDaVinci instance;private LeonardoDaVinci(){}public static LeonardoDaVinci getLeonardo(){
if( instance == null )instance = new LeonardoDaVinci();
}return instance;
}public String writeName(){
return “odranoeL”;}...
}
El “contexto” de la clase no tiene visibilidad de la lógica de instanciación de objetos LeonardoDaVinci. ¿Consecuencias?
Ejemplo
02/08/2007Franco Guidi Polanco (PUCV-EII) 33
Encapsulación y Diseño
Ante especificaciones variables y sistemas que evolucionan...
... ¿podemos lograr un buen diseño?
Sí, encontrando qué cosas pueden variar en
el diseño y encapsulándolas
02/08/2007Franco Guidi Polanco (PUCV-EII) 34
Encapsulación y Diseño
Muchos patrones de diseño (soluciones a problemas comunes de diseño) utilizan la encapsulación de tipos para crear capas de separación entre objetos.
La separación se crea asignando referencias a clases abstractas o interfaces.
Esto permite modificar alguno de los “lados” de la capa de separación, sin afectar a la otra.
02/08/2007Franco Guidi Polanco (PUCV-EII) 35
El principio “abierto-cerrado”
En el libro Object Oriented Software Construction de 1988, Bertrand Meyerpropuso el “Open-Closed Principle” (OCP)
“Las entidades de software (clases, módulos, funciones, etc.) deberían estar abiertos para extensión y cerrados para modificaciones.”
En otras palabras, el software debe ser diseñado para soportar la adición de nuevas funcionalidades, sin que esto comporte modificaciones en aquellas existentes.
No es siempre posible seguir completamente este principio.
Bertrand Meyer
02/08/2007Franco Guidi Polanco (PUCV-EII) 36
El principio “abierto-cerrado”
Síntomas de un mal diseño (cuando no se cumple este principio):
Al modificar un módulo de software, los cambios se propagan a otros módulos.
Por lo tanto:Se deben diseñar módulos que nunca cambiarán.Si los requerimientos cambian, se debe extender el comportamiento de tales módulos, agregando nuevo código, no modificando aquél existente.
La base de este principio está en los conceptos de:AbstracciónPolimorfismo
02/08/2007Franco Guidi Polanco (PUCV-EII) 37
El principio “abierto-cerrado”
Los módulos desarrollados bajo este principio tienen dos características:
Están “abiertos para extensión”: el comportamiento del módulo puede ser extendido, a fin de lograr un nuevo comportamiento, impusto por nuevos requerimientos de la misma o de otra aplicación.Están “cerrados para modificaciones”: el código fuente de un módulo existente no debe ser alterado.
02/08/2007Franco Guidi Polanco (PUCV-EII) 38
El principio “abierto-cerrado”
Aquí no se respeta el principio:
Dibujador
Héroe Enemigo
pinta(Personaje p)pintaHéroe(Héroe p)pintaEnemigo(Enemigo p)
Personaje
public void pinta(Personaje p){if( seRequierePintar ){
if( p instance of Héroe)pintaHeroe((Héroe) p);
else if(p instance of Enemigo)pintaEnemigo((Enemigo) p);
}…
}
¿Qué pasa si es necesario agregar un nuevo tipo de personaje (ej. un Mago)?
02/08/2007Franco Guidi Polanco (PUCV-EII) 39
El principio “abierto-cerrado”
Aquí si es respetado el principio:
Dibujador
Héroe Enemigo
pinta(Personaje p)
Personaje
public void pinta(Personaje p){if( seRequierePintar )
p.pinta();…
}
pinta() pinta()
Es posible agregar nuevos objetos a pintar (agregando una subclase de Personaje), sin modificar el código ya existente
pinta()
02/08/2007Franco Guidi Polanco (PUCV-EII) 40
Consecuencias del principio “abierto–cerrado”
“Regla” de diseño: Establecer visibilidad “privada” a variables de instancia.
Los conceptos de abstracción y polimorfismo del principio abierto-cerrado están asociados a la especificación de jerarquías de herencia.
¿Hay algo que decir respecto de las jerarquías de herencia? (Veamos el principio de sustitución de Liskov)
02/08/2007Franco Guidi Polanco (PUCV-EII) 41
El principio de sustitución de Liskov
Barbara Liskov, en “Data Abstraction and Hierarchy”, SIGPLAN Notices, 23, 5 (May 1988) estableció lo que hoy se conoce como el “Liskov Substitution Principle” (LSP):
“Las funciones que utilizan punteros o referencias a clases de base, deben ser capaces de utilizar subclases de éstas, sin necesidad de conocerlas”
Esto es:Cualquier propiedad que sea cierta para una súperclase, debe serlo también para sus subclases.Un cliente de una clase debe funcionar correctamente con cualquier subclase de ésta última. Barbara Liskov
02/08/2007Franco Guidi Polanco (PUCV-EII) 42
El principio de sustitución de Liskov
Ejemplo:
Programador
Aéreo Terrestre
Vehículo
Bus Tren
La clase Programador debe funcionar correctamente con la clase Vehículo, o con cualquier subclase de ella
02/08/2007Franco Guidi Polanco (PUCV-EII) 43
El principio de sustitución de Liskov
El LSP se violaría ante la presencia de situaciones como la siguiente:
Programador
Aéreo Terrestre
Vehículo
Bus Tren
public void programa(Vehículo v){if( v instance of Bus ){
throw new InvalidException();else
programaAutomático(v);}
}
programa(vehiculo v)
02/08/2007Franco Guidi Polanco (PUCV-EII) 44
El principio de “inversión de dependencia”
El “Dependency Inversion Principle” (DIP) establece cómo implementar los objetivos enunciados por el OCP y el LSP.
“Los módulos de alto nivel no deberían depender de los módulos de bajo nivel. Ambos deberían depender de abstracciones.Las abstracciones no deberían depender de detalles. Los detalles deberían depender de abstracciones.”
KleeKandinsky
02/08/2007Franco Guidi Polanco (PUCV-EII) 45
El principio de “inversión de dependencia”
Propone la estategia de depender de abstracciones (interfaces, funciones abstractas y/o clases abstractas), en vez de depender de funciones y clases concretas.
02/08/2007Franco Guidi Polanco (PUCV-EII) 46
El principio de “inversión de dependencia”
Aquí no se cumple el DIP:
Copiador
LectorTeclado EscritorDisco
public void copiar(LectorTeclado l, EscritorDisco e){while( !l.eof){
byte b = l.leer();e.escribir( b );
}}
La lógica general del copiador tiene “cableada” la acción sobre un LectorTeclado y un EscritorDisco ¿Posibilidad de reutilizar el código del Copiador?
02/08/2007Franco Guidi Polanco (PUCV-EII) 47
El principio de “inversión de dependencia”
Aquí sí se cumple:
Lector Escritor
Copiador
LectorTeclado EscritorDisco
public void copiar(Lector l, Escritor e){while( !l.eof){
byte b = l.leer();e.escribir( b );
}}
02/08/2007Franco Guidi Polanco (PUCV-EII) 48
Después de la OO... ¿qué?
Los objetos ofrecen una interfaz pública por medio de la cual otros objetos invocan sus comportamientos.
Los objetos son inherentemente reactivos: su comportamiento es gatillado por la acción (externa) de otro objeto.
Nuevo paradigma: agentes de software.
Los agentes de software son unidades de software con objetivos y responsabilidades.
Los agentes de software exhiben comportamientoproactivo: un agente actúa por cuenta propia sobre el ambiente y sobre otros agentes para alcanzar sus objetivos.