Download La Programación Orientada a Objetos: Introducción “Half the battle

Document related concepts
no text concepts found
Transcript
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)
La Programación Orientada a Objetos:
Introducción
Prof. Franco Guidi Polanco
Escuela de Ingeniería Industrial
Pontificia Universidad Católica de Valparaíso, Chile
[email protected]
De http://pbfcomics.com/
Actualización: 02 de agosto de 2007
Franco Guidi Polanco (PUCV-EII)
De Problemas a Soluciones
™Los requerimientos:
ƒ son incompletos
ƒ usualmente están equivocados
ƒ son engañosos (y los usuarios
también)
ƒ no cuentan la historia completa
™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/2007
2
Los Requerimientos
™Análisis: entender el problema y sus
requerimientos
Franco Guidi Polanco (PUCV-EII)
02/08/2007
™Por lo tanto, los
requerimientos siempre
cambian
3
Franco Guidi Polanco (PUCV-EII)
02/08/2007
4
El Desarrollo de Proyectos
Metodologías y Modelos
La Ingeniería de Software provee:
™ Metodologías de desarrollo.
ƒ Desarrollo en cascada
ƒ Proceso Unificado
ƒ etc.
que propuso el
1 Lo
comité de proyecto
que se especificó
2 Lo
como requerimiento
3
™ Modelos para soportar el desarrollo
Lo que diseñó
el analista
Se estudiarán
en detalle
en curso de
Modelamiento
de Sistemas
ƒ Especificación estructurada (DFDs, MER, etc.)
ƒ UML
ƒ etc.
™ Lenguajes para la implementación
que desarrollaron
4 Lo
los programadores
Franco Guidi Polanco (PUCV-EII)
5
Lo que se instaló
al usuario
ƒ C, C++
ƒ Java
ƒ etc.
que necesitaba
6 Lo
el usuario
02/08/2007
5
Cecilia Serrano
(Miss Chile 1979)
Franco Guidi Polanco (PUCV-EII)
02/08/2007
6
Divide et Impera: Descomposición Funcional
™ “Divide et Impera”
The Beatles
Grease
™ 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.
Antes de la Programación
Orientada a Objetos
™ ¿Costo?
Teleserie de Cara
al Mañana
(1982)
1a Teletón (1978)
Franco Guidi Polanco (PUCV-EII)
02/08/2007
8
Descomposición Funcional
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.
...
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;
}
}
™ 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.
procedimiento calcularMedia(datos:arreglo, media:float)
{
i=0;
suma = 0;
mientras i <= 10 hacer
{
suma = suma + datos[i]
i = i + 1;
}
media = suma / 10
}
...
Franco Guidi Polanco (PUCV-EII)
02/08/2007
9
Descomposición Funcional: Reutilización de
Código
Programa original
.
.
i=1
mientras i<=10
{
si a[i]=10
i=i+1
}
.
.
i=1
mientras i<=10
{
si b[i]=10
i=i+1
}
.
.
i=1
mientras i<=10
{
si c[i]=10
i=i+1
}
.
hacer
entonces a[i]=0
hacer
entonces b[i]=0
hacer
entonces c[i]=0
Franco Guidi Polanco (PUCV-EII)
02/08/2007
10
Ventajas de Funciones o Subrutinas
™ Ahorro de memoria de computador (código fuente de
programas más corto).
Programa con subrutina
.
.
HacerCeros(a)
.
.
.
HacerCeros(b)
.
.
.
HacerCeros(c)
.
.
.
™ 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).
Procedimiento
HacerCeros(x:arreglo)
i=1
mientras i<=10 hacer
{
si x[i]=10 entonces x[i]=0
i=i+1
}
Franco Guidi Polanco (PUCV-EII)
02/08/2007
11
Franco Guidi Polanco (PUCV-EII)
02/08/2007
12
Reutilización antes de la POO: Tipos Abstractos de
Datos
Lenguajes de Programación
™Antes de la POO los lenguajes de programación
eran procedimentales.
ADT
NOTA:
NO LO INTENTE
Aproximación:
(Abstract
Data Type)
Imagine
programar en
Java, usando
sólo métodos
estáticos, con
instancias de
clases que no
tengan métodos.
Franco Guidi Polanco (PUCV-EII)
Tipo de dato
(No provisto por
el lenguaje de
programación)
+
Operaciones
Por separado, pero asociadas.
02/08/2007
13
Franco Guidi Polanco (PUCV-EII)
02/08/2007
14
La Programación Orientada a Objetos (POO)
Pulp Fiction
Q. Tarantino (1994)
Tragedia Transbordador Challenger
(1986)
™ El paradigma de la Orientación a Objetos es sucesor de la
descomposición funcional
™ Se centra en el concepto de Objeto:
Tim Berners-Lee
(CERN-1989)
Objeto = Datos + Métodos
La Programación
Orientada a Objetos
Derrumbe
Muro Berlín (09/09/1989)
Cecilia Bolocco
Miss Universo (1987)
(Definición tradicional)
™ 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.
Franco Guidi Polanco (PUCV-EII)
02/08/2007
16
POO versus Descomposición Funcional
¿Cómo identificar Objetos?
™ El modelo de programación funcional mantenía
centralizadas las responsabilidades:
™En problemas pequeños una técnica sencilla se
basa en la identificación de sustantivos y verbos :
ƒ Una cena en la cual un garzón pide a cada comensal lo que se
servirá, y luego les trae los platos solicitados.
ƒ Los sustantivos pueden ser objetos
ƒ Los verbos pueden ser métodos
™ 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.
Franco Guidi Polanco (PUCV-EII)
02/08/2007
17
Objetos
Franco Guidi Polanco (PUCV-EII)
02/08/2007
18
Visión de 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ública
del objeto.
™ 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
Franco Guidi Polanco (PUCV-EII)
02/08/2007
19
Franco Guidi Polanco (PUCV-EII)
02/08/2007
20
Perspectivas para Describir Sistemas OO
Nivel Conceptual
Perspectivas para Describir Sistemas OO: Ejemplo
™ Sistema de docencia, que mantiene datos de
alumnos y registra sus inscripciones en
cursos.
Análisis
Nivel Especificación
Codificación (Lenguajes de
programación e.g. Java, C++, C#, etc.)
Diseño (Lenguajes de
modelamiento e.g. UML)
Nivel Conceptual
Nivel Especificación
Nivel Implementación
Nivel Implementación
Franco Guidi Polanco (PUCV-EII)
02/08/2007
21
Franco Guidi Polanco (PUCV-EII)
Ejemplo: Nivel Conceptual
22
Ejemplo: Nivel Especificación
Responsabilidades:
™ Clase Alumno:
ƒ
ƒ
ƒ
ƒ
™ Alumno:
ƒ Mantener datos de un alumno (rol y nombre). Debe validar el rol
del alumno.
™ Curso:
02/08/2007
public
public
public
public
setRol(numero: int, verificador: int)
setNombre( nombre: String)
getRol(): String
getNombre(): String
™ Clase 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.
Franco Guidi Polanco (PUCV-EII)
02/08/2007
ƒ public setNombre(nombre: String)
ƒ public addAlumno(alumno:Alumno):boolean
ƒ public getAlumno(rol: String):Alumno
23
Franco Guidi Polanco (PUCV-EII)
02/08/2007
24
¿Es necesario tomar precauciones, si el análisis
inicial está bien hecho?
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 class Curso{
}
private String nombre;
public String getRol(){
private Vector alumnos;
return rol;
}
public void setNombre(String nombre){
public String getNombre(){
this.nombre = nombre;
return nombre;
}
}
public boolean addAlumno(Alumno alumno){
private int sumaDigitos(int numero){if( getAlumno( alumno.getRol() )== null ){
...
alumnos.add( alumno );
}
return true;
}
}
“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,
return false;
}
public Alumno getAlumno(String rol){
...
}
}
Franco Guidi Polanco (PUCV-EII)
02/08/2007
25
POO y Encapsulación
™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;
}
}
™Sin embargo, se refiere además a ocultamiento
de:
implementación de métodos
tipo, clases derivadas
detalles de diseño
reglas de instanciación
Franco Guidi Polanco (PUCV-EII)
02/08/2007
02/08/2007
26
Encapsulación como Ocultamiento de Datos
™Tradicionalmente se asocia a “ocultamiento de
datos” (estado) de un objeto.
ƒ
ƒ
ƒ
ƒ
Franco Guidi Polanco (PUCV-EII)
27
Franco Guidi Polanco (PUCV-EII)
02/08/2007
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.
28
Encapsulación en la Implementación de Métodos
™Ejemplo:
™Ejemplo
public class Angle{
private double angle;
public void setAngle(double a){
angle = a;
}
public double getSin(){
// Cálculo mediante series de
// Taylor
...
}
}
Franco Guidi Polanco (PUCV-EII)
Encapsulación del Tipo
El “contexto” de la
clase Angle no
tiene visibilidad
del algoritmo de
cálculo del seno
del ángulo
Figura
Contexto
Rombo
Consecuencia:
Puede modificarse
la implementación
del método sin
afectar al contexto.
02/08/2007
+dibujar()
+rellenar()
+ocultar()
29
Franco Guidi Polanco (PUCV-EII)
Encapsulación de Detalles de Diseño
+agregar()
+sacar()
Franco Guidi Polanco (PUCV-EII)
Cuadrado
Círculo
+dibujar()
+rellenar()
+ocultar()
+dibujar()
+rellenar()
+ocultar()
Consecuencia:
El contexto puede
implementar una
lógica común para
utilizar cualquiera
de las figuras (o
cualquier nueva
subclase).
02/08/2007
30
™Ejemplo
Banco
Cola
+dibujar()
+rellenar()
+ocultar()
Encapsulación de Reglas de Instanciación
™Ejemplo
Contexto
El “contexto” de
las figuras no tiene
visibilidad de cuál
de ellas está
exactamente
utilizando.
+recibirCliente()
+atenderSiguiente()
Cajero
+atender()
02/08/2007
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.
31
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?
}
Franco Guidi Polanco (PUCV-EII)
02/08/2007
32
Encapsulación y Diseño
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.
™ Ante especificaciones variables y sistemas
que evolucionan...
... ¿podemos lograr un buen
diseño?
™ La separación se crea asignando
referencias a clases abstractas o
interfaces.
™ Sí, encontrando qué cosas pueden variar en
el diseño y
Franco Guidi Polanco (PUCV-EII)
™ Esto permite modificar alguno de los
“lados” de la capa de separación, sin
afectar a la otra.
encapsulándolas
02/08/2007
33
El principio “abierto-cerrado”
Franco Guidi Polanco (PUCV-EII)
02/08/2007
34
El principio “abierto-cerrado”
™ En el libro Object Oriented Software
Construction de 1988, Bertrand Meyer
propuso el “Open-Closed Principle” (OCP)
™ Síntomas de un mal diseño (cuando no se cumple este
principio):
™ “Las entidades de software (clases,
módulos, funciones, etc.) deberían
estar abiertos para extensión y
cerrados para modificaciones.”
™ Por lo tanto:
ƒ Al modificar un módulo de software, los cambios se propagan a
otros módulos.
ƒ 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.
Bertrand Meyer
™ 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.
™ La base de este principio está en los conceptos de:
ƒ Abstracción
ƒ Polimorfismo
™ No es siempre posible seguir completamente este principio.
Franco Guidi Polanco (PUCV-EII)
02/08/2007
35
Franco Guidi Polanco (PUCV-EII)
02/08/2007
36
El principio “abierto-cerrado”
El principio “abierto-cerrado”
™Los módulos desarrollados bajo este principio
tienen dos características:
™Aquí no se respeta el principio:
Personaje
ƒ 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.
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);
}
…
}
Héroe
Enemigo
Dibujador
pinta(Personaje p)
pintaHéroe(Héroe p)
pintaEnemigo(Enemigo p)
™ ¿Qué pasa si es necesario agregar un nuevo tipo de
personaje (ej. un Mago)?
Franco Guidi Polanco (PUCV-EII)
02/08/2007
37
El principio “abierto-cerrado”
Franco Guidi Polanco (PUCV-EII)
02/08/2007
38
Consecuencias del principio “abierto–cerrado”
™Aquí si es respetado el principio:
™“Regla” de diseño: Establecer visibilidad “privada”
a variables de instancia.
Personaje
Dibujador
™Los conceptos de abstracción y polimorfismo del
principio abierto-cerrado están asociados a la
especificación de jerarquías de herencia.
pinta()
pinta(Personaje p)
Héroe
public void pinta(Personaje p){
if( seRequierePintar )
p.pinta();
…
}
pinta()
Enemigo
pinta()
™ Es posible agregar nuevos objetos a pintar (agregando una
subclase de Personaje), sin modificar el código ya existente
Franco Guidi Polanco (PUCV-EII)
02/08/2007
39
™¿Hay algo que decir respecto de las jerarquías de
herencia? (Veamos el principio de sustitución de
Liskov)
Franco Guidi Polanco (PUCV-EII)
02/08/2007
40
El principio de sustitución de Liskov
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):
™Ejemplo:
Programador
™ “Las funciones que utilizan punteros
o referencias a clases de base, deben
ser capaces de utilizar subclases de
éstas, sin necesidad de conocerlas”
Vehículo
™ 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.
Franco Guidi Polanco (PUCV-EII)
Bus
Barbara Liskov
41
El principio de sustitución de Liskov
Terrestre
Tren
Kandinsky
Franco Guidi Polanco (PUCV-EII)
02/08/2007
42
™ “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.”
programa(vehiculo v)
Bus
02/08/2007
™ El “Dependency Inversion Principle” (DIP) establece cómo implementar
los objetivos enunciados por el OCP y el LSP.
Vehículo
public void programa(Vehículo v){
if( v instance of Bus ){
throw new InvalidException();
else
programaAutomático(v);
}
}
Franco Guidi Polanco (PUCV-EII)
El principio de “inversión de dependencia”
™ El LSP se violaría ante la presencia de situaciones como la
siguiente:
Aéreo
Tren
™ La clase Programador debe funcionar correctamente con la
clase Vehículo, o con cualquier subclase de ella
02/08/2007
Programador
Terrestre
Aéreo
43
Franco Guidi Polanco (PUCV-EII)
Klee
02/08/2007
44
El principio de “inversión de dependencia”
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.
™Aquí no se cumple el DIP:
public void copiar(LectorTeclado l, EscritorDisco e){
while( !l.eof){
byte b = l.leer();
e.escribir( b );
}
}
Copiador
LectorTeclado
Franco Guidi Polanco (PUCV-EII)
02/08/2007
45
El principio de “inversión de dependencia”
™ Los objetos son inherentemente reactivos: su
comportamiento es gatillado por la acción (externa)
de otro objeto.
Copiador
Franco Guidi Polanco (PUCV-EII)
46
™ Los objetos ofrecen una interfaz pública por medio
de la cual otros objetos invocan sus
comportamientos.
public void copiar(Lector l, Escritor e){
while( !l.eof){
byte b = l.leer();
e.escribir( b );
}
}
LectorTeclado
02/08/2007
Después de la OO... ¿qué?
™Aquí sí se cumple:
Lector
Franco Guidi Polanco (PUCV-EII)
EscritorDisco
™ 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?
™ Nuevo paradigma: agentes de software.
™ Los agentes de software son unidades de software
con objetivos y responsabilidades.
Escritor
™ Los agentes de software exhiben comportamiento
proactivo: un agente actúa por cuenta propia sobre
el ambiente y sobre otros agentes para alcanzar sus
objetivos.
EscritorDisco
02/08/2007
47
Franco Guidi Polanco (PUCV-EII)
02/08/2007
48