Tema 2.
Principios del Diseño Orientado a
Objetos
Objetivo:
El alumno analizará a fondo los conceptos de la
teoría Orientada a Objetos, sus implicaciones y alcances,
aplicándolos a un Diseño Orientado a Objetos.
1.
Conceptos de Programación Orientada a Objetos
1.
Abstracción
2.
Encapsulamiento
3.
Polimorfismo
4.
Composición
5.
Herencia
2.
Implementación de conceptos de la POO en el lenguaje
Java
3.
Principios de Diseño Orientado a Objetos
Abstracción
Es el proceso con el que identificamos las propiedades y métodos de
un objeto.
Los números tienen un valor, y pueden sumarse, obtener su valor absoluto, etc.
Una ventana (GUI) tiene un titulo, una posición, dimensiones y puede moverse o modificar su tamaño
Ayuda a definir las capacidades y responsabilidades de distintos
objetos dentro de una interacción.
El objeto clienteCorreoElectrónico sabe enviar y recibir correos, mientras que el objeto calendario lleva el control de citas.
Al proceso de abstracción no le interesa definir los detalles de las
operaciones.
No necesitamos conocer algoritmo LZ77, sólo necesitamos saber que la operación deflate de un software de compresión toma un archivo y lo reduce de tamaño
Abstracción
Al identificar las responsabilidades de cada objeto
simplificamos el proceso de programación.
Si cada objeto solo tiene que realizar una tarea, la
implementación de sus métodos es mas sencilla.
En un video juego
motorRender
sólo se dedica a dibujar
en pantalla, no tiene que preocuparse por leer del teclado
pues eso lo hará
dispositivoEntrada
. Tampoco se
preocupa por dirigir cómo se moverán los personajes,
pues de eso se encarga
motorIA.
¿Cómo se traduce esto en código?
Interfaces claras y simples
Solo debemos exponer métodos que indiquen QUE debe hacer el objeto no
COMO
Abstracción
Ejercicio. Define la interfaz de los siguientes
objetos.
Lista de objetos
Conjunto de objetos
Encapsulamiento
Es un principio del DOO que indica que los datos y los métodos que
operan sobre ellos deben estar en el mismo objeto
punto contiene x, y y los métodos traslada, calculaDistanciaA que trabajan sobre las coordenadas
cadena contiene un arreglo de caracteres y los métodos aMayúsculas, aMinúsculas, reemplaza que trabajan sobre los caracteres
Evita que la estructura de un objeto esté dispersa por todo el código.
Las struct del lenguaje C permiten agrupar variables (datos) de manera lógica, pero no proporcionan un mecanismo para asociar las variables con las funciones que pueden trabajar con ellas.
Un lenguaje orientado a objetos (OO) debe proporcionar un
mecanismo para relacionar los atributos y los métodos
Java lo hace con el concepto de atributos y métodos de instancia.
¿Cómo se traduce esto en código?
Los datos (variables, atributos) deben estar en el mismo objeto
que los métodos que los van a manipular.
Code Smells
Son los síntomas de la falta, mal uso o abuso de los principios
de la POO
Debemos corregirlos de inmediato, ya que es muy probable
que indiquen otros problemas con la implementación o incluso
con la arquitectura.
Son el principio del
refactoring
.
Code Smells - Encapsulamiento
Feature envy
. Se refiere a cuando un método de una clase
utiliza muchas propiedades de un objeto de otra para realizar
sus cálculos.
Indica que los datos y los métodos que los utilizan se
encuentran en lugares distintos
Se está faltando al principio del
encapsulamiento
Code Smells - Encapsulamiento
Ejercicio. Identifica los dos casos de falta de
encapsulamiento
en el siguiente código
Ocultamiento de información
Promueve que los objetos no expongan información que solo le sirve a ellos mismos. Convirtiéndolos en atributos privados
Ayuda a simplificar la programación porque reduce los puntos en los que las variables pueden ser modificadas.
Solo el código de los métodos del objeto tiene permitido el acceso a los atributos del objeto
.
Ayuda a la abstracción pues oculta los detalles de la implementación.
matriz puede guardar sus elementos en un arreglo bidimensional o en
uno unidimensional (usando cálculos con los índices), pero eso no le interesa a los demás objetos. Nadie más que los métodos de matriz (transponer, inversa, multiplicaPorEscalar) pueden modificar los valores de sus elementos
Ocultamiento de información
Protege a los atributos de modificaciones indebidas o que rompan las
invariantes de un objeto
Nadie mas que los métodos entregarRefresco y recargarExistencias
debe modificar el contadorRefrescos. Además de protegerlo de
valores ilógicos como un número negativo.
Un lenguaje OO debe de proveer un mecanismo para ocultar los atributos al
resto de los objetos.
Java provee el modificador de acceso
private
para indicar que los
atributos solo están disponibles para los métodos de la misma clase
donde están declarados
¿Cómo se traduce esto en código?
Conceptos de Programación Orientada a Objetos
Todos los atributos que
solo deban ser vistos
por los métodos del
objeto
se
deben
declarar como privados.
Ocultamiento de información
Como regla general todos los atributos de una clase deben declararse
privados.
Si se necesita exponer alguno de los atributos se agrega un método que lo
devuelva (
getters
).
Si se necesita modificar un atributo, se agrega un método que lo modifique
(
mutators
) o que lo establezca (
setters
). Siempre revisando que los valores
a establecer no sean ilógicos para el objeto.
¿Cómo se traduce esto en código?
Composición
Los objetos del mundo real se pueden ver como una composición*
de objetos mas simples.
Un smartphone está compuesto por la pantalla, sistema de sonido, el circuito integrado etc.
Establece una relación “contiene un” entre objetos
Dividir un objeto en varios componentes ayuda a simplificar el diseño
y la implementación del sistema, pues a cada objeto se le asigna una
responsabilidad.
Del teclado se leen los comandos, la unidad de procesamiento realiza los cálculos y la pantalla muestra los resultados.
Conceptos de Programación Orientada a Objetos
* En la teoría de POO existen los conceptos composition y aggregation, por simplicidad se obviará la diferencia. Para mas información:
Composición
Cuando cada componente tiene una sola responsabilidad, sus
operaciones son mas sencillas
Es la forma más flexible de re-utilización de código
Un objeto bien definido y con una interfaz fácil de utilizar se puede
usar en muchas partes del sistema
¿Cómo se traduce esto en código?
Un objeto tiene otros objetos en sus atributos y los usa en
sus métodos para realizar tareas.
¿Cómo se traduce esto en código?
Un mismo objeto puede ser usado por varios. Con lo que
reutilizamos su código.
Herencia
Es otro mecanismo de re-utilización de código. En el que un objeto delega
la definición de un método (o atributo) a “alguien más”
Existen 2 tipos de herencia
Basada en objetos
Basada en clases
Herencia
En la herencia basada en objetos o delegación, un objeto delega a otro (su prototipo) todos aquellos métodos que no reconoce.
También conocida como basada en prototipo (prototypal inhertance)
Es la herencia usada por ECMAScript (JavaScript) y es más popular en lenguajes de tipos dinámicos.
Herencia
En la herencia basada en clases una clase
(hija) hereda la definición de los métodos de
su súper-clase (padre). Por lo tanto todos los
objetos que se crean a partir de la clase hija
presentan los métodos de las dos clases.
Es el tipo de herencia que proporciona Java,
C++ y otros lenguajes de tipos estáticos.
Es menos flexible que la herencia basada en
prototipo, por lo que hay que usarla con
precaución
¿Cómo se traduce esto en código?
¿Cómo se traduce esto en código?
Subtipos
Establece una relación “es un” entre clases
Un alumno es una persona
Un becario es un alumno
Un becario es una persona
Permite tratar objetos como instancias de la clase más general
que tienen en común
Los alumnos y los becarios “saben” hablar
Un método que trabaje con personas, igual lo puede hacer
con alumnos o becarios.
Subtipos
El subtipo también se conoce como herencia de interfaz (pues
presenta los mismos métodos)
Las
clases
MD5
y
SHA1
son
subtipos
de
AlgoritmoHuellaElectronica
BotonGuardar, BotonAbrir, BotonCerrar son subtipos de Boton
Estrictamente, es un concepto independiente del de Herencia
visto anteriormente.
En Java la Herencia (extends) implica también ser subtipo de la
clase padre. Pero el subtipo también se puede obtener
implementando una Interfaz (implements)
¿Cómo se traduce esto en código?
Polimorfismo
Es el mecanismo por el cual un lenguaje OO decide que versión de
un método usar.
Distintas clases pueden tener distintas implementaciones del mismo
método.
El método acción de la clase BotonAbrir se comporta de manera distinta al de la clase BotonGuardar o de BotonCerrar.
Se elige la versión dependiendo del tipo de objeto sobre el que se
llame el método.
Si el objeto botón1 es del tipo BotonAbrir, se elegirá la versión definida en la clase BotonAbrir