Ejemplo de programa orientado a eventos
En este ejemplo vamos a ver como programar usando eventos y observadores. Se basa en que cuando se produce un evento en un objeto del programa, este evento se propaga por toda la aplicación haciendo que los objetos que lo estuvieran observando ejecuten el código que tengan asociado a dicho evento.
Eston son los comandos que vamos a usar:
Event: es un comando que hace que se declare un evento dentro de una clase (ver
http://gambaswiki.org/wiki/lang/eventdecl?l=es&w )
EVENT Nombre ( [ Parámetro #1 [ , Parámetro #2 ... ] )
Raise: es un comando que hace que se dispare el evento. (ver
http://gambaswiki.org/wiki/lang/raise?l=es&w )
[ Cancelado = ] RAISE Evento ( [ Parámetro #1 [ , Parámetro #2 ... ] )
Observer: Los
Observadores son objetos que le permiten interceptar eventos lanzados por otros objetos, es decir que los "observan". (ver
http://gambaswiki.org/wiki/comp/gb/observer/_new?l=es&w )
hObserver = New Observer ( Object As Object [ , After As Boolean ] )
Nuestro Ejemplo:
Tenemos varios objetos "peloton" los cuales cuando son atacados (evento atacar), informan a sus superiores (que los estan observando), para que tomen las acciones adecuadas.
Este es el código de la clase
Pelotón:
' gambas class file
Event ataque(obj As Object, dato As Point)
Private posicion As New Point
Public Sub _new(xx As Integer, yy As Integer)
'posicion en el tablero
posicion.X = xx
posicion.y = yy
End
Public Sub SiendoAtacado()
Raise ataque(Me, posicion)
End
Como veis, hemos declarado un evento, "ataque", que acepta los parametros obj (un objeto) y dato (una coordenada)
Cuando se ejecuta el método "SiendoAtacado()", este hace que se dispare en el programa, el evento ataque, pasando los datos (parámetros) el propio objeto (ME) y su posicion.
Ahora vemos,la clase
ControlDeTropas:
' gambas class file
Private ObservadorControl2 As Observer
Public Sub _new()
End
Public Sub addObservador(p As Peloton)
ObservadorControl2 = New Observer(p) As "Observador"
End
Public Sub Observador_ataque(obj As Object, d As Point)
Print "Posicion atacada (evento desde objeto): ", obj, d.x, d.y
End
Comentamos el código:
Lo primero que hacemos es definir un observador: ObservadorControl2
Luego tenemos el metodo publico .addObservador, que tiene como parámetro a un objeto peloton, y que lo que hace es crear un observador al objeto pasado , agrupandolo en "Observador"
"Observador" tiene ahora un evento "_ataque", que recibe los datos del objeto y de la posición (los datos que manda Raise). Y nos presenta un texto por pantalla. Esto de escribir un mensaje, es una simplificación, no normal seria que hiciera algo: mandar ayuda (otro peloton) a esa posición, etc
La clase ServiciosSanitarios:
' gambas class file
Private ObservadorControl As Observer
Public Sub _new()
End
Public Sub addObservador(p As Peloton)
ObservadorControl = New Observer(p) As "Observador"
End
Public Sub observador_ataque(obj As Object, d As Point)
Print "Posicion que tengo que enviar ayuda (evento desde objeto): ", obj, d.x, d.y
End
Esta clase es muy similar a la anterior, lo que cambia es la acción que realizará cuando se produzca el evento _Ataque(), ya que nos muestra distitno mensaje
El principal
Fmain
:
' gambas class file
Public cTropas As ControlTropas
Public ServSani As ServiciosSanitarios
Public ptmp As Peloton
Public listaPelotones As New Peloton[]
Public Sub _new()
End
Public Sub Form_Open()
cTropas = New ControlTropas
ServSani = New ServiciosSanitarios
ptmp = New Peloton(10, 243)
listaPelotones.add(ptmp)
ptmp = New Peloton(130, 3)
listaPelotones.add(ptmp)
ptmp = New Peloton(-2, -53)
listaPelotones.add(ptmp)
For Each ptmp In listaPelotones
cTropas.addObservador(ptmp)
ServSani.addObservador(ptmp)
Next
End
Public Sub Button1_Click()
Dim p As Peloton
If RadioButton1.value = True Then p = listaPelotones[0]
If RadioButton2.value = True Then p = listaPelotones[1]
If RadioButton3.value = True Then p = listaPelotones[2]
p.SiendoAtacado()
End
En el programa pincipal, cuando se abre el formulario (_open() ) se crea una lista de objetos pelotones. y estos se van añadiendo a los objetos cTropas y ServSani, para que los observen.
Si se elige a un peloton dependiendo del radiobutton seleccionado. elegido y se pulsa el boton del formulario (button1_click) , , se llama al método ".siendoAtacado" del peloton seleccionado.
De una manera "trasparente" .siendoAtacado, hace que se dispare el evento Ataque, y que los objetos que observan al peloton elegido, respondan y manden los mensajes.
En el siguiente video podemos ver como se ejecuta el programa y lo que se va obteniendo.
¿que utilidad tiene todo esto? Imaginaos que creamos otra clase "X" que tambien va a observar y hacer algo cuando un peloton sea atacado....solo con añadir el código de la nueva clase, y modificando el bucle For Each, para que observen los objetos pelotones por el objeto "X", podemos ampliar el código, sin tocar el resto del programa:
For Each ptmp In listaPelotones
cTropas.addObservador(ptmp)
ServSani.addObservador(ptmp)
'.....aqui se pueden añadir los nuevos objetos que observen a ptmp
Next
'Codigo fuente de ejemplo:
https://drive.google.com/file/d/0B02Ro2CNt-OOSjUtc2RGRG1OS00/edit?usp=sharing
https://drive.google.com/file/d/0B02Ro2CNt-OOQUw0UnhZdEV2c3c/edit?usp=sharing
El 2º enlace es un ejemplo ampliado, añadiendo un nuevo observdor al formulario
Nota:
Todo lo anteriormente dicho, se trata de la forma que tiene gambas3 de aplicar el patron observador.
Como vereis es más simple ya que nos proporciona todas las herramientas para aplicarlo.
Fuente:
http://gambaswiki.org/wiki/doc/object-model?l=es
http://www.gambas-es.org/viewtopic.php?f=1&t=3960&highlight=eventos