Está en la página 1de 23

PATRONES DE DISEÑO

1. ¿CUÁLES SON LOS PRINCIPIOS DEL DISEÑO? ¿EXPLÍQUELOS?

LOS 6 PRINCIPIOS DEL DISEÑO


Un buen diseño comienza con una comprensión clara de los conceptos básicos. Los seis
principios del diseño son pautas para reunir elementos de una manera en específico para
crear una comunicación efectiva, a través del diseño gráfico. La forma en que se aplican
estos principios afecta el contenido expresivo y el mensaje del trabajo. Es bastante raro
ver que solo se usa un principio a la vez, sin embargo, no necesariamente se deben usar
los seis principios en una página, incluso el uso de uno ayuda a crear un buen diseño.

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.

A continuación, hay algunos ejemplos de cómo se puede aplicar el contraste a un diseño:

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.

Como se muestra en la siguiente ilustración, a la izquierda, vemos cómo los objetos


individuales que están dispersos y no tienen relación entre sí tienden a crear diseños
confusos y caóticos sin puntos focales. Por otro lado, a la derecha, vemos cómo, cuándo
se colocan muy cerca el uno del otro, estos mismos objetos crean diseños limpios y
organizados que crean formas muy distintas.
REPETICIÓN
La repetición refuerza un diseño repitiendo elementos a lo largo de toda la pieza. Es un
esfuerzo consciente de unificar todas las partes de un diseño. Puede ser un formato
particular, un color, una forma, una fuente en negrita, incluso una textura: repitiendo el
elemento a lo largo del diseño, se crea consistencia y continuidad.

Un ejemplo de donde la repetición debería usarse con toda seguridad es el paquete de


negocios. Al repetir ciertos elementos en todas las piezas que conforman un paquete de
negocios (tarjetas de presentación, sobres, membretes, etc.) está solidificando su imagen
de marca y creando consistencia.
ESPACIO EN BLANCO
El espacio en blanco es la ausencia de texto y gráficos entre los elementos. También se
conoce como «espacio negativo». Aunque se denomina «espacio en blanco», no
necesariamente debe ser blanco, puede ser de cualquier color (negro, azul, rojo, amarillo,
etc.), cualquiera que sea el color de fondo. El espacio en blanco es importante porque
proporciona un espacio de respiración visual para el ojo haciendo que la página se sienta
menos apretada.

Como se muestra a continuación (a la izquierda), vemos un hermoso anuncio que es muy


limpio y atractivo, creado simplemente usando la menor cantidad posible de gráficos y
texto.
El espacio en blanco, o «espacio negativo», es también una gran manera de ser creativo
en el diseño de gráficos y logotipos. Puedes dar la ilusión de que hay un objeto allí
simplemente mostrando su contorno o parte de su contorno. Esto se muestra en la
siguiente ilustración (derecha). Al cortar una pieza de cada uno de los tres círculos en el
diseño, el contorno de un triángulo se hace visible.

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?

• S: Single Responsibility Principle (SRP)


• O: Open-Closed Principle (OCP)

• L: Liskov Substitution Principle (LSP)

• I: Interface Segregation Principle (ISP)

• D: Dependency Inversion Principle (DIP)

SINGLE RESPONSIBILITY PRINCIPLE

A class should have just one reason to change.

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)

Argumentos en contra de este principio

• Puedes llegar a tener demasiadas clases debido a la separación de


responsabilidades.

• Si no piensas bien en el diseño de la aplicación puede llegar a ser complicado


entender el panorama general de la arquitectura.

Veamos un ejemplo

La clase Employee tiene dos factores de cambio; se traduce a más de una


responsabilidad. El primero es el manejo de la información de los datos del empleado
(Employee) y el segundo se trata de imprimir el reporte del salario del Empleado, lo que la
lógica del método printSalaryReport() es muy distinta a la principal responsabilidad de la
clase:
ANTES: La clase contiene dos comportamientos distintos.

El problema se resuelve moviendo el método printSalaryReport() a una clase que tenga


como responsabilidad la gestión de Salario, Salary :

DESPUÉS: La cohesión de la clase Employee es más alta y con una única


responsabilidad.

OPEN-CLOSED PRINCIPLE

Software Entities (Classes, Modules, Functions, etc.) should be open for extension, but

closed for modification.

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.

No se debe de aplicar este principio cuando el número de sentencias if o switch en un


método no va a cambiar o si el comportamiento de la Entidad es fijo.

Argumentos en contra de este principio

• Requiere más esfuerzo el diseñar las clases

• 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()

El principal problema que encontramos en la clase SortAlgorithm es que debemos de


modificar el código existente para agregar una nueva funcionalidad (que podemos ver
directamente en el diagrama de clases), pero al ver más a detalle el código del
método sort() notamos que la clase se vuelve más compleja de lo que debería e implica
modificar directamente el sort(), agregar un nuevo método o incluso atributos; al momento
de hacer un cambio sobre la clase accidentalmente se puede afectar la funcionalidad de
las clases/módulos relacionadas a esta. La solución es abstraer la clase SortAlgorithm y
bajo el uso de la herencia crear las clases derivadas con el comportamiento necesario para
cada método de ordenamiento.

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.

De esta manera extendemos cuando se trate de agregar un nuevo método de


ordenamiento (que en la teoría son muchos) y se reduce la complejidad de la clase. Para el
caso de las clases relacionadas a SortAlgorithm, ahora usarán el potencial
del Polimorfismo:

SortAlgorithm sort;
...
sort = new Quicksort();
sort = new Mergesort();
sort = new Bubblesort();
...

LISKOV SUBSTITUTION PRINCIPLE

Let ϕ(x) be a property provable about objects of x of type T. Then ϕ(y) should be provable for

objects y of type S where S is a subtype of T.

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.

Robert C. Martin en su libro Agile Principles, Patterns, and Practices in C# popularizó el


termino llamándolo Liskov Substitution, con una versión más corta del termino:

Subtypes must be substitutable for their base types

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.

Argumentos en contra de este principio

• Requiere un mayor entendimiento de OOP y de la arquitectura en la aplicación.

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.

public abstract class Document{


public bool open(){
var file = new File(path+fileName);
return file.exists();
}
public abstract bool save();
}

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.

public class Drive{


saveAll(Document doc){
if(doc.open()){
if(doc.save()){
print('The document's saved');
}
}
}
}

En la clase derivada MyDocument en el método save obtendremos como resultado un


error, debido a que cambia el correcto funcionamiento esperado por la clase Drive. La
cohesión de la clase base define que primero debemos de llamar al método open para
luego llamar al método save.

public class MyDocument extends Document{


@override
public bool save(){
return null;
}
}

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(); }
}

INTERFACE SEGREGATION PRINCIPLE

Clients shouldn’t be forced to depend on methods they do not use.

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.

Argumentos en contra de este principio

• Requiere un mayor entendimiento de OOP y de la arquitectura en la aplicación.

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.

ANTES: La clase GoogleDrive implementa métodos que no necesita.

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).

DESPUÉS: Se definen interfaces pequeñas que resuelven un problema en específico, en


lugar de una interfaz grande con múltiples responsabilidades.

DEPENDENCY INVERSION PRINCIPLE

High-level classes shouldn’t depend on low-level classes. Both should depend on

abstractions. Abstractions shouldn’t depend on details. Details should depend on

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.

Argumentos en contra de este principio

• Requiere un mayor entendimiento de OOP

• Requiere más esfuerzo de diseño de la arquitectura en la aplicación.

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.

ANTES: La clase Report depende de una clase de bajo nivel.

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.

3. ¿ CUÁL ES LA CLASIFICACIÓN DE LOS PATRONES DE DISEÑO: CREACIONALES,


COMPORTAMENTALES Y ESTRUCTURALES?

¿Qué son los patrones de diseño de software?

Pues ni más ni menos son formas “estandarizadas” de resolver problemas comunes de


diseño en el desarrollo de software.

Las ventajas del uso de patrones son evidentes:

• Conforman un amplio catálogo de problemas y soluciones

• Estandarizan la resolución de determinados problemas

• Condensan y simplifican el aprendizaje de las buenas prácticas

• Proporcionan un vocabulario común entre desarrolladores


• Evitan “reinventar la rueda”

Según la finalidad del patrón, estos se clasifican en tres tipos:

• Patrones Creacionales

• Patrones Estructurales

• Patrones de comportamiento.

Veamos en detalle cada uno de estos tipos.

Patrones Creacionales

Como su nombre indica, estos patrones vienen a solucionar o facilitar las tareas de
creación o instanciación de objetos.

Estos patrones hacen hincapié en la encapsulación de la lógica de la instanciación,


ocultando los detalles concretos de cada objeto y permitiéndonos trabajar con
abstracciones.

Algunos de los patrones creacionales más conocidos son:

• Factory: Desacoplar la lógica de creación de la lógica de negocio, evitando al cliente


conocer detalles de la instanciación de los objetos de los que depende.

• 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.

• Factory Method: Expone un método de creación, delegando en las subclases la


implementación de este método.

• Builder: Separa la creación de un objeto complejo de su estructura, de tal forma que


el mismo proceso de construcción nos puede servir para crear representaciones
diferentes.

Patrones estructurales

Los patrones estructurales nos ayudan a definir la forma en la que los objetos se
componen.

Los patrones estructurales más habituales son:


• Adapter: Nos ayuda a definir una clase intermedia que sirve para que dos clases con
diferentes interfaces puedan comunicarse. Esta clase actúa como mediador, haciendo
que la clase A pueda ejecutar métodos de la clase B sin conocer detalles de su
implementación. También se conoce como Wrapper.

• Decorator: Permite añadir funcionalidad extra a un objeto (decora el objeto) sin


modificar el comportamiento del resto de instancias.

• 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.

Algunos de los más conocidos (por citar unos pocos) son:

• 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.

• Template Method: Especifica el esqueleto de un algoritmo, permitiendo a las


subclases definir cómo implementan el comportamiento real.

4. EXPLIQUE MVC

MODELO VISTA CONTROLADOR (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.

El modelo es el responsable de:

• Acceder a la capa de almacenamiento de datos. Lo ideal es que el modelo sea


independiente del sistema de almacenamiento.
• Define las reglas de negocio (la funcionalidad del sistema). Un ejemplo de regla
puede ser: "Si la mercancía pedida no está en el almacén, consultar el tiempo de
entrega estándar del proveedor".
• Lleva un registro de las vistas y controladores del sistema.
• Si estamos ante un modelo activo, notificará a las vistas los cambios que en los
datos pueda producir un agente externo (por ejemplo, un fichero por lotes que
actualiza los datos, un temporizador que desencadena una inserción, etc.).

El controlador es responsable de:

• 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 )".

Las vistas son responsables de:

• Recibir datos del modelo y los muestra al usuario.


• Tienen un registro de su controlador asociado (normalmente porque además lo
instancia).
• Pueden dar el servicio de "Actualización()", para que sea invocado por el controlador
o por el modelo (cuando es un modelo activo que informa de los cambios en los
datos producidos por otros agentes).
El flujo que sigue el control generalmente es el siguiente:

1. El usuario interactúa con la interfaz de usuario de alguna forma (por ejemplo, el


usuario pulsa un botón, enlace, etc.)
2. El controlador recibe (por parte de los objetos de la interfaz-vista) la notificación
de la acción solicitada por el usuario. El controlador gestiona el evento que llega,
frecuentemente a través de un gestor de eventos (handler) o callback.
3. El controlador accede al modelo, actualizándolo, posiblemente modificándolo de
forma adecuada a la acción solicitada por el usuario (por ejemplo, el controlador
actualiza el carro de la compra del usuario). Los controladores complejos están a
menudo estructurados usando un patrón de comando que encapsula las acciones
y simplifica su extensión.
4. El controlador delega a los objetos de la vista la tarea de desplegar la interfaz de
usuario. La vista obtiene sus datos del modelo para generar la interfaz apropiada
para el usuario donde se refleja los cambios en el modelo (por ejemplo, produce
un listado del contenido del carro de la compra). El modelo no debe tener
conocimiento directo sobre la vista. Sin embargo, se podría utilizar el patrón
Observador para proveer cierta indirección entre el modelo y la vista, permitiendo
al modelo notificar a los interesados de cualquier cambio. Un objeto vista puede
registrarse con el modelo y esperar a los cambios, pero aun así el modelo en sí
mismo sigue sin saber nada de la vista. El controlador no pasa objetos de dominio
(el modelo) a la vista aunque puede dar la orden a la vista para que se actualice.
Nota: En algunas implementaciones la vista no tiene acceso directo al modelo,
dejando que el controlador envíe los datos del modelo a la vista.
5. La interfaz de usuario espera nuevas interacciones del usuario, comenzando el
ciclo nuevamente.

También podría gustarte