Eventos en ABAP Object-Oriented permiten comunicacion desacoplada entre objetos. Una clase puede disparar un evento, y otras clases pueden reaccionar a el sin dependencia directa.
Sintaxis
Declaracion de evento
EVENTS <nombre_evento> [ EXPORTING VALUE(<parametro>) TYPE <tipo> ... ].Disparar evento
RAISE EVENT <nombre_evento> [ EXPORTING <parametro> = <valor> ... ].Definir Handler
METHODS <nombre_handler> FOR EVENT <nombre_evento> OF <clase> [ IMPORTING <parametro> ... ].Registrar Handler
SET HANDLER <handler> FOR <objeto>.SET HANDLER <handler> FOR ALL INSTANCES.Ejemplos
1. Evento basico
CLASS zcl_button DEFINITION. PUBLIC SECTION. " Declaracion de evento EVENTS clicked.
METHODS press.ENDCLASS.
CLASS zcl_button IMPLEMENTATION. METHOD press. " Disparar el evento RAISE EVENT clicked. ENDMETHOD.ENDCLASS.
" Clase HandlerCLASS zcl_handler DEFINITION. PUBLIC SECTION. METHODS on_button_click FOR EVENT clicked OF zcl_button.ENDCLASS.
CLASS zcl_handler IMPLEMENTATION. METHOD on_button_click. WRITE: / 'Boton fue clickeado!'. ENDMETHOD.ENDCLASS.
" UsoDATA: lo_button TYPE REF TO zcl_button, lo_handler TYPE REF TO zcl_handler.
CREATE OBJECT: lo_button, lo_handler.
" Registrar handlerSET HANDLER lo_handler->on_button_click FOR lo_button.
" Disparar eventolo_button->press( ). " Salida: "Boton fue clickeado!"2. Evento con parametros
CLASS zcl_order DEFINITION. PUBLIC SECTION. EVENTS order_created EXPORTING VALUE(ev_order_id) TYPE i VALUE(ev_customer_id) TYPE string.
METHODS create_order IMPORTING iv_customer_id TYPE string RETURNING VALUE(rv_order_id) TYPE i.
PRIVATE SECTION. DATA: mv_next_id TYPE i VALUE 1000.ENDCLASS.
CLASS zcl_order IMPLEMENTATION. METHOD create_order. " Logica de negocio mv_next_id = mv_next_id + 1. rv_order_id = mv_next_id.
" Disparar evento con datos RAISE EVENT order_created EXPORTING ev_order_id = rv_order_id ev_customer_id = iv_customer_id. ENDMETHOD.ENDCLASS.
" HandlerCLASS zcl_order_logger DEFINITION. PUBLIC SECTION. METHODS on_order_created FOR EVENT order_created OF zcl_order IMPORTING ev_order_id ev_customer_id.ENDCLASS.
CLASS zcl_order_logger IMPLEMENTATION. METHOD on_order_created. WRITE: / 'Nuevo pedido:', ev_order_id, 'para cliente:', ev_customer_id. ENDMETHOD.ENDCLASS.3. Multiples Handlers
" Multiples clases pueden reaccionar al mismo eventoCLASS zcl_notification_service DEFINITION. PUBLIC SECTION. METHODS on_order_created FOR EVENT order_created OF zcl_order IMPORTING ev_order_id ev_customer_id.ENDCLASS.
CLASS zcl_inventory_service DEFINITION. PUBLIC SECTION. METHODS on_order_created FOR EVENT order_created OF zcl_order IMPORTING ev_order_id.ENDCLASS.
" UsoDATA: lo_order TYPE REF TO zcl_order, lo_logger TYPE REF TO zcl_order_logger, lo_notif TYPE REF TO zcl_notification_service, lo_inventory TYPE REF TO zcl_inventory_service.
CREATE OBJECT: lo_order, lo_logger, lo_notif, lo_inventory.
" Registrar multiples handlersSET HANDLER lo_logger->on_order_created FOR lo_order.SET HANDLER lo_notif->on_order_created FOR lo_order.SET HANDLER lo_inventory->on_order_created FOR lo_order.
" Un evento -> tres handlers ejecutadoslo_order->create_order( 'CUST001' ).4. Eventos estaticos (CLASS-EVENTS)
CLASS zcl_system_monitor DEFINITION. PUBLIC SECTION. " Evento estatico - no necesita instancia CLASS-EVENTS system_error EXPORTING VALUE(ev_message) TYPE string.
CLASS-METHODS report_error IMPORTING iv_message TYPE string.ENDCLASS.
CLASS zcl_system_monitor IMPLEMENTATION. METHOD report_error. RAISE EVENT system_error EXPORTING ev_message = iv_message. ENDMETHOD.ENDCLASS.
" Handler para evento estaticoCLASS zcl_error_logger DEFINITION. PUBLIC SECTION. METHODS on_system_error FOR EVENT system_error OF zcl_system_monitor IMPORTING ev_message.ENDCLASS.
" Registro para eventos estaticosDATA: lo_logger TYPE REF TO zcl_error_logger.CREATE OBJECT lo_logger.
" Sin FOR <objeto> - porque es estaticoSET HANDLER lo_logger->on_system_error.
" Dispararzcl_system_monitor=>report_error( 'Error critico!' ).5. SET HANDLER FOR ALL INSTANCES
" Un handler para TODAS las instancias de una claseDATA: lo_handler TYPE REF TO zcl_order_logger.
CREATE OBJECT lo_handler.
" Registrar para todas las instancias (existentes y futuras)SET HANDLER lo_handler->on_order_created FOR ALL INSTANCES.
" Ahora cualquier instancia de zcl_order dispara el handlerDATA: lo_order1 TYPE REF TO zcl_order, lo_order2 TYPE REF TO zcl_order.
CREATE OBJECT: lo_order1, lo_order2.
lo_order1->create_order( 'CUST001' ). " Handler se ejecutalo_order2->create_order( 'CUST002' ). " Handler se ejecuta6. Desregistrar Handler
" RegistrarSET HANDLER lo_handler->on_order_created FOR lo_order.
" Desregistrar (con ACTIVATION abap_false)SET HANDLER lo_handler->on_order_created FOR lo_order ACTIVATION abap_false.
" Ahora el handler ya no se ejecutalo_order->create_order( 'CUST003' ). " Sin reaccion7. Patron Observer con Eventos
" Sujeto ObservableCLASS zcl_stock DEFINITION. PUBLIC SECTION. EVENTS price_changed EXPORTING VALUE(ev_symbol) TYPE string VALUE(ev_price) TYPE p.
METHODS set_price IMPORTING iv_symbol TYPE string iv_price TYPE p.ENDCLASS.
CLASS zcl_stock IMPLEMENTATION. METHOD set_price. " Actualizar precio y notificar RAISE EVENT price_changed EXPORTING ev_symbol = iv_symbol ev_price = iv_price. ENDMETHOD.ENDCLASS.
" Observador 1: PantallaCLASS zcl_stock_display DEFINITION. PUBLIC SECTION. METHODS on_price_change FOR EVENT price_changed OF zcl_stock IMPORTING ev_symbol ev_price.ENDCLASS.
CLASS zcl_stock_display IMPLEMENTATION. METHOD on_price_change. WRITE: / 'Pantalla:', ev_symbol, ev_price. ENDMETHOD.ENDCLASS.
" Observador 2: AlertaCLASS zcl_stock_alert DEFINITION. PUBLIC SECTION. METHODS on_price_change FOR EVENT price_changed OF zcl_stock IMPORTING ev_symbol ev_price.
PRIVATE SECTION. DATA: mv_threshold TYPE p VALUE 100.ENDCLASS.
CLASS zcl_stock_alert IMPLEMENTATION. METHOD on_price_change. IF ev_price > mv_threshold. WRITE: / 'ALERTA:', ev_symbol, 'supera umbral!'. ENDIF. ENDMETHOD.ENDCLASS.8. Eventos en interfaces
INTERFACE zif_document. EVENTS document_saved EXPORTING VALUE(ev_doc_id) TYPE string.
METHODS save.ENDINTERFACE.
CLASS zcl_invoice DEFINITION. PUBLIC SECTION. INTERFACES zif_document. ALIASES document_saved FOR zif_document~document_saved.ENDCLASS.
CLASS zcl_invoice IMPLEMENTATION. METHOD zif_document~save. " Guardar factura DATA(lv_doc_id) = 'INV-001'.
" Disparar evento de interfaz RAISE EVENT document_saved EXPORTING ev_doc_id = lv_doc_id. ENDMETHOD.ENDCLASS.
" Handler para interfazCLASS zcl_doc_handler DEFINITION. PUBLIC SECTION. METHODS on_doc_saved FOR EVENT document_saved OF zif_document IMPORTING ev_doc_id.ENDCLASS.9. Eventos con objeto sender
" Parametro SENDER implicitoCLASS zcl_handler DEFINITION. PUBLIC SECTION. METHODS on_clicked FOR EVENT clicked OF zcl_button IMPORTING sender. " Objeto que disparo el eventoENDCLASS.
CLASS zcl_handler IMPLEMENTATION. METHOD on_clicked. " Acceder al objeto disparador DATA(lo_button) = sender.
" Llamar metodos del sender si es necesario " lo_button->get_id( ). ENDMETHOD.ENDCLASS.10. Ejemplo practico: Sistema de pedidos
" Sistema de eventos completoCLASS zcl_order_system DEFINITION. PUBLIC SECTION. EVENTS: order_placed EXPORTING VALUE(ev_order) TYPE REF TO zcl_order_data, order_shipped EXPORTING VALUE(ev_order_id) TYPE string, order_cancelled EXPORTING VALUE(ev_order_id) TYPE string VALUE(ev_reason) TYPE string.
METHODS: place_order IMPORTING is_data TYPE zst_order_input RETURNING VALUE(rv_order_id) TYPE string, ship_order IMPORTING iv_order_id TYPE string, cancel_order IMPORTING iv_order_id TYPE string iv_reason TYPE string.ENDCLASS.
" Servicio de EmailCLASS zcl_email_service DEFINITION. PUBLIC SECTION. METHODS: constructor, on_order_placed FOR EVENT order_placed OF zcl_order_system IMPORTING ev_order, on_order_shipped FOR EVENT order_shipped OF zcl_order_system IMPORTING ev_order_id, on_order_cancelled FOR EVENT order_cancelled OF zcl_order_system IMPORTING ev_order_id ev_reason.ENDCLASS.
CLASS zcl_email_service IMPLEMENTATION. METHOD constructor. " Auto-registro en sistema de ordenes DATA(lo_order_system) = zcl_order_system=>get_instance( ).
SET HANDLER: on_order_placed FOR lo_order_system, on_order_shipped FOR lo_order_system, on_order_cancelled FOR lo_order_system. ENDMETHOD.
METHOD on_order_placed. " Enviar email de confirmacion WRITE: / 'Email: Pedido confirmado'. ENDMETHOD.
METHOD on_order_shipped. " Enviar email de envio WRITE: / 'Email: Pedido enviado', ev_order_id. ENDMETHOD.
METHOD on_order_cancelled. " Enviar email de cancelacion WRITE: / 'Email: Pedido cancelado', ev_order_id, ev_reason. ENDMETHOD.ENDCLASS.Resumen
| Aspecto | Sintaxis |
|---|---|
| Declarar evento | EVENTS <nombre> EXPORTING ... |
| Evento estatico | CLASS-EVENTS <nombre> ... |
| Disparar | RAISE EVENT <nombre> |
| Definir handler | METHODS ... FOR EVENT ... OF ... |
| Registrar | SET HANDLER <handler> FOR <objeto> |
| Todas instancias | SET HANDLER ... FOR ALL INSTANCES |
| Desregistrar | SET HANDLER ... ACTIVATION abap_false |
Notas importantes / Mejores practicas
- Los eventos permiten desacoplamiento entre clases.
- Usar
CLASS-EVENTSpara eventos que no necesitan instancia. FOR ALL INSTANCESregistra para todas las instancias (existentes y futuras).- El parametro
senderda acceso al objeto disparador. - Los handlers se ejecutan sincronicamente en el mismo hilo.
- Desregistrar handlers cuando el objeto ya no se necesita (evitar memory leaks).
- Los eventos son ideales para el Patron Observer.
- En ABAP Cloud/RAP: usar RAP Business Events en lugar de eventos de clase.