Upload
loren-diaz
View
250
Download
0
Embed Size (px)
DESCRIPTION
Tema 1 - ED
Citation preview
1
Programa Informá,co
• Se define como un conjunto de instrucciones que se ejecutan de manera secuencial con el obje4vo de realizar una o varias tareas en un sistema.
• Es creado por un programador en un lenguaje determinado, y que será compilado y ejecutado por un sistema.
• Cuando un programa es ejecutado el procesador ejecuta el código compilado instrucción por instrucción.
• Un programa informá4co es soBware, aunque un conjunto de programas también lo es. 2
• Para comprender como un programa interactúa con un sistema es necesario comprender la funcionalidad básica y el programa básico. Para ello hay que entender el funcionamiento de una única instrucción en la máquina von Neumann.
• El procesador ejecuta instrucciones una a una, pero no solo eso, sino que cada instrucción conlleva realizar una serie de microinstrucciones para llevarla a cabo.
• Imaginemos que tenemos un programa que pide dos números y los suma. Dicho programa corresponde a la siguiente línea:
c = a + b • El ordenador tendrá reservada una can4dad de posiciones de memoria definidas por el 4po de variables que se corresponden con las variables de las instrucciones.
Arquitectura Von Neumann
3
• El procesador no puede ejecutar dicha instrucción (por sencilla que sea) de un solo golpe. Ha de acudir a la ALU (Aritme'c Logic Unit) que 4ene un número muy limitado de operaciones que puede realizar.
• Hay que tener en cuenta que: • La ALU solo puede realizar una operación a la vez. • El registro temporal de la ALU, el bus y los registros solo pueden almacenar un dato a la vez.
• Durante el proceso se deben llevar las posiciones de memoria(R1 y R2) a los buses, y de los buses a la ALU, la ALU suma y después de nuevo a los buses, y de los buses a R3.
Arquitectura Von Neumann
4
Arquitectura Von Neumann
5
• El funcionamiento básico no ha cambiado, hoy en día. • El programa se sigue almacenando en una memoria no volá4l y se sigue ejecutando en la memoria de acceso aleatorio, al igual que las variables.
• La interacción con el sistema no siempre es directa: no todos los programas 4enen acceso libre y directo al hardware, por lo que podemos clasificar los programas como soBware de sistema y soBware de aplicación. • SoBware de sistema: se encarga de controlar y ges4onar el hardware, así como de ges4onar el soBware de aplicación. Por ejemplo el sistema opera4vo.
• SoBware de aplicación: aplicaciones comerciales usadas hoy en día. Por ejemplo una sistema gestor de bases de datos.
Arquitectura Von Neumann
6
• Conjunto de instrucciones, operadores y reglas que se ponen a disposición del programador para que éste pueda comunicarse con los disposi4vos de hardware y soBware existentes.
• Facilitan la tarea de crear programas, permi4endo con un mayor nivel de abstracción realizar las mismas operaciones que se podrían realizar u4lizando código máquina.
• El código máquina es el único código que todo ordenador es capaz de entender: se basa en un conjunto de 0s y 1s de grandes proporciones.
• Este método de programación resulta inviable para cualquier programador, hasta que se estableció un lenguaje con las secuencias de programación más frecuentes, estableciéndolas en posiciones de memoria concretas. A esto se le llamo lenguaje ensamblador.
Lenguajes de programación
7
• Con la aparición del uso de los ordenadores para computación cien]fica el uso del lenguaje ensamblador resultaba muy complicado (ya que no eran informá4cos los usuarios), por lo que se creo un nuevo lenguaje más fácil para facilitar la tarea del programador: FORTRAN (FORmula TRANsla'on).
• De esta forma se eleva el nivel de abstracción del código máquina lo más posible, haciendo la tarea más liviana, entendible e intui4va.
• Aunque usemos lo que usemos lo que usemos siempre acabará como 0s y 1s.
Lenguajes de programación
8
• La can4dad de lenguajes de programación es enorme, cada uno de ellos con caracterís4cas y obje4vos determinados.
• Se puede clasificar por una gran variedad de criterios, pero en este caso vamos a realizar la clasificación por 3 criterios: nivel de abstracción, forma de ejecución y paradigma.
• Para el nivel de abstracción nos encontraremos lenguajes que van desde el código máquina hasta el lenguaje que usamos diariamente. Podemos hablar de la can4dad de capas de ocultación de código máquina que hay entre el código que escribimos y el código que la máquina ejecutará en úl4mo termino. • Lenguajes de bajo nivel:
• Primera generación: es el código máquina. Cadenas interminables de secuencias de 0s y 1s que conforman operaciones que la máquina puede entender sin interpretación alguna.
Clasificación y Caracterís,cas
9
• Lenguajes de medio nivel: • Segunda generación: 4enen definidas instrucciones para realizar
operaciones sencillas con datos simples o posiciones de memoria. Corresponde al lenguaje ensamblador.
• Lenguajes de alto nivel: • Tercera generación: La gran mayoría de lenguajes de hoy en día
pertenecen a dicho nivel. Entre ellos destacamos los lenguajes del paradigma de programación orientada a objetos.
• Cuarta generación: son lenguajes creados con un propósito específico, al ser un lenguaje tan específico permite reducir la can4dad de líneas de código que tendríamos que hacer con otros lenguajes de tercera generación mediante procedimientos específicos.
• Quinta generación: son lenguajes naturales, que pretenden abstraer más aún el lenguaje u4lizando un lenguaje natural con una base de conocimientos que produce un sistema basado en el conocimiento. Puede establecerse el problema que hay que resolver y las premisas y condiciones que hay que reunir para que la máquina lo resuelva. Suele u4lizarse para I.A. y lógica.
Clasificación y Caracterís,cas
10
Clasificación y Caracterís,cas
• Depende de la forma de ejecutarse podemos clasificarlos como: • Lenguajes compilados: un compilador convierte el código
fuente en código objeto, y otro programa (enlazador) unirá el código objeto del programa con el código objeto de las librerías necesarias para producir el programa ejecutable.
• Lenguajes interpretados: ejecutan instrucciones directamente, sin que se genere código objeto, por lo que es necesario un programa que interprete el código y lo ejecute. En este caso traduce las instrucciones en 4empo real, mientras que el anterior no.
• Lenguajes virtuales: 4enen un funcionamiento muy similar al de los lenguajes compilados, pero, a diferencia de éstos, no se genera código objeto sino un bytecode que puede ser interpretado por cualquier arquitectura que tenga la máquina virtual que se encargará de interpretar dicho bytecode generado para ejecutarlo en la máquina.
11
Clasificación y Caracterís,cas
• Dependiendo del paradigma de programación, se clasifica a par4r de un enfoque par4cular de la construcción del soBware. • Paradigma impera4vo: programación como secuencia de instrucciones que
cambian el estado del programa, indicando cómo realizar una tarea. • Paradigma declara4vo: declara un conjunto de premisas y condiciones para
indicar qué es lo que hay que hacer y no necesariamente cómo hay que hacerlo.
• Paradigma procedimental: el programa se divide en partes más pequeñas, llamadas funciones y procedimientos, que pueden comunicarse entre sí. Permite reu4lizar código ya programado y solventa el problema de la programación spaghe=.
• Paradigma orientado a objetos: encapsula el estado y las operaciones en objetos, creando una estructura de clases y objetos que emula un modelo del mundo real, donde los objetos realizan acciones e interactúan con otros objetos.
• Paradigma funcional: evalúa el problema realizando funciones de manera recursiva, evita declarar datos haciendo hincapié en la composición de las funciones y en las interacciones entre ellas.
• Paradigma lógico: define un conjunto de reglas lógicas para ser interpretadas mediante inferencias lógicas. Permite responder preguntas planteadas al sistema para resolver problemas.
12
Obtención de código ejecutable • Nuestro programa, esté programado en el lenguaje que esté y
ejecutado en la arquitectura que sea, necesita ser traducido para ser ejecutado (a excepción del lenguaje máquina). Por lo que nos encontraremos con: • Código fuente: Conjunto de sentencias entendibles por el
programador que componen el programa o una parte de ello. Suele estar almacenado en un fichero del 4po texto como los que se pueden abrir por ejemplo, con el bloc de notas o Wordpad en los entornos Windows. El código fuente estará escrito en un lenguaje de programación determinado, elegido por el programador, como pueden ser: Basic, C, C++, C#, Java, Perl, Python, PHP.
• Código objeto: Conjunto de instrucciones y datos escritos en un lenguaje que en4ende el ordenador directamente: binario o código máquina. Provienen de la traducción de cierto código fuente, es un fragmento del programa final y es específico de la plataforma de ejecución.
• Código ejecutable: Reúne diferentes códigos u objetos generados por los programadores junto con las “librerías de uso general” (propias del entorno o del lenguaje de programación) componiendo el programa final. Este es el código que ejecutan los usuarios del sistema, y es específico para una plataforma concreta: Windows, Linux, Mac OS, o cierto sistema Hardware.
13
Compilación • Aunque el proceso de obtener nuestro código ejecutable pase tanto por
un compilador como por un enlazador, se suele llamar al proceso completo “compilación”.
• Todo este proceso se lleva a cabo mediante dos programas: el compilador y el enlazador. Mientras que el enlazador solamente une el código objeto con las librerías, el trabajo del compilador es mucho más completo.
• Las fases de compilación son: • Análisis lexicográfico: se leen de manera secuencial todos los
caracteres de nuestro código fuente, buscando palabras reservadas, operaciones, caracteres de puntuación y agrupándolos todos en cadenas de caracteres que se denominan lexemas.
• Análisis sintác4co-‐semán4co: agrupa todos los componentes léxicos estudiados en el análisis anterior en forma de frases grama4cales. Con el resultado del proceso del análisis sintác4co, se revisa la coherencia de las frases grama4cales, si su “significado” es correcto, si los 4pos de datos son correctos, si los arrays 4enen el tamaño y 4po adecuados, y así consecu4vamente con todas las reglas semán4cas de nuestro lenguaje.
14
Compilación
• Generación de código intermedio: una vez finalizado el análisis, se genera una representación intermedia a modo de pseudoensamblador con el obje4vo de facilitar la tarea de traducir al código abierto.
• Op4mización de código: revisa el código pseudoensamblador generado en el paso anterior op4mizándolo para que el código resultante sea más fácil y rápido de interpretar por la máquina.
• Generación de código: genera el código objeto de nuestro programa en un código de lenguaje máquina relocalizable, con diversas posiciones de memoria sin establecer, ya que no sabemos en qué parte de la memoria volá4l se va a ejecutar nuestro programa.
• Enlazador de librerías: como se ha comentado anteriormente, se enlaza nuestro código objeto con las librerías necesarias, produciendo en úl4mo término nuestro código final o código ejecutable.
15
Compilación
16
Procesos de desarrollo
• El desarrollo de un soBware o de un conjunto de aplicaciones pasa por diferentes etapas desde que se produce la necesidad de crear un soBware hasta que se finaliza y está listo para ser usado por un usuario.
• Ese conjunto de etapas en el desarrollo del soBware responde al concepto de ciclo de vida del programa.
• No en todos los programas ni en todas las ocasiones el proceso de desarrollo llevará fielmente las mismas etapas en el proceso de desarrollo; no obstante, son unas directrices muy recomendadas.
• Hay más de un modelo de etapas de desarrollo, que de modo recurrente suelen ser compa4bles y usadas entre sí, sin embargo vamos a estudiar uno de los modelos más extendidos y completos, el modelo en cascada.
17
Procesos de desarrollo
!18
Procesos de desarrollo
• El modelo en cascada consta de las siguientes fases: 1. Definición de los requisitos: Los servicios, restricciones y obje4vos
son establecidos con los usuarios del sistema. Se busca hacer esta definición en detalle.
2. Diseño de soBware: Se par4ciona el sistema en sistemas de soBware o hardware. Se establece la arquitectura total del sistema. Se iden4fican y describen las abstracciones y relaciones de los componentes del sistema.
3. Implementación y pruebas unitarias: Construcción de los módulos y unidades de soBware. Se realizan pruebas de cada unidad.
4. Integración y pruebas del sistema: Se integran todas las unidades. Se prueban en conjunto. Se entrega el conjunto probado al cliente.
5. Operación y mantenimiento: Generalmente es la fase más larga. El sistema es puesto en marcha y se realiza la corrección de errores descubiertos. Se realizan mejoras de implementación. Se iden4fican nuevos requisitos. 19
Procesos de desarrollo
• Una fase no comienza hasta que termine la fase anterior y generalmente se incluye la corrección de los problemas encontrados en fases previas.
• En la prác4ca, este modelo no es lineal, e involucra varias iteraciones e interacción entre las dis4ntas fases de desarrollo. Algunos problemas que se observan en el modelo de cascada son: • Las iteraciones son costosas e implican rehacer trabajo debido a la
producción y aprobación de documentos. • Aunque son pocas iteraciones, es normal congelar parte del
desarrollo y con4nuar con las siguientes fases. • Los problemas se dejan para su posterior resolución, lo que lleva a
que estos sean ignorados o corregidos de una forma poco elegante. • Existe una alta probabilidad de que el soBware no cumpla con los
requisitos del usuario por el largo 4empo de entrega del producto. • Es inflexible a la hora de evolucionar para incorporar nuevos
requisitos. Es dipcil responder a cambios en los requisitos. 20
Roles que interactúan en el desarrollo
• A lo largo del proceso de desarrollo de un soBware deberemos realizar, como ya hemos visto anteriormente , diferentes y diversas tareas.
• Es por ello que el personal que interviene en el desarrollo de un soBware es tan diverso como las diferentes tareas que se van a realizar.
• Los roles no son necesariamente rígidos y es habitual que par4cipen en varias etapas del proceso de desarrollo. • Analista de sistemas: uno de los roles más an4guos en el desarrollo
del soBware. Su obje4vo consiste en realizar un estudio del sistema para dirigir el proyecto en una dirección que garan4ce las expecta4vas del cliente determinando el comportamiento del soBware. Par4cipa en la etapa de análisis.
• Diseñador de soBware: Nace como una evolución del analista y realiza, en función del análisis de un soBware, el diseño de la solución que hay que desarrollar. Par4cipa en la etapa de diseño. 21
Roles que interactúan en el desarrollo
• Analista programador: Comúnmente llamado “desarrollador”, domina una visión más amplia de la programación, aporta una visión general del proyecto más detallada diseñando una solución más amigable para la codificación y par4cipando ac4vamente en ella. Par4cipa en las etapas de diseño y codificación.
• Programador: Se encarga de manera exclusiva de crear el resultado del estudio realizado por analistas y diseñadores. Escribe el código fuente del soBware. Par4cipa en la etapa de codificación.
• Arquitecto de soBware: Es la argamasa que cohesiona el proceso de desarrollo. Conoce e inves4ga los frameworks y tecnologías revisando que todo el procedimiento se lleva a cabo de la mejor forma y con los recursos más apropiados. Par4cipa en las etapas de análisis, diseño, documentación y explotación.
22
Patrones de desarrollo • Básicamente podemos decir que los patrones son soluciones a problemas ]picos en el desarrollo y diseño de soBware.
• Los obje4vos principales de los patrones de diseño son, entre otros: • Evitar buscar soluciones a problemas ]picos ya solucionados anteriormente.
• Estandarizar el modo en que se realiza el diseño. • Facilitar el aprendizaje de la solución a dichos problemas a los nuevos diseñadores.
• Así pues, el uso de patrones de diseño no es obligatorio, pero sí recomendable siempre que se puedan aplicar sin forzar su uso.
23
• Nombre Un buen nombre es vital porque será parte del vocabulario de diseño
• Nombres Alterna4vos Otros nombres de uso común para el patrón.
• Propósito Qué problema pretende solucionar.
• Mo4vación Descripción del problema y su contexto • Puede consis'r en un ejemplo (un escenario) que ilustre la clase de problemas que el patrón intenta resolver.
• En general se en'enden mejor los problemas concretos que los abstractos.
Plantillas de Patrones (Plantilla GoF)
• Estructura Representación gráfica de las clases de los objetos que par'cipan en el patrón y de sus relaciones estructurales (está'cas)
• Actualmente, lo más común es usar UML.
• Aplicabilidad ¿En qué situaciones puede/debe aplicarse el patrón? • Par4cipantes Las clases y objetos que par'cipan en el patrón y sus responsabilidades o roles
• Consecuencias ¿Qué efectos posi'vos y nega'vos implica el uso del patrón?
• ¿Cuáles son los compromisos de diseño que implica su uso? • ¿Qué aspectos de la estructura del sistema pueden variar de forma independiente?
• Colaboración Cómo colaboran los participantes para llevar a cabo sus responsabilidades y proporcionar el comportamiento deseado
Plantillas de Patrones (Plantilla GoF)
• Usos conocidos Al menos dos ejemplos de uso del patrón en aplicaciones reales.
• Implementación ¿Cómo puede implementarse el patrón en un lenguaje de programación?
• ¿Qué dificultades implica? • ¿Hay aspectos dependientes del lenguaje de programación?
• Código de ejemplo Fragmentos de código que ilustren cómo se implementa el patrón en uno o varios lenguajes de programación
• Patrones relacionados ¿Cuáles son los patrones más estrechamente relacionados con el dado?
• ¿Se usa en conjunción con otros patrones? ¿De qué manera?
Plantillas de Patrones (Plantilla GoF)
Propósito
Creación Estructurales Comportamiento
Ám
bito
Clase
Factory Method
Adapter Interpreter Template Method
Ob
jeto
Abstract Factory Builder Prototype Singleton
Adapter Bridge Composite Decorator Facade Flyweight Proxy
Chain of Responsibility Command Iterator Mediator Memento Observer State Strategy Visitor
Clasi2icación de los patrones (GoF) • Los criterios de clasificación: los obje4vos y áreas de aplicarlos:
Clasi2icación de los patrones (GoF)
• Los patrones se clasifican en 3 4pos diferentes: • Patrones creacionales: Resuelven problemas relacionados con la creación de instancias de objetos. Por ejemplo, el patrón Singleton se encarga de que sólo pueda exis4r una instancia de la clase a la que es aplicado.
• Patrones estructurales: Se centran en problemas relacionados con la forma de estructurar las clases. Por ejemplo, el patrón Composite permite trabajar con listas de objetos (u objetos compuestos) como si de un solo objeto se tratase.
• Patrones de comportamiento: Permiten resolver problemas relacionados con el comportamiento de la aplicación, normalmente en 4empo de ejecución. Por ejemplo, el patrón Strategy proporciona diferentes métodos (o algoritmos) para resolver un mismo problema, pudiendo decidir en 4empo de ejecución cuál de ellos u4lizar. 28
Patrones de diseño creacionales. • Como hemos indicado los patrones de diseño creacionales se centran en resolver problemas acerca de cómo crear instancias de las clases de nuestra aplicación. Entre ellos tenemos: • Object Pool (no es exactamente un patrón): se ob4enen objetos nuevos a través de la clonación. U4lizado cuando el costo de crear un objeto es mayor que el de clonarla. Especialmente con objetos muy complejos. Se especifica un 4po de objeto a crear y se u4liza una interfaz del proto4po para crear un nuevo objeto por clonación. El proceso de clonación se inicia instanciando un 4po de objeto de la clase que queremos clonar.
• Abstract Factory (fábrica abstracta): permite trabajar con objetos de dis4ntas familias de manera que las familias no se mezclen entre sí y haciendo transparente el 4po de familia concreta que se esté usando. 29
Patrones de diseño creacionales • Builder (constructor virtual): abstrae el proceso de creación de un objeto complejo, centralizando dicho proceso en un único punto.
• Factory Method (método de fabricación): centraliza en una clase constructora la creación de objetos de un sub4po de un 4po determinado, ocultando al usuario la casuís4ca para elegir el sub4po que crear.
• Prototype (proto4po): crea nuevos objetos clonándolos de una instancia ya existente.
• Singleton (instancia única): garan4za la existencia de una única instancia para una clase y la creación de un mecanismo de acceso global a dicha instancia.
30
Patrón creacional Abstract Factory. • El patrón Abstract Factory o Fábrica Abstracta resuelve el problema de crear familias de objetos. Veamos un ejemplo ]pico de este patrón:
• Imaginemos que estamos trabajando con Interfaces Gráficas de Usuario (GUI). Pensemos que, en nuestro programa, tenemos las clases Ventana y Boton. Pongamos, por ejemplo, que tenemos 2 interfaces diferentes: una con colores claros y otra con colores oscuros. Esto nos llevaría a tener 4 clases:
VentanaClara VentanaOscura BotonClaro BotonOscuro
• Cuando el usuario decida trabajar con colores claros, se deben crear instancias de VentanaClara y BotonClaro. Sin embargo, si el usuario decide u4lizar la interfaz de colores oscuros, deberíamos crear instancias de VentanaOscura y BotonOscuro. 31
Patrón creacional Abstract Factory • La forma más básica de hacerlo sería de esta manera: // A la hora de seleccionar la interfaz String GUI; GUI = "clara"; // u "oscura” // A la hora de crear un botón if(GUI == "clara"){
new BotonClaro(); }else if(GUI == "oscura"){
new BotonOscuro(); } // A la hora de crear una ventana if(GUI == "clara"){
new VentanaClara(); }else if(GUI == "oscura"){
new VentanaOscura(); } 32
Patrón creacional Abstract Factory
• Esto implicaría realizar una comprobación de la interfaz seleccionada cada vez que se quiera crear una Ventana o un Boton.
• La mejor opción en este caso sería u4lizar el patrón Abstract Factory.
• En este patrón se crean ciertas clases adicionales llamadas fábricas. Estas clases son las encargadas de crear los diferentes 4pos de ventanas y botones. Veamos un ejemplo de su estructura:
33
Patrón creacional Abstract Factory
34
Patrón creacional Abstract Factory • Iden4fiquemos cada clase del diagrama con las clases de nuestro ejemplo: • Cliente: Parte del programa que u4lizará las fábricas y productos. • IProductoA: Interfaz que define un ejemplo de producto. Se correspondería con la clase Ventana de nuestro ejemplo.
• ProductoA1 y ProductoA2: Los diferentes 4pos de ese producto. Se corresponderían con la clases VentanaClara y VentanaOscura.
• IProductoB: Interfaz que define otro ejemplo de producto. Se correspondería con la clase Boton de nuestro ejemplo.
• ProductoB1 y ProductoB2: Los diferentes 4pos de ese producto. Se corresponderían con la clases BotonClaro y BotonOscuro.
• IFabrica: Interfaz que define las funciones de creación de productos. En nuestro ejemplo podría llamarse InterfazGrafica y definiría las funciones crearVentana():Ventana y crearBoton():Boton.
• Fabrica1 y Fabrica2: Clases encargadas de crear los productos. En nuestro ejemplo, serían InterfazClara (que crearía instancias de VentanaClara y BotonClaro) e InterfazOscura (que crearía instancias de VentanaOscura y BotonOscuro).
35
Patrón creacional Abstract Factory • Cabe señalar que podría haber más 4pos de productos (Ventana, Boton, Icono, etc.) y más familias de estos (InterfazClara, InterfazOscura, InterfazAzul, InterfazRoja, etc.).
• Una vez u4lizado el patrón, el código anterior quedaría así: // A la hora de seleccionar la interfaz InterfazGrafica GUI = new InterfazClara();
// o new InterfazOscura(); // tal como pone el ejemplo descrito sería asi: //Fabrica GUI = new Fabrica1(); // A la hora de crear un botón GUI.crearBoton(); // A la hora de crear una ventana GUI.crearVentana(); • Según el 4po de InterfazGrafica instanciada, se crearán ventanas/botones de un 4po u otro dinámicamente, sin necesidad de comprobar a mano qué interfaz gráfica se está u4lizando.
36
Patrón creacional Builder • El patrón Builder o Constructor se u4liza cuando queremos crear un producto que 4ene diferentes partes. El siguiente ejemplo, basado en este otro, lo ilustra mejor:
• Imaginemos la cocina de una pizzería donde se hacen pizzas. Las pizzas constan de varias partes (masa, salsa y relleno), y podríamos tener 2 cocineros, cada uno especialista en un 4po de pizza. Esto nos llevaría a tener 5 clases:
Cocina Pizza Cocinero CocineroHawai CocineroPicante • En una situación como esta el patrón Builder nos puede ayudar. Veamos un ejemplo de su estructura:
37
Patrón creacional Builder
38
Patrón creacional Builder • Iden4fiquemos cada clase del diagrama con las clases de nuestro ejemplo: • Cliente: Parte del programa que u4lizará el resto de clases. • Director: Clase que decide qué constructor se u4liza y cuando se debe construir el producto. Se correspondería con la clase Cocina de nuestro ejemplo.
• IConstructor: Interfaz que define las funciones de creación de cada parte del producto y la función de obtención del producto resultante. En nuestro ejemplo se correspondería con Cocinero y definiría las funciones hacerMasa():void, u4lizarSalsa():void y hacerRelleno():void.
• Constructor1 y Constructor2: Clases encargadas de crear las partes del producto. En nuestro ejemplo, serían CocineroHawai y CocineroPicante.
• Producto: Clase del producto en sí. Se correspondería con la clase Pizza de nuestro ejemplo. 39
Patrón creacional Builder • De esta manera, un posible código de este ejemplo sería el siguiente:
var cocina; Cocina = new Cocina(); // Decidimos que se crearán pizzas hawaianas cocina.elegirCocinero(new CocineroHawai()); // Creamos la pizza var pizzaHawaiana; Pizza = cocina.nuevaPizza();
40
Patrón creacional Builder • El código de la clase Cocina podría ser: public class Cocina {
private Cocinero cocinero;
public void elegirCocinero(cocinero Cocinero) { this.cocinero = cocinero; }
public Pizza nuevaPizza() { cocinero.hacerMasa(); cocinero.utilizarSalsa(); cocinero.hacerRelleno(); }
} 41
Patrón creacional Factory Method • El patrón Factory Method o Método de Fábrica es una simplificación del patrón Abstract Factory. En un patrón Factory Method sólo existe un producto, no una familia de ellos.
• Imaginemos que deseamos crear un juego es4lo Tetris. En este juego tendríamos diferentes 4pos de piezas. Esto nos llevaría a tener una clase por cada 4po de pieza:
PiezaL PiezaT PiezaI ... • Cada vez que se crea una pieza nueva, desearíamos seleccionar el 4po de pieza de forma aleatoria.
• La forma más básica de hacerlo sería la siguiente: 42
Patrón creacional Factory Method // Seleccionaríamos el tipo de pieza aleatoriamente // 7 es el número de piezas diferentes en el Tetris uint tipo = Math.random()*7; // Creamos dicha pieza switch(tipo){
case 1: new PiezaL(); break; case 2: new PiezaT(); break; case 3: new PiezaI(); break; // ...
} 43
Patrón creacional Factory Method • Sin embargo, sería mucho más sencillo poder hacerlo de una manera parecida a esta:
// Seleccionaríamos el tipo de pieza aleatoriamente // 7 es el número de piezas diferentes en el Tetris uint tipo = Math.random()*7; // Creamos dicha pieza new Pieza[tipo](); • Para poder hacer algo así debemos u4lizar el patrón Factory Method.
• En este patrón se u4lizan fábricas, al igual que en el patrón Abstract Factory. Estas fábricas son las encargadas de crear los diferentes 4pos de piezas.
• Veamos un ejemplo de su estructura: 44
Patrón creacional Factory Method
45
ICreador Pieza
PiezaL PiezaT CreadorPiezaL CreadorPiezaT
Patrón creacional Factory Method
• Iden4fiquemos cada clase del diagrama con las clases de nuestro ejemplo: • Cliente: Parte del programa que u4lizará las fábricas y productos. • IProducto: Interfaz que define el producto. Se correspondería con una clase Pieza en nuestro ejemplo.
• ProductoA y ProductoB: Los diferentes 4pos del producto. Se corresponderían con la clases PiezaL, PiezaT y PiezaI.
• IFabrica: Interfaz que define las función de creación del producto. En nuestro ejemplo podría llamarse ICreador y definiría la función crearPieza():Pieza.
• FabricaA y FabricaB: Clases encargadas de crear los productos. En nuestro ejemplo, serían CreadorL (que crearía instancias de PiezaI), CreadorT (que crearía instancias de PiezaT), CreadorI (que crearía instancias de PiezaI), etc.
46
Patrón creacional Factory Method • Una vez u4lizado el patrón, el código anterior quedaría así: // Crearíamos una lista con todas las fábricas Vectos <ICreador> creadores; <ICreador> creadores = new Vector <ICreador>(); creadores.push(new CreadorL(), new CreadorT(), new CreadorI()); // Seleccionaríamos el tipo de pieza aleatoriamente uint tipo; // 7 es el número de piezas diferentes en el Tetris tipo = Math.random()*7; // Creamos dicha pieza creadores[i].crearPieza();
• De esta manera no necesitaríamos un switch, sino que se crearía la pieza a través del creador seleccionado.
47
Patrón creacional Prototype • El patrón Prototype o Proto4po resuelve el problema de duplicar objetos ya creados con anterioridad.
• Imaginemos que tenemos un programa de dibujo por ordenador en el cual podemos crear círculos y cuadrados. Cuando se crea un círculo, éste 4ene un radio de 50 píxeles y es de color rojo. Sin embargo, podemos redimensionar el círculo y cambiar su color. Cuando se crea un cuadrado, 4ene 50 píxeles de lado y es de color azul. Hasta aquí todo perfecto.
• Imaginemos ahora que el usuario decide crear un círculo y modifica su color y tamaño. Acto seguido, el usuario decide hacer una copia de dicho círculo.
• El código sería el siguiente: 48
Patrón creacional Prototype Circulo circuloNuevo; circuloNuevo = new Circulo(); circuloNuevo.color = circuloExistente.getColor(); circuloNuevo.radio = circuloExistente.getRadio(); • El patrón Prototype añade un método que permita crear una copia de un objeto. Veamos un ejemplo de su estructura:
49
Patrón creacional Prototype
50
Patrón creacional Prototype • Iden4fiquemos cada clase del diagrama con las clases de nuestro ejemplo: • Cliente: Parte del programa que u4lizará las fábricas y productos. • IProtoApo: Interfaz que define el método clonar():IProto4po. En nuestro ejemplo podría ser una clase llamada IObjetoGrafico.
• ProtoApo1 y ProtoApo2 : Las diferentes clases que implementarán el método de clonación. Se corresponderían con la clases Circulo y Cuadrado de nuestro ejemplo.
• Una vez u4lizado el patrón, el código anterior quedaría así:
Circulo circuloNuevo; circuloNuevo = circuloExistente.clone(); 51
Patrón creacional Singleton • El patrón Singleton se u4liza para no permi4r que existan múl4ples instancias de una clase, sino solamente una.
• Imaginemos un programa que, al hacer click en un icono de ayuda, cree una ventana nueva con los documentos de ayuda del programa. Normalmente, si el usuario hiciese click en el botón nuevamente, se abriría una nueva ventana, y así sucesivamente.
• Sin embargo, podríamos desear que, si la ventana de ayuda ya ha sido abierta, no se abra de nuevo. Para ello recurriríamos a un patrón Singleton, que aseguraría la existencia de una única ventana de ayuda en todo momento.
• Veamos un ejemplo de la estructura del patrón Singleton: 52
Patrón creacional Singleton
53
Patrón creacional Singleton • Iden4fiquemos cada clase del diagrama con las clases de nuestro ejemplo: • Cliente: Parte del programa que u4lizará las fábricas y productos. Podría ser el archivo .fla principal, por ejemplo.
• Singleton: Clase que se quiere instanciar una sola vez. Se corresponde con la clase VentanaAyuda de nuestro ejemplo.
• La forma de implementar el patrón Singleton en este ejemplo sería dotando a la clase VentanaAyuda de un método está4co getInstancia():VentanaAyuda que comprobase si ya existe una instancia VentanaAyuda o si, por el contrario, se debe crear.
• De esta manera, el código para crear una nueva VentanaAyuda sería el siguiente:
54
Patrón creacional Singleton VentanaAyuda ayuda; ayuda = VentanaAyuda.getInstance(); • Sin embargo, debemos evitar que el usuario pueda crear instancias de VentanaAyuda mediante el constructor new VentanaAyuda().
• La forma idónea de hacerlo es declarando el constructor como privado o protegido, de modo que no pueda ser llamado desde fuera de la clase VentanaAyuda.
55
Patrón creacional Singleton public class VentanaAyuda {
private static VentanaAyuda INSTANCE = new VentanaAyuda();
// El constructor privado no permite que se genere un // constructor por defecto (con mismo modificador de // acceso que la definición de la clase) private VentanaAyuda() { };
public static VentanaAyuda getInstance() { return INSTANCE; }
} 56
Patrón creacional Singleton • De esta forma si ejecutáramos lo siguiente:
new VentanaAyuda(); // Se devolvería un error y no se //instanciaría la ventana
VentanaAyuda.getInstancia(); // Se devolvería una nueva //instancia de VentanaAyuda
VentanaAyuda.getInstancia(); // Se devolvería la instancia //ya existente que se creó en //la linea anterior
57
Patrones estructurales • Lo fundamental son las relaciones de uso entre objetos. • Se trata de conseguir que cambios en los requisitos de la aplicación no ocasionen cambios en las relaciones entre los objetos.
• Las relaciones de uso están determinadas por las interfaces que soportan los objetos.
58
Adapter • Objetivo:
• Convierte la interfaz de una clase en otra que es la que esperan los clientes
• Nombres: • Wrapper, Adaptador
• Ejemplo: • La pila a partir del vector
Adapter - Ejemplo
Adapter - Estructura
Adaptador de clase Adaptador de objeto
Adapter - Aplicabilidad • Se quiere usar una clase existente y su interfaz
no concuerda con la que se necesita • Se quiere crear una clase reutilizable que coopere
con clases no relacionadas
Adapter - Consecuencias • Un adaptador de clases no nos servirá cuando
queramos adaptar una clase y sus subclases • Un adaptador de clases permite redefinir parte del
comportamiento de Adaptable • Un adaptador de objetos permite que un mismo
Adaptador funcione con muchos Adaptables
Bridge • Objetivo:
• Desacoplar una abstracción de su implementación para que ambas varíen de forma independiente
• Nombres: • Handle/Body, Puente
• Ejemplo: • Herencia de ventanas en diferentes plataformas
Bridge - Ejemplo
Bridge
Bridge - Estructura
Bridge - Aplicabilidad • Evitar un enlace permanente entre una
abstracción y su implementación • Los cambios en la implementación no deberían
tener impacto en los clientes • Se quiere ocultar completamente a los clientes la
implementación • Proliferación de clases • Se quiere compartir una implementación entre
varios objetos
Bridge - Consecuencias • Desacopla la interfaz y la implementación • Mejora la extensibilidad • Oculta detalles de implementación a los clientes
Composite • Objetivo:
• Compone objetos en estructuras de árbol parte-todo. Trata de forma uniforme elementos individuales y compuestos
• Nombres: • Compuesto
• Ejemplo: • Manejo de gráficos simples y compuestos
Composite - Ejemplo
Composite - Estructura
Composite - Aplicabilidad • Se quiere representar jerarquías de objetos
parte-todo • Se quiere que los clientes obvien diferencias entre
objetos compuestos e individuales
Composite - Consecuencias • Objetos primitivos y compuestos se tratan de
igual forma • Simplifica el cliente • Facilita añadir nuevos tipos de componentes • Puede hacer que un diseño sea demasiado
general
Decorator • Objetivo:
• Asigna responsabilidades adicionales a un objeto dinámicamente. Alternativa flexible a la herencia para extender la funcionalidad
• Nombres: • Wrapper, Decorador
• Ejemplo: • Caja de texto con decoradores
Decorator - Ejemplo
Decorator - Estructura
Decorator - Aplicabilidad • Añadir objetos individuales de forma dinámica y
transparente • Retirar responsabilidades a los objetos • Cuando la extensión por herencia no es viable
Decorator - Consecuencias • Más flexibilidad que la herencia estática • Evita clases cargadas de funciones en la parte
superior de la jerarquía • Un decorador y su componente no son idénticos • Muchos objetos pequeños
Facade • Objetivo:
• Proporciona una interfaz unificada para un conjunto de interfaces de un subsistema
• Nombres: • Fachada
• Ejemplo: • Compilador
Facade - Ejemplo
Facade - Estructura
Fachada
C1
C5
C2
C6
C3 C4
Facade - Aplicabilidad • Proporcionar una interfaz simple para un
subsistema complejo • Hay muchas dependencias entre los clientes y las
clases del subsistema • Queremos dividir en capa nuestros subsistemas
Facade - Consecuencias • Oculta a los clientes los componentes del
subsistema haciendo que sea más fácil de utilizar • Promueve un débil acoplamiento entre el
subsistema y los clientes • No impide que las aplicaciones usen las clases del
subsistema
Flyweight • Objetivo:
• Hacer más eficiente los sistemas con un gran número de objetos de grano fino
• Nombres: • Peso Ligero
• Ejemplo: • Procesador de texto
Flyweight - Ejemplo
Flyweight - Estructura
Flyweight - Aplicabilidad • Una aplicación utiliza un gran número de objetos • Los costes de almacenamiento son elevados • La mayor parte del estado del objeto se puede
hacer extrínseco • Muchos objetos se pueden representar por pocos • La aplicación no depende de la identidad de los
objetos
Flyweight - Consecuencias • Disminuyen requisitos de almacenamiento • Aumenta tiempo de ejecución con la
transferencia, búsqueda y cálculo del estado extrínseco
Proxy • Objetivo:
• Proporciona un representante o sustituto de otro objeto para controlar el acceso a éste
• Nombres: • Surrogate, Apoderado
• Ejemplo: • Visualización de imágenes en documentos
Proxy - Ejemplo
Proxy - Estructura
Proxy - Aplicabilidad • Proxy remoto: proporciona un representante local
de un objeto remoto • Proxy virtual: crea objetos costosos por encargo • Proxy de protección: controla el acceso seguro al
objeto original • Referencia inteligente: sustituto de un simple
puntero
Proxy - Consecuencias • Control previo a un objeto • Se pueden realizar operaciones sobre el objeto de
forma más eficiente/inteligente • Introduce un nivel de indirección al acceder a un
objeto
Patrones de Comportamiento Chain of Responsibility, Command, Interpreter, Iterator, Mediator, Memento, Observer, State, Strategy, Template Method, Visitor
Chain of Responsibility • Objetivo:
• Evita acoplar el emisor de una petición a un receptor permitiendo responder a varios objetos
• Nombres: • Cadena de responsabilidad
• Ejemplo: • Ayuda contextual en una aplicación
Chain of Responsibility - Ejemplo
Chain of Responsibility - Estructura
Chain of Responsibility - Aplicabilidad
• Hay más de un objeto que puede manejar la petición
• No se conoce a priori el manejar sino que debería determinarse automáticamente
• Se quiere enviar la petición a un grupo de objetos sin especificar el receptor
• El conjunto de objetos que pueden tratar la petición debería ser especificado dinámicamente
Chain of Responsibility - Consecuencias • Reduce el acoplamiento • Añade flexibilidad para asignar responsabilidades
a objetos • No se garantiza la recepción
Command • Objetivo:
• Encapsular una petición en un objeto para tener un control más fino sobre la petición
• Nombres: • Action, Transaction, Orden
• Ejemplo: • Menús de las aplicaciones
Command - Ejemplo
Command - Estructura
Command - Diagrama secuencia
: Receptor : Cliente unaOrden : Orden
: Invocador
Asignar(unaOrden)
Ejecutar( )Accion( )
<<create>>
Command - Aplicabilidad • Parametrizar objetos con una acción a realizar • Especificar, poner en cola y ejecutar peticiones en
diferentes instantes de tiempo • Permitir deshacer • Permitir registrar los cambios • Estructurar un sistema alrededor de operaciones
de alto nivel
Command - Consecuencias • Desacopla el objeto que invoca la operación de
aquél que sabe cómo realizarla • Las órdenes son objetos de primera clase • Se pueden ensamblar órdenes en una orden
compuesta (Orden Macro) • Es fácil añadir nuevas órdenes
Interpreter
• Objetivo: • Define la representación de la gramática de un
lenguaje junto con un intérprete • Nombres:
• Intérprete • Ejemplo:
• Expresion ::= literal | alternativa | secuencia | repetición | ‘(‘ expresion ‘)’
• Alternativa ::= expresion ‘|’ expresion • Secuencia ::= expresion ‘&’ expresion • Repetición ::= expresion ‘*’ • Literal ::= ‘a’ | ‘b’ | ‘c’ |… { ‘a’ | ‘b’ | ‘c’ |…}*
Interpreter - Ejemplo
Interpreter - Estructura
Interpreter - Aplicabilidad • Cuando hay un lenguaje que interpretar • La gramática es simple • La eficiencia no es una preocupación crítica
Interpreter - Consecuencias • Es fácil cambiar y ampliar la gramática • Resulta fácil implementarla • Las gramáticas complejas son difíciles de
mantener • Añadir nuevos modos de interpretar expresiones
Iterator • Objetivo:
• Acceder a los elementos de un agregado sin exponer su representación interna
• Nombres: • Cursor, Iterador
• Ejemplo: • Listas e iteradores sobre listas • STL
Iterator - Ejemplo
Iterator - Estructura
Iterator - Aplicabilidad • Acceder a un objeto agregado sin exponer su
representación interna • Permitir varios recorridos sobre los agregados • Proporcionar una interfaz uniforme para recorrer
diferentes estructuras agregadas
Iterator - Consecuencias • Permite variaciones en el recorrido de un
agregado • Los iteradores simplifican la interfaz del agregado • Se puede hacer más de un recorrido a la vez
sobre el mismo agregado
Mediator • Objetivo:
• Define un objeto que encapsula cómo interactúan una serie de objetos
• Nombres: • Mediador
• Ejemplo: • Elementos de interfaces de usuario sincronizados
Mediator - Ejemplo
: Cliente : ListaDesplegable : DirectorDialogoFuente : CampoDeEntrada
MostrarDialogo
UtilModificado( )
ObtenerSeleccion( )
EstablecerTexto( )
Mediator - Ejemplo
Mediator - Estructura
Cliente(from Logical View)
Mediator Colega-mediator
ColegaConcreto1
ColegaConcreto2MediatorConcreto
Mediator - Aplicabilidad • Un conjunto de objetos se comunican de forma
bien definida, pero compleja • Difícil reutilizar un objeto ya que éste se refiere a
muchos otros • Comportamiento distribuido entre varias clases
debería poder ser adaptado
Mediator - Consecuencias • Reduce la herencia • Desacopla a los “Colegas” • Simplifica los protocolos de los objetos • Abstrae cómo cooperan los objetos • Centraliza el control
Memento • Objetivo:
• Representa y externaliza el estado interno de un objeto sin violar la encapsulamiento
• Nombres: • Token, Recuerdo
• Ejemplo: • Deshacer
Memento - Estructura
Memento - Estructura
: Originador : Conserje : Memento
CrearMemento( ) <<create>>
EstablecerEstado( )
EstablecerMemento( )
ObtenerEstado( )
Memento - Aplicabilidad • Hay que guardar la instantánea de un objeto y
volverlo a recuperar más tarde
Memento - Consecuencias • Preservación de los límites del encapsulamiento • Simplifica al Creador • El uso de mementos puede ser costoso • Definición de interfaces reducidas y amplias • Costes ocultos en el cuidado de los mementos
Observer • Objetivo:
• Define una dependencia de uno a muchos, de forma que cuando se modifique, se actualicen automáticamente los otros
• Nombres: • Dependents, Publish-Subscribe, Observador
• Ejemplo: • Varias vistas de unos mismos datos
Observer - Ejemplo
a b c
x 60 30 10
y 50 30 20
z 80 10 10 a b c
ab
c
a= 50% b=30 % c=20%
Observer - Estructura
Observer - Estructura
: SujetoConcreto o1 : ObservadorConcreto o2 : ObservadorConcreto
EstablecerEstado( )
Notificar( )
Actualizar( )
ObtenerEstado( )
Actualizar( )
ObtenerEstado( )
Observer - Estructura
Observer - Aplicabilidad • Un cambio en un objeto requiere cambiar otros • Un objeto debería notificar algún cambio a otros
objetos sin hacer suposiciones sobre quiénes son estos
Observer - Consecuencias • Bajo acoplamiento entre sujeto y observador • Capacidad de comunicación mediante difusión • Actualizaciones inesperadas
State • Objetivo:
• Permite que un objeto modifique su comportamiento cuando varíe su estado interno
• Nombres: • Estado
• Ejemplo: • Conexiones TCP/IP
State - Ejemplo
State - Estructura
State - Aplicabilidad • El comportamiento de un objeto depende de su
estado y debe cambiar en tiempo de ejecución • Operaciones con muchas sentencias condicionales
que dependen del estado
State - Consecuencias • Localiza el comportamiento dependiente del
estado • Hace explícitas las transiciones entre estados • Los objetos Estado pueden compartirse
Strategy??? • Objetivo:
• Nombres: • Estrategia
• Ejemplo: • Convertir un fichero RTF a distintos tipos de
formatos de texto
Strategy - Ejemplo
Strategy - Estructura
Strategy - Aplicabilidad
Strategy - Consecuencias
Template Method ??? • Objetivo:
• Nombres: • Constructor
• Ejemplo: • Convertir un fichero RTF a distintos tipos de
formatos de texto
Template Method - Ejemplo
Template Method - Estructura
Template Method - Aplicabilidad
Template Method - Consecuencias
Visitor • Objetivo:
• Representa una operación sobre los elementos de una estructura de objetos
• Nombres: • Visitante
• Ejemplo: • Compilador
Visitor - Ejemplo
Visitor - Estructura
Visitor - Estructura : Estructura e1 :
ElementoConcreto1e2 :
ElementoConcreto2v :
VisitanteConcreto1
Aceptar(v)
VisitarElementoConcreto2(e2)
Operacion2( )
Aceptar(v)
VisitarElementoConcreto1(e1)
Operacion1( )
Visitor - Aplicabilidad • Muchas operaciones distintas sobre una misma
estructura de objetos. Evitar contaminar la estructura
• Las clases de la estructura de objetos rara vez cambian y se quieren definir nuevas operaciones
Visitor - Consecuencias • Se facilita añadir nuevas operaciones • Se agrupan operaciones relacionadas • Es difícil añadir nuevas clases de
ElementoConcreto • Visitar varias jerarquías de clases • Acumular el estado • Romper el encapsulamiento
Patrones de creación: Resumen • The Factory Method retorna una de las posibles subclases de una clase abstracta dependiendo de los datos que se le provee.
• The Abstract Factory Method retorna una de las varias familias de objetos.
• The Builder PaJern separa la construcción de un objeto complejo de su representación. Varias representaciones se pueden crear dependiendo de las necesidades del programa.
• The Prototype PaJern inicializa e instancia una clase y luego copia o clona si necesita otras instancias, mas que crear nuevas instancias.
• The Singleton PaJern es una clase de la cual no puede exis'r mas de una instancia.
156
Patrones estructurales: Resumen • Adapter: cambia la interfaz de una clase a la de otra. • Bridge: permite mantener constante la interfaz que se presenta al cliente, cambiando la clase que se usa
• Composite: una colección de objetos • Decorator: una clase que envuelve a una clase dándole nuevas capacidades.
• Facade: reúne una jerarquía compleja de objetos y provee una clase nueva permi'endo acceder a cualquiera de las clases de la jerarquía.
• Flyweight: permite limitar la proliferación de pequeñas clases similares.
157
Patrones de comportamiento: Resumen • Cadena de responsabilidad: permite que un conjunto de clases intenten manejar un requerimiento.
• Interpreter: define una gramá'ca de un lenguaje y usa esa gramá'ca para interpretar sentencias del lenguaje.
• Iterator: permite recorrer una estructura de datos sin conocer detalles de cómo están implementados los datos
• Observer: algunos objetos reflejan un cambio a raíz del cambio de otro, por lo tanto se le debe comunicar el cambio de este úl'mo.
• Strategy: can'dad de algoritmos relacionados encerrados en un contexto a través del cual se selecciona uno de los algoritmos.
Otros tipos de patrones • Patrones de programación concurrente • Patrones de interfaz gráfica • Patrones de organización de código • Patrones de op4mización de código • Patrones de robustez de código • Patrones de fases de prueba