¡Caminando hacia el éxito!

Aprende en Comunidad

Avalados por :

Optimizando consultas a la tabla ZPARAMETERS en ABAP OO: Interfaz y clase global implementada

  • Creado 01/03/2024
  • Modificado 01/03/2024
  • 3 Vistas
0
Cargando...

Hola a todos,

Como muchos de ustedes saben, todavía no me llevo muy bien con ABAP OO, así que lucho incluso con las tareas más simples porque nunca estoy seguro de si lo que estoy haciendo es la forma correcta y/o mejor de hacerlo (incluso después de revisar cosas en Código Limpio o varios libros). Por eso, aquí está lo que me gustaría hacer y lo que ya codifiqué para ello, seguido de algunas preguntas de "verificación de cordura".

Tenemos una tabla de parámetros genérica - llamémosla ZPARAMETERS - que se utiliza para muchas cosas, como decidir si se debe ejecutar una rutina si hay una entrada para valores específicos o para proporcionar un valor específico para un campo. No es bonita, pero no va a desaparecer pronto. Hay varias formas en las que se consulta la tabla y al menos intentaría hacer eso un poco más eficiente. Es por eso que me adentré un poco en los métodos funcionales.

Creé una interfaz:

interface zif_table_zparameters_dao
  public .

  METHODS:
    entry_exists
      IMPORTING
        i_zparameters TYPE zparameters
      RETURNING
        VALUE(entry_found) TYPE abap_bool,

    return_value2
      IMPORTING
        i_zparameters TYPE zparameters
      RETURNING
        VALUE(result) TYPE zparameters-value2.

endinterface.

Clase global que implementa la interfaz:

CLASS zcl_table_zparameters DEFINITION
  PUBLIC CREATE PUBLIC.

  PUBLIC SECTION.
    INTERFACES zif_table_zparameters_dao.
  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.

CLASS zcl_table_zparameters IMPLEMENTATION.

  METHOD zif_table_zparameters_dao~entry_exists.
    CLEAR entry_found.

    SELECT SINGLE @abap_true
         FROM zparameters
         INTO @entry_found
        WHERE modul        EQ @i_zparameters-modul
          AND z_program    EQ @i_zparameters-z_program
          AND field        EQ @i_zparameters-field
          AND value1       EQ @i_zparameters-value1
          AND value2       EQ @i_zparameters-value2.

  ENDMETHOD.

  METHOD zif_table_zparameters_dao~return_value2.
    CLEAR result.

    SELECT SINGLE    
            
Pedro Pascal
Se unió el 07/03/2018
Pinterest
Telegram
Linkedin
Whatsapp

4 Respuestas

0
Cargando...

mateuszadamus

Gracias, Mateusz!

Agregar los parámetros EXPORTING parece ser una solución sencilla para mi segundo método. Sin embargo, ¿no estaría esto "en contra" de este principio de código limpio que indica usar RETURNING o EXPORTING o CHANGING, pero no una combinación de ellos ? ¿O sería una excepción válida a la regla para no permitir que lo perfecto sea enemigo de lo bueno?

En cuanto al almacenamiento en búfer: esto realmente no es una preocupación en este momento, ya que la tabla de parámetros se lee literalmente "al final" a lo largo, por ejemplo, del extenso código de una mejora con diferentes cláusulas WHERE que incluyen los valores de MODUL y Z_PROGRAM, ¡así que no tiene mucho sentido intentar determinar qué podría ser incluso estos "datos básicos"!

Saludos

Bärbel

Respondido el 15/04/2024
LUCIANO RIOJA GHIOTTO
Se unió el 13/07/2019
0
Cargando...

Hola 8b889d0e8e6f4ed39f6c58e35664518f

Aquí están mis dos centavos sobre el tema. Claramente, otros desarrolladores pueden tener una opinión diferente.

1. Interfaz - Yo, por mi parte, no la crearía. Claro, existe una Programación basada en interfaz , pero realmente no veo sentido en crear algo que no aporte un valor real. Si solo tienes una implementación concreta y la usas solo en tus propios sistemas, entonces, en mi opinión, la interfaz no aporta nada.
Si alguna vez surge la necesidad de tener otra implementación de la lógica que lee valores, entonces, claro, la interfaz podría ser una opción, pero puedes refactorizar el código en función de tus necesidades en ese momento.

2. Nomenclatura - ¿La tabla ZPARAMETERS es la única de ese tipo? Si es así, probablemente nombraría la interfaz/clase de manera más genérica, tal vez ZIF/ZCL_CONFIG o ZIF/ZCL_PARAMETERS.
Luego, los métodos podrían ser ENTRY_EXISTS (o simplemente EXISTS) y RETURN_VALUE (o VALUE). En el último caso, supongo que siempre quieres devolver el valor del campo VALUE2, ya que el VALUE1 es un valor utilizado para la comparación. ¿Correcto?
En cualquier caso, intentaría mantener la nomenclatura clara y corta (pero aún significativa). La razón es que esta clase y estos métodos se usarán mucho. Es bueno que sea fácil de escribir y recordar, para que no se tenga que buscarlos cada vez.

3. Cómo informar - en mi solución de este tipo, hice un parámetro EXPORTING que devolvía TRUE/FALSE en función de la existencia del registro. De esta manera, el desarrollador puede (pero no tiene que) solicitar esta información.

return_value2
  IMPORTING
    i_zparameters TYPE zparameters
  EXPORTING
    ev_found TYPE flag
  RETURNING
    VALUE(result) TYPE zparameters-value2.

METHOD zif_table_zparameters_dao~return_value2.
  CLEAR result.

  SELECT SINGLE value2
       FROM zparameters
       INTO @result
      WHERE modul        EQ @i_zparameters-modul
        AND z_program    EQ @i_zparameters-z_program
        AND field        EQ @i_zparameters-field
        AND value1       EQ @i_zparameters-value1.
  
  ev_found = xsdbool( sy-subrc = 0 ).
ENDMETHOD.

Ejemplo de uso (algo así como un seudocódigo):

DATA:
  lv_found TYPE flag,
  lv_value TYPE string.

lv_value = lcl_config=>value( ).
lv_value = lcl_config=>value( IMPORTING ev_found =
        
Respondido el 15/04/2024
LUCIANO RIOJA GHIOTTO
Se unió el 13/07/2019
0
Cargando...

No deberías abstraer si no hay razón para hacerlo. Las recomendaciones existen solo por buenas razones y no creo que aplique a tu caso.

Si tienes una buena razón para usarlos, cambiaría el nombre de los métodos a (supongo que todos saben qué significa DB):

  • db_entry_exists
  • db_select

En cuanto a devolver la información encontrada/no encontrada, depende de ti. El uso del valor inicial no me molesta, acompañado de un comentario. El uso de una excepción también podría ser válido.

Respondido el 15/04/2024
LUCIANO RIOJA GHIOTTO
Se unió el 13/07/2019
0
Cargando...

Aquí están mis comentarios convertidos en una respuesta.

-

1) ¿Es realmente necesaria la interfaz para lo que estoy haciendo aquí, especialmente dado que es muy poco probable que haya pruebas unitarias para la lógica? La razón principal por la que la creé es que parece ser la forma recomendada para clases/métodos públicos.

No abstraería si no hay razón para hacerlo. Las recomendaciones existen solo por buenas razones y no creo que se aplique a tu caso.

-

2) ¿Tiene sentido el nombre de las diferentes entidades?

Si tienes una buena razón para usar una interfaz, renombraría DAO a DB (supongo que DB es más conocido que DAO), y la instancia también debería mantener DB: db_zparameters. Nota: No soy fan de la notación húngara prefijada.

-

3) ¿Cómo hacer que el proceso llamador sepa que es posible que no se encuentre ninguna entrada en RETURN_VALUE2 en un método funcional que solo devuelve exactamente un valor, en este caso el contenido de VALUE2? En este momento, lo resuelvo consultando si VALUE2 está lleno, pero no estoy seguro de si esa es la mejor/manera correcta de hacerlo.

Para devolver la información encontrada/no encontrada, depende de ti.

a) El uso del valor inicial no me molesta, acompañado de un comentario.

b) El uso de una excepción también podría ser válido.

c) El uso de una referencia, para devolver algún dato o NULL significando no encontrado en tu caso.

Definición:

METHODS
    return_value2
      IMPORTING
        i_zparameters TYPE zparameters
      RETURNING
        VALUE(result) TYPE REF TO zparameters-value2. " <==== REF TO

Implementación:

  METHOD zif_table_zparameters_dao~return_value2.
    SELECT SINGLE value2
         FROM zparameters
         INTO @DATA(value2)          " <==== variable temporal
        WHERE modul        EQ @i_zparameters-modul
          AND z_program    EQ @i_zparameters-z_program
          AND field        EQ @i_zparameters-field
          AND value1       EQ @i_zparameters-value1.
    IF sy-subrc = 0.
      result = NEW #( value2 ).      " <==== necesario para evitar excepción FREED
    ENDIF.
  ENDMETHOD.

Uso:

DATA(value2) = int_zparameters->return_value2( VALUE
        
Respondido el 15/04/2024
LUCIANO RIOJA GHIOTTO
Se unió el 13/07/2019

contacto@primeinstitute.com

(+51) 1641 9379
(+57) 1489 6964

© 2024 Copyright. Todos los derechos reservados.

Desarrollado por Prime Institute

¡Hola! Soy Diana, asesora académica de Prime Institute, indícame en que curso estas interesado, saludos!
Hola ¿Puedo ayudarte?