El patrón de diseño de objeto activo desacopla la ejecución del método de la invocación del método para los objetos que residen en su propio hilo de control. [1] El objetivo es introducir la simultaneidad mediante la invocación de métodos asincrónicos y un planificador para gestionar las solicitudes. [2]
El patrón consta de seis elementos: [3]
- Un proxy , que proporciona una interfaz hacia los clientes con métodos de acceso público.
- Una interfaz que define la solicitud de método en un objeto activo.
- Una lista de solicitudes pendientes de los clientes.
- Un planificador , que decide qué solicitud ejecutar a continuación.
- La implementación del método de objeto activo.
- Una devolución de llamada o una variable para que el cliente reciba el resultado.
Ejemplo
Java
Un ejemplo de patrón de objeto activo en Java . [4]
En primer lugar, podemos ver una clase estándar que proporciona dos métodos que establecen un doble como un valor determinado. Esta clase NO se ajusta al patrón de objeto activo.
class MyClass { privado doble val = 0.0 ; void doSomething () { val = 1,0 ; } void doSomethingElse () { val = 2.0 ; } }
La clase es peligrosa en un escenario de subprocesos múltiples porque ambos métodos se pueden llamar simultáneamente, por lo que el valor de val (que no es atómico, se actualiza en varios pasos) podría no estar definido, una condición de carrera clásica. Por supuesto, puede usar la sincronización para resolver este problema, que en este caso trivial es fácil. Pero una vez que la clase se vuelve realmente compleja, la sincronización puede volverse muy difícil. [5]
Para reescribir esta clase como un objeto activo, puede hacer lo siguiente:
class MyActiveObject { privado doble val = 0.0 ; Private BlockingQueue < Ejecutable > dispatchQueue = new LinkedBlockingQueue < Ejecutable > (); public MyActiveObject () { new Thread ( new Runnable () { @Override public void run () { while ( true ) { try { dispatchQueue . tomar (). ejecutar (); } catch ( InterruptedException e ) { // bien, simplemente termina el despachador } } } } ). inicio (); } void doSomething () lanza InterruptedException { dispatchQueue . put ( new Runnable () { @Override public void run () { val = 1.0 ; } } ); } void doSomethingElse () lanza InterruptedException { dispatchQueue . put ( new Runnable () { @Override public void run () { val = 2.0 ; } } ); } }
Java 8 (alternativa)
Otro ejemplo de patrón de objeto activo en Java implementado en Java 8 proporciona una solución más corta.
public class MyClass { private double val ; // contenedor para tareas // decide qué solicitud ejecutar a continuación // asyncMode = true significa que nuestro hilo de trabajo procesa su cola de tareas local en el orden FIFO // solo un hilo puede modificar el estado interno privado final ForkJoinPool fj = new ForkJoinPool ( 1 , ForkJoinPool . DefaultForkJoinWorkerThreadFactory , nulo , verdadero ); // implementación del método de objeto activo public void doSomething () lanza InterruptedException { fj . ejecutar (() -> { val = 1.0 ; }); } // implementación del método de objeto activo public void doSomethingElse () lanza InterruptedException { fj . ejecutar (() -> { val = 2.0 ; }); } }
Ver también
Referencias
- ^ Douglas C. Schmidt ; Michael Stal; Hans Rohnert; Frank Buschmann (2000). Arquitectura de software orientada a patrones, volumen 2: patrones para objetos simultáneos y en red . John Wiley e hijos. ISBN 0-471-60695-2.
- ^ Bajo, L., Clements, P., Kazman, R. Arquitectura de software en la práctica . Addison Wesley, 2003
- ^ Lavanda, R. Greg; Schmidt, Douglas C. "Objeto activo" (PDF) . Archivado desde el original (PDF) el 22 de julio de 2012 . Consultado el 2 de febrero de 2007 .
- ^ Holub, Allen. "Java Active Objects - Una propuesta" . Archivado desde el original el 22 de junio de 2013 . Consultado el 16 de junio de 2014 .
- ^ Holub, Allen. "Java Active Objects - Una propuesta" . Archivado desde el original el 22 de junio de 2013 . Consultado el 16 de junio de 2014 .