Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Patrones de Diseño PDF
Patrones de Diseño PDF
EQUILIBRIO
El equilibrio es la distribución visual del peso de los objetos, colores y espacio en su
diseño. Tenga en cuenta que no es necesario que un diseño sea simétrico para que se lo
considere equilibrado, sino que también se puede equilibrar un diseño asimétrico. Por
ejemplo, con el equilibrio simétrico tendría un elemento en un lado y el mismo elemento
en el otro lado. En cambio, con un equilibrio asimétrico podría tener un elemento grande
en un lado y varios elementos más pequeños en el otro lado. El equilibrio del diseño se
logra por completo mediante la colocación de los elementos dentro de ese diseño.
CONTRASTE
El contraste en el diseño es una acentuación de las diferencias entre los elementos.
Aplicar contraste a un diseño le permite enfatizar o resaltar los elementos clave. Aunque
el contraste generalmente se aplica usando colores opuestos, el contraste es de hecho
una yuxtaposición de varios elementos del diseño, por lo que incluso diferencias en
texturas (áspero vs. suave), formas (grande vs. pequeño) y líneas (gruesas vs. finas), solo
por nombrar algunos, también crea contraste. La diferencia entre los elementos es lo que
crea el interés visual.
PROXIMIDAD
La proximidad es la relación de cómo encajan los objetos en una composición. El objetivo
principal de la proximidad es agrupar elementos relacionados para organizar su diseño. Al
colocar dos o más elementos muy cerca el uno del otro, los está agrupando como un
grupo cohesivo, en lugar de objetos dispersos y no relacionados. Esto también ayuda
enormemente a crear puntos focales para los espectadores.
ALINEACIÓN
La alineación es uno de los principios más básicos e importantes del diseño. Ayuda a
unificar los elementos en una página creando una conexión visual entre ellos. Incluso si
esos elementos no están muy cerca el uno del otro, cuando se alinea se crea una línea
invisible (tanto en el ojo como en la mente) que los conecta. Al establecer una conexión
visual con otra cosa en la página, la alineación les dice a los lectores que los dos
elementos pertenecen a la misma pieza; esto, a su vez, crea un diseño más nítido y
organizado.
2. ¿CUÁLES SON LOS PRINCIPIOS DE PROGRAMACIÓN SOLID? EXPLIQUE SUS
BENEFICIOS.
¿Qué es SOLID?
Es un conjunto de cinco principios destinados para que el diseño de software sea más
comprensible, flexible y mantenible. Se puede aplicar en cualquier lenguaje de
programación orientado a objetos (OOP); por lo cual, no es un framework o librería y no es
exclusivo a una tecnología en específico.
Al igual que todo en la vida, usar estos principios sin pensar o entenderlos, puede causar
más daño que beneficios. Recordemos que SOLID son un conjunto de principios y que
deben ser considerados como guías y no como reglas. Por lo tanto, el costo de aplicar
estos principios puede traer grandes beneficios en la arquitectura, pero si son aplicados de
la manera incorrecta, puede que la arquitectura sea más complicada de lo que debería ser.
El orden del acrónimo no significa nada, se les dio ese orden debido a que SOLID formaba
una regla mnemotécnica sencilla de recordar. Pero a todo esto ¿Qué significa acrónimo
SOLID?
Este término fue introducido por Robert C. Martin en su artículo The Principles of Object
Oriented Design. Este principio señala que cada clase debe tener una única
responsabilidad. Una clase debe tener una, y solo una, razón de cambio. El objetivo
principal de este principio es reducir la complejidad mediante la coherencia del
comportamiento de la clase; Por lo tanto aumentamos la cohesión de nuestro código.
Este principio nos ayuda a organizar el código, ayuda a reducir el anti patrón Spagethi
Code, reduce el número de líneas de código en la clase y/o métodos (recordemos que
clases con muchas líneas de código son difíciles de entender y mantener)
Veamos un ejemplo
OPEN-CLOSED PRINCIPLE
Software Entities (Classes, Modules, Functions, etc.) should be open for extension, but
Este término fue introducido por Bertrand Meyer en su libro Object Oriented Software
Construction. Este principio señala que una clase no se debe de modificar, pero sí se
puede extender haciendo uso de la herencia mediante el uso de abstracciones (clases
abstractas o interfaces). El objetivo principal de este principio es evitar que el código
existente se rompa cuando implemente nuevas funciones. Recordemos que una clase solo
debe ser modificada si se debe de hacer una corrección, no cada vez que se necesita
agregar una nueva funcionalidad porque se puede romper alguna funcionalidad existente
en módulos dependientes.
Este principio nos ayuda a reducir el riesgo de agregar nuevos bugs al código existente,
reduce el acoplamiento y mejora el índice de mantenimiento.
• Requiere mayor experiencia ya que se puede combinar este principio con los patrones
de diseño Strategy y Template method.
Veamos un ejemplo
Supongamos que tienes una aplicación y que dentro de las funcionalidades se necesita
ordenar datos con distintos algoritmos de ordenamiento; dependiendo de la fuente de
datos. Para ello se crea una clase con el nombre SortAlgorithm, que cumple con las
necesidades de ordenamiento pero con el paso de tiempo (o bajo el criterio de
investigación) se debe de implementar otros métodos de ordenamiento como bubble sort.
ANTES: Se tiene que modificar la clase SortAlgorithm para agregar una nueva
funcionalidad.
A simple vista podemos notar que debemos abrir la clase para agregar una nueva
funcionalidad, pero ahora veamos parte del código del método sort():
Código del método sort()
Nota: Clase derivada, clase hija, subclase o clase concreta significan lo mismo; extienden
de una abstracción o también llamada clase base.
DESPUÉS: La clase SortAlgorithm cambia ser abstracta y bajo el patrón Strategy cada
nueva funcionalidad será en una clase derivada.
SortAlgorithm sort;
...
sort = new Quicksort();
sort = new Mergesort();
sort = new Bubblesort();
...
Let ϕ(x) be a property provable about objects of x of type T. Then ϕ(y) should be provable for
Este es el principio más difícil de explicar debido a que fue introducido por Ph.D Barbara
Liskov que lo definió en su trabajo Data abstraction and hierarchy. Veamos la definición
informal:
Si S es un subtipo de T, entonces los objetos de tipo T en un programa de pueden ser
sustituidos por objetos de tipo S (es decir, los objetos de tipo S pueden sustituir
objetos de tipo T), sin alterar ninguna de las propiedades deseables de ese programa.
Este principio señala que una clase derivada puede ser reemplazada por cualquier otra
que use su clase base sin alterar el correcto funcionamiento. El objetivo principal de este
principio es el uso correcto del polimorfismo donde una subclase no debe remover
comportamiento de la clase base, no debe conocer a los demás subtipos y no debe violar
las pre-condiciones, post-condiciones de la clase base. Este principio es fundamental al
desarrollar librerías y frameworks, ya que las clases serán utilizadas por otras personas
cuyo código no puede acceder y cambiar directamente.
Este principio nos ayuda a tener un código flexible y más fácil de mantener; debido a que
se agrupan las clases que cuentan con el mismo comportamiento, pero no se debe de
aplicar con clases que tienen un comportamiento fijo. Además, esté principio trabaja de la
mano con el principio Open Close.
Veamos un ejemplo
Ejemplo de una jerarquía de clases que viola el principio de sustitución de Liskov.
Tenemos la clase abstracta Document que tiene dos métodos validate() y save(). El
método validate, verifica sí el documento existe en el servidor antes de guardar cualquier
modificación. En cuanto al método save, guarda el documento según las reglas de negocio
especificadas en la clase derivada.
En cuanto a la clase Drive, el método saveAll() recibe una instancia de la clase Document y
cuenta con la lógica para guardar diferentes archivos. Si alguna clase derivada no cumple
con las reglas de la clase base, estaría violando este principio.
En este caso al retornar un null, le indicamos a la clase Drive, que no fue posible guardar el
documento e incluso podríamos provocar un error de ejecución, ya que se espera un
valor boolean y esto viola el principio de Liskov.
Para resolver este problema, aplicaremos el principio de Liskov donde se respete las pre y
post condiciones que especifica la clase base. Al pasar la referencia, esperamos el
correcto funcionamiento de la misma.
public class MyDocument extends Document{
@override
public bool save(){
...
Files.write(path, data);
...
return Files.isFileSaved(); }
}
Este término fue introducido por Robert C. Martin durante su consultoría que realizó a la
empresa Xerox. Este principio señala que se deben de definir interfaces pequeñas que
resuelvan un problema específico (Role Interface), en lugar de tener interfaces grandes
que hagan muchas cosas (Head Interface). Esto quiere decir que los clientes deben de
implementar solo los métodos que realmente necesitan o de lo contrario, un cambio en una
interfaz rompería incluso a los clientes que no usan los métodos modificados.
Este principio nos ayuda a tener un bajo acoplamiento, alta cohesión y un código fácil de
mantener. Se debe de aplicar cuando existan clases con método vacíos o que devuelvan
valores por defecto. Pero no es recomendable utilizarlo cuando la clase no será rehusada o
que nadie depende de esta clase.
Veamos un ejemplo
Supongamos que vas a crear una librería para el fácil manejo de integración de
proveedores de servicio de alojamiento de archivos en la nube. En la primera versión de
esta librería, sé asumió que todos los proveedores tienen el mismo espectro de
características que Dropbox. Cuando se trato de implementar soporte para otro proveedor,
resultó que algunos métodos de la interfaz son demasiado amplios y simplemente no
tienen comportamiento alguno.
Podemos aplicar este principio creando Role Interface con métodos que tengan relación
entre sí para no obligar al cliente que dependa de cosas que no necesita. Tengamos en
cuenta que al hacer esto, estamos cumpliendo el principio de Single Responsibility. Y
recuerda entre más interfaces crees, más complejo se volverá tu código (mantén el
equilibrio).
abstractions.
El término Dependency Inversion fue introducido por Robert C. Martin en su artículo The
Principles of Object Oriented Design y luego lo popularizó en su libro Agile Principles,
Patterns, and Practices in C#. Este principio señala que los módulos de alto nivel no deben
de depender de los módulos de bajo nivel, ambos deben de depender de abstracciones y
no de clases concretas. Esto quiere decir que primero debemos diseñar el core del sistema
para detectar cuáles son las dependencias que se necesitan. Una vez definidas estas
dependencias, se pasa a crear las implementaciones que van a ser usadas por el core. En
otras palabras, en lugar de trabajar con clases acopladas entre si, se debe de trabajar con
interfaces como lo define este principio.
Este principio nos ayuda a tener un bajo acoplamiento, testeabilidad y flexibilidad en el
código. Se debe de aplicar cuando se necesite desacoplar clases que pueden cambiar en
el futuro o cuando el nivel de acoplamiento en el código es alto.
Veamos un ejemplo
En el siguiente ejemplo tenemos una clase llamada Report que depende de una clase
concreta, es decir, depende de una clase de bajo nivel. Esto significa que cualquier cambio
en la clase de bajo nivel, como por ejemplo cuando se actualice la versión del servidor de
la base de datos, puede afectar a la clase de alto nivel, ya que no se preocupa por los
detalles del almacenamiento de información.
Se puede solucionar este problema creando una interfaz que describa las operaciones sin
importar el servidor de la base de datos. La clase Report, dependerá de esa interfaz en
lugar de la clase de bajo nivel. Como resultado, la dirección de la dependencia original se
ha invertido: las clases de bajo nivel ahora dependen de abstracciones de alto nivel.
DESPUÉS: La clase Report ahora depende de una abstracción de alto nivel.
• Patrones Creacionales
• Patrones Estructurales
• Patrones de comportamiento.
Patrones Creacionales
Como su nombre indica, estos patrones vienen a solucionar o facilitar las tareas de
creación o instanciación de objetos.
• Abstract Factory: Nos provee una interfaz que delega la creación de una serie de
objetos relacionados sin necesidad de especificar cuáles son las implementaciones
concretas.
Patrones estructurales
Los patrones estructurales nos ayudan a definir la forma en la que los objetos se
componen.
• Facade: Una fachada es un objeto que crea una interfaz simplificada para tratar con
otra parte del código más compleja.
Patrones comportamentales
Los patrones comportamentales nos ayudan a definir la forma en la que los objetos
interactúan entre ellos.
• Command: Son objetos que encapsulan una acción y los parámetros que necesitan
para ejecutarse.
• Observer: Los objetos son capaces de suscribirse a una serie de eventos que otro
objeto va a emitir, y serán avisados cuando esto ocurra.
• Strategy: Permite la selección del algoritmo que ejecuta cierta acción en tiempo de
ejecución.
4. EXPLIQUE MVC
Modelo Vista Controlador (MVC) es un estilo de arquitectura de software que separa los
datos de una aplicación, la interfaz de usuario, y la lógica de control en tres componentes
distintos.
Se trata de un modelo muy maduro y que ha demostrado su validez a lo largo de los años
en todo tipo de aplicaciones, y sobre multitud de lenguajes y plataformas de desarrollo.
• El Modelo que contiene una representación de los datos que maneja el sistema, su
lógica de negocio, y sus mecanismos de persistencia.
• La Vista, o interfaz de usuario, que compone la información que se envía al cliente
y los mecanismos interacción con éste.
• El Controlador, que actúa como intermediario entre el Modelo y la Vista,
gestionando el flujo de información entre ellos y las transformaciones para adaptar
los datos a las necesidades de cada uno.
• Recibe los eventos de entrada (un clic, un cambio en un campo de texto, etc.).
• Contiene reglas de gestión de eventos, del tipo "SI Evento Z, entonces Acción W".
Estas acciones pueden suponer peticiones al modelo o a las vistas. Una de estas
peticiones a las vistas puede ser una llamada al método "Actualizar()". Una petición
al modelo puede ser "Obtener_tiempo_de_entrega ( nueva_orden_de_venta )".