¡Caminando hacia el éxito!

Aprende en Comunidad

Avalados por :

Otimizando consultas à tabela ZPARAMETERS em ABAP OO: Interface e classe global implementada

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

Olá a todos,

Como muitos de vocês sabem, ainda não me dou muito bem com o ABAP OO, então eu luto até mesmo com as tarefas mais simples porque nunca tenho certeza se estou fazendo da forma correta e/ou melhor (mesmo depois de revisar coisas em Código Limpo ou vários livros). Por isso, aqui está o que eu gostaria de fazer e o que já codifiquei para isso, seguido de algumas perguntas de "verificação de sanidade".

Temos uma tabela de parâmetros genérica - vamos chamá-la de ZPARAMETERS - que é utilizada para muitas coisas, como decidir se uma rotina deve ser executada se houver uma entrada para valores específicos ou para fornecer um valor específico para um campo. Não é bonita, mas não vai desaparecer em breve. Há várias maneiras de consultar a tabela e pelo menos tentaria tornar isso um pouco mais eficiente. É por isso que me aprofundei um pouco nos métodos funcionais.

Criei uma interface:

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.

Classe global que implementa a interface:

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

Obrigado, Mateusz!

Adicionar os parâmetros EXPORTING parece ser uma solução simples para o meu segundo método. No entanto, isso não estaria "indo contra" o princípio de código limpo que indica usar RETURNING ou EXPORTING ou CHANGING, mas não uma combinação deles ? Ou seria uma exceção válida à regra para não permitir que o perfeito seja inimigo do bom?

Quanto ao armazenamento em buffer: isso realmente não é uma preocupação no momento, pois a tabela de parâmetros é lida literalmente "no final" ao longo, por exemplo, do extenso código de uma melhoria com diferentes cláusulas WHERE que incluem os valores de MODUL e Z_PROGRAM, então não faz muito sentido tentar determinar o que poderia ser até mesmo esses "dados básicos"!

Saudações

Bärbel

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

Olá 8b889d0e8e6f4ed39f6c58e35664518f

Aqui estão meus dois centavos sobre o assunto. Claramente, outros desenvolvedores podem ter uma opinião diferente.

1. Interface - Eu, por minha parte, não a criaria. Claro, existe uma Programação baseada em interface , mas realmente não vejo sentido em criar algo que não agregue um valor real. Se você tem apenas uma implementação concreta e a utiliza apenas em seus próprios sistemas, então, em minha opinião, a interface não acrescenta nada.
Se alguma vez surgir a necessidade de ter outra implementação da lógica que lê valores, então, claro, a interface poderia ser uma opção, mas você pode refatorar o código conforme suas necessidades naquele momento.

2. Nomenclatura - A tabela ZPARAMETERS é a única desse tipo? Se for o caso, provavelmente nomearia a interface/classe de forma mais genérica, talvez ZIF/ZCL_CONFIG ou ZIF/ZCL_PARAMETERS.
Em seguida, os métodos poderiam ser ENTRY_EXISTS (ou simplesmente EXISTS) e RETURN_VALUE (ou VALUE). No último caso, presumo que sempre deseja retornar o valor do campo VALUE2, já que o VALUE1 é um valor utilizado para comparação. Correto?
De qualquer forma, tentaria manter a nomenclatura clara e curta (mas ainda significativa). A razão é que essa classe e esses métodos serão muito usados. É bom que seja fácil de escrever e lembrar, para que não precise procurá-los sempre.

3. Como informar - em minha solução desse tipo, fiz um parâmetro EXPORTING que retorna TRUE/FALSE dependendo da existência do registro. Dessa forma, o desenvolvedor pode (mas não precisa) solicitar essa informação.

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.

Exemplo de uso (algo como um pseudocó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...

Não deve abstrair se não houver motivo para tal. As recomendações existem apenas por boas razões e não acredito que se apliquem ao seu caso.

Se tiver uma boa razão para usá-las, mudaria o nome dos métodos para (presumo que todos sabem o que significa DB):

  • db_entry_exists
  • db_select

Quanto a retornar a informação encontrada/não encontrada, isso depende de você. O uso do valor inicial não me incomoda, desde que acompanhado de um comentário. O uso de uma exceção também poderia ser válido.

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

Aqui estão meus comentários convertidos em uma resposta.

-

1) É realmente necessária a interface para o que estou fazendo aqui, especialmente dado que é muito improvável que haja testes unitários para a lógica? A razão principal pela qual a criei é que parece ser a forma recomendada para classes/métodos públicos.

Não abstrairia se não houver motivo para isso. As recomendações existem apenas por boas razões e não acredito que se aplique ao seu caso.

-

2) Faz sentido o nome das diferentes entidades?

Se você tiver uma boa razão para usar uma interface, renomearia DAO para DB (suponho que DB seja mais conhecido que DAO), e a instância também deveria manter DB: db_zparameters. Nota: Não sou fã da notação húngara prefixada.

-

3) Como fazer com que o processo chamador saiba que é possível que não seja encontrada nenhuma entrada em RETURN_VALUE2 em um método funcional que apenas retorna exatamente um valor, neste caso o conteúdo de VALUE2? No momento, resolvo isso verificando se VALUE2 está preenchido, mas não tenho certeza se essa é a melhor/maneira correta de fazer isso.

Para retornar a informação encontrada/não encontrada, depende de você.

a) O uso do valor inicial não me incomoda, acompanhado de um comentário.

b) O uso de uma exceção também poderia ser válido.

c) O uso de uma referência, para retornar algum dado ou NULL significando não encontrado em seu caso.

Definição:

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

Implementação:

  METHOD zif_table_zparameters_dao~return_value2.
    SELECT SINGLE value2
         FROM zparameters
         INTO @DATA(value2)          " <==== variável temporária
        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 ).      " <==== necessário para evitar exceção 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?