Articulo de referencia

Patrón mediador

En ingeniería de software , el patrón mediador define un objeto que encapsula cómo interactúa un conjunto de objetos. Este patrón se considera un patrón de comportamiento debido...

En ingeniería de software , el patrón mediador define un objeto que encapsula cómo interactúa un conjunto de objetos. Este patrón se considera un patrón de comportamiento debido a la forma en que puede alterar el comportamiento de ejecución del programa.

En la programación orientada a objetos, los programas suelen estar compuestos por muchas clases . La lógica empresarial y los cálculos se distribuyen entre estas clases. Sin embargo, a medida que se añaden más clases a un programa, especialmente durante el mantenimiento o la refactorización , el problema de la comunicación entre estas clases puede volverse más complejo. Esto hace que el programa sea más difícil de leer y mantener. Además, puede resultar difícil cambiar el programa, ya que cualquier cambio puede afectar al código de varias otras clases.

Con el patrón mediador, la comunicación entre objetos se encapsula dentro de un objeto mediador . Los objetos ya no se comunican directamente entre sí, sino que se comunican a través del mediador. Esto reduce las dependencias entre los objetos que se comunican, lo que reduce el acoplamiento .

Descripción general

El patrón de diseño mediador [1] es uno de los veintitrés patrones de diseño conocidos que describen cómo resolver problemas de diseño recurrentes para diseñar software orientado a objetos flexible y reutilizable, es decir, objetos que son más fáciles de implementar, cambiar, probar y reutilizar.

Problemas que el patrón de diseño mediador puede resolver[2]

  • Se debe evitar el acoplamiento estrecho entre un conjunto de objetos que interactúan.
  • Debería ser posible cambiar la interacción entre un conjunto de objetos de forma independiente.

Definir un conjunto de objetos que interactúan accediendo y actualizándose entre sí directamente es inflexible porque vincula estrechamente los objetos entre sí y hace imposible cambiar la interacción independientemente de los objetos (sin tener que cambiarlos). Además, impide que los objetos sean reutilizables y dificulta su prueba.

Los objetos estrechamente acoplados son difíciles de implementar, cambiar, probar y reutilizar porque hacen referencia a muchos objetos diferentes y conocen sus características.

Soluciones descritas por el patrón de diseño del mediador

  • Define un objeto separado (mediador) que encapsula la interacción entre un conjunto de objetos.
  • Los objetos delegan su interacción a un objeto mediador en lugar de interactuar entre sí directamente.

Los objetos interactúan entre sí indirectamente a través de un objeto mediador que controla y coordina la interacción.

Esto hace que los objetos estén débilmente acoplados . Solo hacen referencia a su objeto mediador y conocen su existencia, pero no tienen conocimiento explícito entre sí.

Vea también el diagrama de clases y secuencias UML a continuación.

Definición

La esencia del patrón mediador es "definir un objeto que encapsula cómo interactúa un conjunto de objetos". Promueve el acoplamiento flexible al evitar que los objetos se refieran entre sí de manera explícita y permite que su interacción varíe de forma independiente. [3] [4] Las clases cliente pueden usar el mediador para enviar mensajes a otros clientes y pueden recibir mensajes de otros clientes a través de un evento en la clase mediadora.

Estructura

Diagrama de clases y secuencias UML

Un ejemplo de diagrama de clase y secuencia UML para el patrón de diseño del mediador. [5]

En el diagrama de clases UML anterior , las clases y no se refieren entre sí (ni se actualizan) directamente. En cambio, hacen referencia a la interfaz común para controlar y coordinar la interacción ( ), lo que las hace independientes entre sí con respecto a cómo se lleva a cabo la interacción. La clase implementa la interacción entre y . Colleague1Colleague2Mediatormediate()Mediator1Colleague1Colleague2

El diagrama de secuencia UML muestra las interacciones en tiempo de ejecución. En este ejemplo, un objeto media (controla y coordina) la interacción entre y objetos. Mediator1Colleague1Colleague2

Suponiendo que Colleague1desea interactuar con Colleague2(para actualizar/sincronizar su estado, por ejemplo), Colleague1llama mediate(this)al Mediator1objeto, que obtiene los datos modificados Colleague1y realiza una operación action2()on Colleague2.

A continuación, Colleague2llama mediate(this)al Mediator1objeto, que obtiene los datos modificados Colleague2y realiza una operación action1()en Colleague1.

Diagrama de clases

El patrón de diseño del comportamiento del mediador
Participantes

Mediador : define la interfaz para la comunicación entre objetos de Colega

ConcreteMediator : implementa la interfaz del mediador y coordina la comunicación entre los objetos Colega . Conoce a todos los Colegas y sus propósitos en relación con la intercomunicación.

Colega : define la interfaz para la comunicación con otros colegas a través de su mediador.

ConcreteColleague : implementa la interfaz Colleague y se comunica con otros colegas a través de su mediador

Ejemplo

DO#

El patrón mediador garantiza que los componentes estén acoplados de forma flexible , de modo que no se llamen entre sí de forma explícita, sino que lo hagan a través de llamadas a un mediador. En el siguiente ejemplo, el mediador registra todos los componentes y luego llama a sus métodos SetState.

interfaz IComponent { void SetState ( objeto estado ); } 

      


clase Componente1 : IComponent { void interno SetState ( estado del objeto ) { lanzar nueva NotImplementedException (); } }   

       
    
          
    


clase Componente2 : IComponent { void interno SetState ( estado del objeto ) { lanzar nueva NotImplementedException (); } }   

       
    
          
    


// Media las tareas comunes 
clase Mediador { interno IComponent Component1 { obtener ; establecer ; } interno IComponent Component2 { obtener ; establecer ; } 

          
          

    void interno ChangeState ( objeto estado ) { this.Component1.SetState ( estado ) ; this.Component2.SetState ( estado ) ; } }   
    
        
        
    

Una sala de chat podría utilizar el patrón de mediador, o un sistema en el que muchos "clientes" reciben un mensaje cada vez que uno de los otros clientes realiza una acción (para las salas de chat, esto sería cuando cada persona envía un mensaje). En realidad, el uso del patrón de mediador para una sala de chat solo sería práctico cuando se utiliza con comunicación remota . El uso de sockets sin formato no permitiría las devoluciones de llamadas de delegado (personas suscritas al evento MessageReceived de la clase Mediator).

delegado público void MessageReceivedEventHandler ( string mensaje , string remitente );      

clase pública Mediador { evento público MessageReceivedEventHandler MessageReceived ;  

       

    public void Send ( string mensaje , string remitente ) { if ( MessageReceived != null ) { Console . WriteLine ( "Enviando '{0}' desde {1}" , mensaje , remitente ); MessageReceived ( mensaje , remitente ); } } }     
    
           
        
              
             
        
    


clase pública Persona { privada Mediador _mediator ;  

      

    cadena pública Nombre { obtener ; establecer ; }      

    public Person ( Mediator mediator , string nombre ) { Nombre = nombre ; _mediator = mediator ; _mediator.MensajeRecibido + = new MessageReceivedEventHandler ( Recibir ) ; }    
    
          
          
           
    

    private void Recibir ( cadena mensaje , cadena remitente ) { if ( remitente != Nombre ) Console . WriteLine ( "{0} recibió '{1}' de {2}" , Nombre , mensaje , remitente ); }     
    
           
               
    

    public void Send ( string mensaje ) { _mediator.Send ( mensaje , Nombre ) ; } }   
    
         
    

Java

En el siguiente ejemplo, un Mediatorobjeto controla los valores de varios Storageobjetos, obligando al código de usuario a acceder a los valores almacenados a través del mediador. Cuando un objeto de almacenamiento desea emitir un evento indicando que su valor ha cambiado, también vuelve al objeto mediador (a través del método notifyObservers) que controla la lista de observadores (implementada mediante el patrón de observador ).

importar java.util.HashMap ; importar java.util.Optional ; importar java.util.concurrent.CopyOnWriteArrayList ; importar java.util.function.Consumer ; 
 
 
 

clase  Almacenamiento < T > { T valor ; T obtenerValor ( ) { valor de retorno ; } void setValue ( Mediador < T > mediador , String nombreDeAlmacenamiento , T valor ) { this.valor = valor ; mediador.notificarObservadores ( nombreDeAlmacenamiento ) ; } } 
     
    
      
         
    
           
          
        
    


clase  Mediador < T > { privado final HashMap < String , Storage < T >> storageMap = new HashMap <> (); privado final CopyOnWriteArrayList < Consumer < String >> observadores = new CopyOnWriteArrayList <> (); público void setValue ( String nombreAlmacenamiento , T valor ) { Almacenamiento almacenamiento = storageMap . calculateIfAbsent ( nombreAlmacenamiento , nombre -> new Almacenamiento <> ()); almacenamiento . setValue ( this , nombreAlmacenamiento , valor ); } público Opcional < T > getValue ( String nombreAlmacenamiento ) { devolver Opcional . ofNullable ( mapaAlmacenamiento . get ( nombreAlmacenamiento )). map ( Almacenamiento :: getValue ); } público void addObserver ( String nombreAlmacenamiento , Ejecutable observador ) { observadores . add ( nombreEvento -> { if ( nombreEvento . equals ( nombreAlmacenamiento )) { observador . run (); } }); } void notifyObservers ( String nombreEvento ) { observadores . forEach ( observador -> observador.aceptar ( nombreEvento ) ) ; } } 
           
          
    
          
               
          
    
    
        
         
    
    
          
          
              
                
            
        
    
    
       
          
    


clase pública MediatorDemo { public static void main ( String [] args ) { Mediador < Integer > mediador = new Mediador <> (); mediador . setValue ( "bob" , 20 ); mediador . setValue ( "alice" , 24 ); mediador . getValue ( "alice" ). ifPresent ( edad -> System . out . println ( "edad para alice: " + edad )); mediador . addObserver ( "bob" , () -> { System . out . println ( "nueva edad para bob: " + mediador . getValue ( "bob" ). orElseThrow ( RuntimeException :: new )); }); mediador . setValue ( "bob" , 21 ); } }   
         
            
         
         
            
        
           
              
        
         
    

Véase también

Referencias

  1. ^ Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides (1994). Patrones de diseño: elementos de software reutilizable orientado a objetos . Addison Wesley. pp. 273ff. ISBN 0-201-63361-2.{{cite book}}: CS1 maint: varios nombres: lista de autores ( enlace )
  2. ^ Franke, Günther. "El patrón de diseño Mediator: problema, solución y aplicabilidad". w3sDesign . Consultado el 12 de agosto de 2017 .
  3. ^ Gamma, Erich ; Helm, Richard; Johnson, Ralph ; Vlissides, John (1994). Patrones de diseño . Addison-Wesley . ISBN. 0-201-63361-2.
  4. ^ "Patrón de diseño de mediador". SourceMaking .
  5. ^ Franke, Günther. "El patrón de diseño Mediator - Estructura y colaboración". w3sDesign . Consultado el 12 de agosto de 2017 .
  • Kaiser, Bodo (21 de septiembre de 2012). "¿Es recomendable utilizar el patrón mediador?". Stack Overflow .
Obtenido de "https://es.wikipedia.org/w/index.php?title=Patrón_mediador&oldid=1234081821"