Desde que o ABAP Objects foi lançado há vários anos atrás a polemica se instalou na comunidade de desenvolvedores ABAP quanto a utilização do novo paradigma de programação orientado a objeto junto com o antigo paradigma da programação procedural, possibilitando então escrever códigos de múltiplos paradigmas. Varias instruções do antigo paradigma foram marcadas como obsoleta pela SAP que ainda as mantem a nível de compatibilidade com programas mais antigos.
A vinda do novo paradigma causa até hoje enorme e incontáveis batalhas e discussões entre os novos e novos, os novos e velhos e os velhos e velhos desenvolvedores ABAP a fim de chegar a uma argumentação final sobre o assunto que parece não ter solução. Enquanto alguns puristas declaram firmemente que você não pode utilizar instruções do antigo paradigma com instruções orientadas objetos, outros mais liberais não veem nenhum problema nisto já que deste modo a programação se torna muito mais fácil e rápida e ainda contam com o respaldo dos exemplos oficiais disponibilizados pela SAP contidos no NetWeaver que educam os novos desenvolvedores a utilizar os dois paradigmas (transação ABAPDOCU).
Com toda está polemica, é claro que não queremos nos meter no meio deste assunto e nossa opinião não poderia ser mais obvia. Ficar em cima do muro! Pode parecer uma posição meio frouxa, mas garanto que este não é o caso. Se por um lado a programação orientada a objeto é considerada superior a programação procedural, então um código orientado a objeto bem escrito deveria ter uma melhor qualidade, e tem! Mas os exemplos e vários códigos fornecidos, escritos e assinados pela própria SAP misturam os paradigmas, então eu também posso fazer isto, também concordamos!
Já que concordamos com ambas as partes temos que achar o verdadeiro ocasionador de tal desavenças, isto não é tão difícil assim, uma simples busca na documentação oficial e logo encontramos uma da muitas explicações plausíveis para o acontecimento (existem vários pontos que divergem a programação procedural da orientada a objeto e um deles é o próprio Open SQL e os Data Objects, mas isto é assunto para outra ocasião). Voltando para linha do raciocínio, acontece que a SAP não terminou de implementar o framework de coleções para a linguagem de programação ABAP Objects e indica nos exemplos oficiais um workaround para simular uma LISTA no conceito de programação orientada a objeto, veja no código a implementação do método: “METHOD WRITE_LIST”.
Isto acontece exatamente no tópico de métodos que são um dos mais importantes elementos que compõem uma classe que obviamente resultará em um objeto. E mais! Também afirma que o exemplo contem instruções obsoletas e não garante a compatibilidade com futuras versões:
“The ABAP statements used for list processing are not yet fully available in ABAP Objects. However, to produce a simple test output, you can use the following statements: WRITE [AT] /<offset>(<length>) <f>
ULINE
SKIP
NEW-LINE
Note: The behavior of formatting and interactive list functions in their current state are not guaranteed. Incompatible changes could occur in a future release.”
Classes: Métodos ABAP
O que é uma lista em programação orientada a objetos?
Em programação orientada a objeto a classe de Lista faz parte do framework de coleções e é equivalente genérico da classe ArrayList . Implementa a interface genérica de listas usando uma matriz cujo tamanho é gerado dinamicamente conforme necessário. Em ABAP podemos dizer que uma lista é semelhante a uma tabela interna que pode conter varias colunas ou linhas, porem é um objeto que pode conter (Container) um objeto criado pelo desenvolvedor e ser manipulado através de outro objeto chamado de iterador.
O ABAP disponibiliza algumas classes para manipular objetos utilizando as coleções porem estas classes ainda não fazem parte de um framework de coleções consistentes como encontramos em outras linguagem com o próprio STL para C++ ou JCF para Java que são as linguagens de programação no qual o ABAP OO foi baseado.
Analisando a Classe do Objeto e Utilizando Coleções
Utilizamos um Pattern básico para o objeto criado na classe do código abaixo baseado no que seria comum em qualquer linguagem orientada a objeto como Java e C++.
- A classe utiliza encapsulamento privado para os atributos que são os campos primitivos ou não que armazenam valores para o objeto.
- Estes campos privados são acessados através dos tradicionais métodos Getter e Setter que são o método Get para ler um atributo do objeto e o método Set para alimentar um atributo do objeto.
- Utilizamos um construtor padrão e um construtor Overload para a classe, em ABAP não podemos sobrecarregar os construtores através de métodos e precisamos criar está funcionalidade pela instrução OPTIONAL declarada nos parâmetros das variáveis no escopo do método construtor.
- Utilizamos a classe de coleção CL_OBJECT_COLLECTION para criar uma lista para o objeto.
- Utilizamos a classe de coleção CL_OBJECT_COLLECTION_ITERATOR para iterar o objeto de lista.
- Para continuar em cima do muro, utilizamos uma instrução FORM-PERFORM para adicionar os objetos na lista e explicamos o motivo nos comentários do código abaixo.
Você ainda pode manipular os objetos da lista, adicionado, removendo, alterando os dados para seu objeto. Mas reiteramos que as coleções ainda não estão totalmente implementadas em ABAP Objetcs o que pode tornar mais difícil este tipo de programação a não ser que você mesmo herde e estenda as classes e implemente seu próprio framework para as coleções.
Mais Questões
Seria o ABAP Objects uma linguagem incompleta? Já que as coleções são de grande importância e essenciais na orientação a objeto uma implementação incompleta justificaria o uso de instruções procedurais para a manipulação de objetos? O Open SQL deixaria o ABAP Objects com um pé no paradigma da programação declarativa já que é utilizado de forma muito similar ao SQL que é uma linguagem declarativa? Manipular dados nos objetos através do Open SQL e Data Objects (Em geral utilizam a instrução DATA) como vemos no exemplo disponibilizado pela SAP no link acima e não através de Patterns de objetos como o DAO (Data Access Objects) para Java entre outros também não quebraria o paradigma da orientação a objeto? Podemos então afirmar que ABAP é uma linguagem exclusivamente de múltiplos paradigmas? Deixaremos que vocês tirem suas próprias conclusões.
DAO Pattern: http://www.oracle.com/technetwork/java/dataaccessobject-138824.html
ABAP: Data Objects
Até o momento não há documentação oficial no site da SAP sobre as classes de coleções.
Object Handling: Manipulando Objetos
Exemplo:
Neste exemplo criamos uma classe que contem alguns recursos básicos da programação orientada a objeto como atributos privados, construtor Overload, métodos Getter e Setter e utilizamos um objeto de lista para armazenar e manipular nosso objeto.
Métodos: Overload
Coleções: Collections Iterator e Collection Map
ABAP
*&---------------------------------------------------------------------* *& Report ZABAPOBJETO *& *&---------------------------------------------------------------------* *& Desenvolvimento Aberto *& Objetos Abap - Manipulando Objetos *& Classe - Objeto - Lista - Iterador *&---------------------------------------------------------------------* REPORT ZABAPOBJETO. * Cria classe Participante class ZPARTICIPANTE definition. public section. * Declara construtor com efeito Overload methods CONSTRUCTOR IMPORTING pid TYPE i OPTIONAL pnome TYPE string OPTIONAL pidade TYPE i OPTIONAL. * Declara métodos Getter e Setter methods SETID importing !PID type i . methods GETID returning value(RESULTADO) type i . methods SETNOME importing !PNOME type STRING . methods GETNOME returning value(RESULTADO) type STRING . methods SETIDADE importing !PIDADE type I . methods GETIDADE returning value(RESULTADO) type I . * Declara atributos privados private section. data ID type i. data NOME type STRING . data IDADE type I . ENDCLASS. * Implementação da classe CLASS ZPARTICIPANTE IMPLEMENTATION. * Construtor METHOD CONSTRUCTOR. me->ID = PID. me->NOME = PNOME. me->IDADE = PIDADE. ENDMETHOD. * Metodos Getter e Setter METHOD GETIDADE. RESULTADO = me->IDADE. ENDMETHOD. METHOD GETNOME. RESULTADO = me->NOME. ENDMETHOD. METHOD GETID. RESULTADO = me->ID. ENDMETHOD. METHOD SETIDADE. me->IDADE = PIDADE. ENDMETHOD. METHOD SETNOME. me->NOME = PNOME. ENDMETHOD. METHOD SETID. me->ID = PID. ENDMETHOD. ENDCLASS. * testa programa START-OF-SELECTION. * Testa Classe DATA: p1 TYPE REF TO ZPARTICIPANTE, p2 TYPE REF TO ZPARTICIPANTE, id TYPE i, nome TYPE String, idade TYPE i. * Istancia Objeto usando Construtor Overload CREATE OBJECT P1 EXPORTING PID = 1 PNOME = 'José Pereira' PIDADE = 35. * Métodos Getter id = p1->GETID( ). nome = P1->GETNOME( ). idade = P1->GETIDADE( ). * Imprime valores P1 WRITE: / 'Valor do Objeto P1: ', id, nome, idade. *Instancia Objeto padrão CREATE OBJECT P2. * Métodos Setter p2->SETID( 2 ). p2->SETNOME( 'Joao da Silva' ). p2->SETIDADE( 20 ). * Métodos Getter id = p2->GETID( ). nome = P2->GETNOME( ). idade = P2->GETIDADE( ). * Imprime valores P2 WRITE: / 'Valor do Objeto P2: ', id, nome, idade. SKIP 2. WRITE : / 'Objetos da lista:'. SKIP 1. * *********************************************** * ************* Manipulando Objetos ************* * *********************************************** * * * Define Lista para iterar objetos * Listas e iteradores fazem parte do framework de coleções * São o meio padrão para manipular objetos * No entanto em ABAP Objects as coleções não * foram totalmente implementadas. * Declara instancia da classe para a lista DATA ITEM TYPE REF TO ZPARTICIPANTE. * Declara objeto de lista e iterador DATA LISTA TYPE REF TO CL_OBJECT_COLLECTION. DATA ITERADOR TYPE REF TO CL_OBJECT_COLLECTION_ITERATOR. * Cria lista CREATE OBJECT LISTA. * Adiciona Objeto a lista PERFORM ADD USING 3 'Mario Alvim' 27. PERFORM ADD USING 4 'Fernando Moraes' 45. PERFORM ADD USING 5 'Eduardo gonçalves' 38. * Atribui objeto ao Iterador ITERADOR = LISTA->GET_ITERATOR( ). * Usa iterator como um cursor de banco de dados WHILE ITERADOR->HAS_NEXT( ) IS NOT INITIAL. " Verifica objetos da lista ITEM ?= ITERADOR->GET_NEXT( ). " Alimenta objeto id = ITEM->GETID( ). nome = ITEM->GETNOME( ). idade = ITEM->GETIDADE( ). " Imprime dados do objeto WRITE : / id, nome, idade. ENDWHILE. * Cria uma polemica instrução FORM-PERFORM * Seria possivel criar uma classe com um método estatico * para executar a mesma função desta sub-rotina * mas encapsular os objetos criados daria muito mais trabalho * do que mesclar Objetos e uma instrução procedural. * * Desde que as Coleções não estão totalmente implementadas em ABAP OO * Exemplos utilizando o FORM-PERFORM para criar objetos * são muito comuns mesmo nos exemplos disponibilizados pela SAP * você pode conferir nos exemplos do NETWEAVER basta procurar na transação * ABAPDOCU e vai encontrar varios exemplos utilizando objetos inicializados com FORM-PERFORM * Este processo seria equivalente a uma VOID em C++ ou Def em Python ou Ruby que pode estar * tanto dentro de uma classe como um método ou fora de uma classe como um procedimento. FORM ADD USING VALUE(pid) TYPE i VALUE(pnome) TYPE string VALUE(pidade) TYPE i. * Cria objeto da classe como item CREATE OBJECT ITEM EXPORTING PID = pid PNOME = pnome PIDADE = pidade. * Adiciona a lista LISTA->ADD( ITEM ). ENDFORM.