Práctica de Diseño (Ingeniería I)
Introducción: Sobre las herramientas de diseño
Ejercicio 1
Dados los siguientes diagramas, complete los nombres de las clases de tal forma que los diagramas representen algún modelo posible.
En este último diagrama de secuencias, considerar cada una de las cinco activaciones de objetos (que están expresadas en forma secuencial, una luego de otra) como independientes unas de otras.
Ejercicio 2
Dadas las siguientes clases: DispositivoElectrico, AM-FMRadio, SonyDigitalRadio, Lavarropas, Dispositivo, DispositivoMecánico. Utilizando el conocimiento intuitivo del dominio del problema, se solicita lo siguiente:
- Determine el comportamiento esencial que los objetos, instancia de las clases dadas, tienen.
- Establecer una jerarquía de herencia de las clases.
- ¿En qué se basó para armar su jerarquía?
- Agregue más clases a la jerarquía.
Ejercicio 3
Modele los diagramas de clases del UML de modo que cualquier diagrama pueda ser instanciado a partir de las clases que usted modele. El modelo debe soportar como mínimo lo siguiente:
- Clases: nombre, y si es abstracta o concreta.
- Atributos: nombre y valor inicial.
- Métodos: nombre y parámetros.
- Relaciones de dependencia, de implementación, de herencia, de asociación simple, composición, agregación. En las relaciones que corresponda deberá poder indicarse: nombre de la relación y en cada extremo: nombre del rol, navegabilidad, multiplicidad y propiedades.
- Interfaces: usos e implementaciones.
Podrá extender su modelo para soportar accesibilidad de atributos y métodos u otras características que desee.
Uso de las herramientas durante el proceso de diseño
Ejercicio 4
Eustaquio, un burrero viejo, saluda al canillita de la esquina de su casa, compra la sexta y parte rumbo al hipódromo de Palermo.
Antes que la carrera comience, Eustaquio se acerca a la ventanilla 7, siempre apuesta en la misma por cábala, y le indica al cajero que desea apostar $1 a la yegua “O Primera o Mortadela” al primer lugar, $2 al caballo “Lole” al segundo lugar y $4 al caballo “Checho Batista” al tercer lugar. El cajero anota las apuestas de Eustaquio y recibe el dinero del apostador. A continuación guarda el dinero en la caja y el ticket de apuesta en el fichero de apuestas pendientes. Luego, el cajero le entrega el recibo a Eustaquio, tanto el recibo como el ticket tienen el mismo número de apuesta.
Finalizada la carrera, Eustaquio se acerca a la ventanilla en busca de sus ganancias (“O Primera o Mortadela” salió afortunadamente primera). El cajero recibe el recibo del apostador, lo compara contra et ticket en el fichero de apuestas pendientes y se fija los resultados de la carrera. Por último, tras corroborar que todo está en orden marca el ticket de apuesta como pagado, lo guarda en el fichero de apuestas pagadas y le paga a Eustaquio el monto correspondiente.
- Modele mediante diagramas de secuencias la situación planteada, utilice la cantidad de diagramas que considere necesarios.
- Construya diagramas de clases, completando atributos, métodos y visibilidad en cada clase.
- Explique brevemente cómo modelaría el hecho de que todos los caballos que participan en una carrera, reciban al menos una apuesta.
Respuesta:
El ejercicio ya fue resuelto en el segundo cuatrimestre del 2006.
Ejercicio 5
Se solicita diseñar la clase Boolean, que modele las constantes booleanas con sus operaciones básicas (negación, conjunción y disyunción). Diseñarlas de dos formas distintas. ¿Qué analogías/diferencias posee esta clase de diseño con su equivalente del modelo conceptual?
Ejercicio 6
Modele un semáforo.
- Modele un semáforo vehicular mediante un diagrama de clases.
- Idem anterior, pero un semáforo para peatones. ¿Surgieron nuevas entidades? ¿Y nuevos mensajes?
- Modele mediante un diagrama de secuencias el estado de las luces del semáforo peatonal.
- Modele mediante un diagrama de secuencias cómo los objetos colaboran para lograr que un peatón pueda cruzar una avenida sin ser atropellado. Suponer que el peatón se encuentra parado en la vereda con el semáforo (para el peatón) en rojo (una avenida tiene típicamente 4 semáforos).
- ¿Encuentra todas las restricciones del modelo representables con estas técnicas? Si no, utilice OCL para completar el modelo.
Tip 1: Justifique todo lo que considere necesario respecto al dominio del problema.
Tip 2: No realizar suposiciones sobre el dominio. Limitarse a los escenarios descriptos.
Ejercicio 7
Esta es la historia de Pablito, el que cumple con sus impuestos en la localidad de "Todus Ponens", un pueblo que poco tiene que ver con la lógica.
Resulta que Pablito llega a su casa y se encuentra que por debajo de la puerta, le llegaron dos boletas de impuestos y servicios (agua y gas) para pagar. Todas las facturas son enviadas a los abonados por la empresa concesionaria del servicio.
En la boleta de agua (como todos los servicios no medidos) figura el importe a abonar, pero en la boleta del gas (como todos los servicios medidos) figura además del importe a abonar, el valor consumido. El ente regulador de servicios públicos sugiere (en realidad impone) que antes de pagar un servicio medido, hay que fijarse en el medidor correspondiente si el valor consumido para ese bimestre coincide con el que figura en la boleta correspondiente, y si no coincide, hay que quejarse al ente. Para los servicios no medidos, se asume que el importe siempre será el correcto.
Lamentablemente, las buenas costumbres del pueblo dicen que para pagar un impuesto o servicio, hay que ir al ente (al mismo que el de antes) para consultar en qué banco del pueblo se puede pagar un impuesto/servicio para ese bimestre. Por suerte para Pablito, ambos impuestos los podía pagar en el Banco Municipal "Su dinero en nuestras manos". Entonces va a ese banco y paga ambos servicios en efectivo (el pago en los bancos municipales se realiza en efectivo).
Al otro día, le llegan otros dos servicios no medidos (cable y luz). Para pagar, hace lo mismo que el día anterior, y el ente le dice que el cable lo puede pagar en el mismo banco municipal del día anterior, pero la luz la tiene que pagar en el banco provincial "Todos para uno". Los bancos provinciales exigen que para pagar un impuesto, tienen que tener una cuenta en ese banco (no más de una), lo que representaría internamente una transferencia del importe de la cuenta personal a la concesionaria del servicio. Para realizar estos pagos, tiene que haber suficiente dinero en la cuenta, y si no, hay que realizar un depósito previo. No se permiten realizar extracciones en la cuenta. Como Pablito no tenía cuenta en este banco, se crea una con un depósito inicial de $100.
Al tercer día, le llega la boleta del teléfono, y cansado de tanto pagar, Pablito no paga. Al llegar el inicio del día de vencimiento, la empresa telefónica concesionaria (como cualquiera a quien no paga su servicio) le corta el teléfono (como a cualquiera que no haya pagado), y Pablito aprende a hacer señales de humo para comunicarse con sus vecinos...
Se adjunta abajo el modelo conceptual sugerido de todo el texto aquí detallado:
Archivo:Ing1-PracDiseno-Ej7-Enunciado.PNG
A partir del texto anterior y del detalle del diagrama de clases del modelo conceptual, se solicita lo siguiente:
- Reconocer los escenarios más representativos, y expresarlos en diagramas de secuencias.
- Realizar el diagrama completo de clases de diseño que sea consistente con las secuencias expresadas en el punto anterior.
- ¿Qué decisiones de diseño propiamente dichas podrían tomarse que no están comentadas en el texto? Dé algunos ejemplos e indique cómo estas decisiones cambian a los diagramas ya realizados.
- ¿Cómo cambiaría sus diagramas de clases y secuencias si se llegara a permitir otro tipo de entidad intermediaria recaudatoria para realizar los pagos (incluso algo completamente distinto a un banco)? ¿Y si algunas de ellas pueden contener “productos de crédito” de naturaleza muy distinta a las cuentas bancarias?
Resolucion:
Los sisguientes serian los diagramas de secuencias correspondientes a algunos de los escenarios más importantes.
El primero corresponde a recibir las boletas y verificar la medicion contra la del medidor. Corresponderia al metodo agregarFacturas([FacturaAgua, FacturaGas]) de Pablito.
Archivo:Ing1-PracDiseno-Ej7-RecibirFactura.PNG
El siguiente corresponde a realizar el pago de las dos facturas, pagarFacturas ([FacturaAgua, FacturaGas]) de Pablito.
Archivo:Ing1-PracDiseno-Ej7-PagarMunic.PNG
El último es el pago de las otras dos facturas, de las cuales una tiene que ser pagada en el banco provincial.
Archivo:Ing1-PracDiseno-Ej7-PagarProv.PNG
El archivo UML hecho con StarUML que contiene los diagramas anteriores puede bajarse aquí.
Ejercicio 8
Se solicita realizar el diseño del manejo de ascensores en un edificio, planteando secuencias y su correspondiente diagrama de clases, con las iguientes variantes:
- Que en el edificio exista un único ascensor no automático.
- Que en el edificio existan dos ascensores no automáticos, donde en cada piso el botón de llamada a los ascensores llame al ascensor que no esté ocupado que esté ubicado más próximo al piso llamador.
- Que en el edificio existan dos ascensores automáticos, donde en cada piso existen dos botones -uno para subir y el otro para bajar-. Considerar además que pueden existir varias estrategias de administración de ascensores automáticos (que siempre hay una activa, aunque ésta puede cambiar en cualquier momento por otra).
Analizar el impacto en el diseño que se produce al cambiar de una variante a otra.
Ejercicio 9
Se solicita realizar el diseño del problema relacionado con el ejercicio 12 de la práctica de casos de uso (mensajería instantánea). Construir escenarios para reflejar la interacción entre los objetos, para luego expresar el diagrama de clases de diseño.
No diseñar cuestiones relacionadas con la transmisión real de los mensajes del usuario origen al destino (relacionadas con la implementación de los protocolos de comunicación respecto a posibles servidores de mensajería).
Ejercicio 10
Se solicita realizar el diseño del problema relacionado con el ejercicio 4 de la práctica de FSM (máquina de venta de gaseosas). Construir escenarios para reflejar la interacción entre los objetos, para luego expresar el diagrama de clases de diseño.
Ejercicio 11
Se solicita realizar el diseño del problema relacionado con el ejercicio 5 de la práctica de FSM (comportamiento de un proceso industrial). Construir escenarios para reflejar la interacción entre los objetos, para luego expresar el diagrama de clases de diseño.
Tener en cuenta (sólo a los efectos del diseño), que existen dos tipos de máquinas para procesar materias primas, que son máquinas chinas y máquinas alemanas. Ambas comparten las características de ser procesadoras de materia, aunque sus naturalezas puedan ser diferentes.
Ejercicio 12
Se solicita realizar el diseño del problema relacionado con el ejercicio 9 de la práctica de FSM (horno a microondas). Construir escenarios para reflejar la interacción entre los objetos, para luego expresar el diagrama de clases de diseño.
Ejercicio 13
Se solicita realizar el diseño del problema relacionado con el ejercicio 2 de la práctica de MC (lotes de drogas). Construir escenarios para reflejar la interacción entre los objetos, para luego expresar el diagrama de clases de diseño.
Principios de diseño: Acoplamiento, Cohesión, Patterns
Ejercicio 14
Ejercicio 15
Contamos una interfaz con muchos métodos (fat interface) que es consumida por muchos clientes:
ClienteA solo utiliza el método showData(), ClienteB solo utiliza parseDate() y ClienteC solo readData().
Al tiempo de haber publicado nuestra interfaz FatServices, el ClienteC además de leer datos necesita un servicio para validarlos, entonces pide agregar un nuevo método validateData().
- Qué problemas encuentra al enfoque propuesto,
- ¿Qué principio o principios se están violando?
- Proponga un diseño alternativo
Respuesta:
Hay un alto grado de fan-in sobre la interfaz FatServices, es decir, es utilizada por muchos clientes, y contiene muchos métodos distintos, lo que genera un alto acoplamiento.
Al añadir un nuevo método requerido por un cliente, se obliga a todas las clases subyacentes que implementan dicha interfaz a implementar este nuevo método, clases que tal vez no son usadas por el cliente C.
Lo más conveniente es partir la FatServices en varias interfaces para modularizar el uso de cada una por parte de los clientes. Es decir, una interfaz por método en este caso, lo que ayuda al acoplamiento aunque lastima a la cohesión.
Ejercicio 16
Ejercicio 17
Eustaquio el burrero (un amigo de la casa), nos pidió un pequeño sistema que le permitiera comparar distintos caballos para poder determinar a cuál debía jugarle. En principio nos dijo que una estrategia que le funcionaba, era apostar a los caballos más jóvenes.
Luego de pensar unos minutos, le entregamos la siguiente solución:
Arrays.sort() es un método de la clase Array que permite ordenar arrays de objetos Comparables (que implementan la interfaz Comparable).
Eustaquio probó la solución, y se fue más que contento.
Una semana después, nuestro querido amigo volvió a charlar con nosotros, su táctica de apostar al más joven no estaba funcionando. Quería ahora, además de poder ordenar por edad, ordenar por peso (había algunos caballitos jóvenes que estaban siendo muy bien alimentados y estaban un poco rechonchos).
Ningún problema dijimos, es muy simple…o no?
- ¿Cómo se le ocurre solucionar el problema que nos plantea Eustaquio?
- ¿Violamos algún principio de diseño en nuestra primera solución?
- ¿Cuánto le cuesta a su solución propuesta en 1) permitir comparar también caballos por altura?
Respuesta:
La idea es implementar un strategy pattern para determinar como se comparan caballos. Hay dos alternativas.
Una posibilidad es modificar Arrays.Sort() para que en lugar de recibir objetos Comparables, también soporte recibir objetos que no implementen dicha interfaz, pero como parámetro adicional reciba un Comparer, que tome dos objetos de una determinada instancia y los compare. Así, se tendrían PesoComparer, AlturaComparer y EdadComparer, que implementan Comparer, y la strategy se haría en el método sort.
Si el método sort ya está cerrado, el pattern puede implementarse en el caballo mismo. Se mantiene la estructura de Comparers de la versión anterior, pero en lugar de pasarlo a Arrays.Sort() como parámetro, se lo asigna al mismo Caballo en un setter. El caballo, entonces, cuando quiera implementar el método CompareTo, simplemente llama al método CompareTo del Comparer que tenga asignado.
Y en mi opinion personal (Palla), no se violo ningun principio de diseño en la solucion inicial, de hecho, esta perfecta. El refactor para incluir los patterns necesarios no debe hacerse hasta que sea necesario. Pero eso no es lo que tiene que ir como respuesta aca! Deberia ir alguna paparruchada como que existe un alto grado de acoplamiento ya que un caballo no tiene por qué tener incorporado el conocimiento de cómo compararse que puede responder a distintos criterios variables.
Ejercicio 18
¿Qué patrones de diseño ayudan a cumplir OCP en un diseño?
Respuesta:
¿Qué significa OCP? Google contestó lo siguiente:
- Oral Contraceptive Pill
- Open Core Protocol
- Original Coated Paper
- Official Community Plan
- Optical Communication Products
- Omni Consumer Products (la compañia que hizo a Robocop!)
Aparentemente es Open-Closed Principle, que dice que las software entities should be open for extension, but closed for modification (artículo sobre el tema).
- La factory permite desacoplar la construcción de un determinado objeto dependiendo del contexto. La factory en sí obliga a modificar sus métodos al aparecer una nueva clase concreta del individuo que se crea, con lo que va contra este principio. La abstract factory lo salva, creando una nueva factory para cada conjunto de objetos relacionados a un mismo contexto; pero sigue siendo necesario algún lugar donde se haga el case por contexto (una factory de factories?).
- El adapter es justamente este principio. No modificar lo que ya existe sino agregarle una capa intermedia, extendiéndola para que pueda cumplir los pedidos de otros clientes.
- La strategy también lo cumple, agregando estrategias nuevas sin tener que modificar los algoritmos preexistentes.
- El pattern observer provee una forma mediante la cual el subject puede notificar a distintos objetos sin modificar su comportamiento. En cuaquier momento pueden aparecer nuevos observadores que también podrán ser notificados por el subject sin cambiar nada, o sea, es extensible.
- El signleton mucho menos.
- La facade permite abstraer a los clientes del manejo de un sistema complejo, pero no extiende funcionalidades, simplemente las remapea.
Ejercicio 19
Se tiene el siguiente diseño de un FileSystem:
El mismo permite modelar un sistema de directorios con sus archivos, y pedir la impresión de dicha lista por pantalla (dir). El siguiente código ejemplifica su uso:
public static void main(String[] args) { Directory myDoc = new Directory("My Documents"); Directory pictures = new Directory("Pictures"); Directory music = new Directory("MP3"); File f1 = new File("Silvina_Luna.jgp"); File f2 = new File("Pampita.jgp"); pictures.add(f1); pictures.add(f2); myDoc.add(pictures); File f3 = new File("Los Palmeras – Bombón Asesino.mp3"); music.add(f3); myDoc.add(music); myDoc.dir(); }
El resultado esperado es:
Directory name: My Documents Directory name: Pictures File name: Silvina_Luna.jgp File name: Pampita.jgp Directory name: MP3 File name: Los Palmeras – Bombón Asesino.mp3
- ¿Qué problemas encuentra en el diseño propuesto?
- Proponga una solución alternativa.
Respuesta:
Existe una funcionalidad común entre los dos objetos que es imprimirse por pantalla. El llamador (dir) debe castear a cada una de sus entradas al objeto que corresponda para llamar al mismo método. Como todo lo que implique casteo en general es feo, conviene extraer el comportamiento comun a una interfaz, digamos IImprimible (si, me gustan las interfaces à la NET, con la capital I adelante).
La solución consistiría en agregar dicha interfaz, con un único método dir o ls (está con dos nombres distintos en el enunciado) y que cada clase lo implemente de manera distinta. File debe solamente mostrar su nombre; Directory debe mostrar su nombre y llamar al método ls de todas sus entradas.
También hay que modificar el método Add de de directory para que solo tome IImprimibles.