O COBOL orientado a objeto

Photo by Victoria Wendish on Unsplash

International Standard Organization (ISO) aprovou em 2002 (e depois revisou em 2014) um novo padrão para o COBOL que, dentre outras alterações, tentou unificar a notação da orientação a objetos na linguagem.

A ISO forçou a barra? Ou essa evolução era realmente necessária?

Classes em COBOL

A especificação de 2002 propõe uma estrutura padrão para definição de classes, métodos, herança, encapsulamento, polimorfismo e todos os outros conceitos fundamentais da orientação a objetos.

Parágrafos novos, instruções novas, mais palavras reservadas… Quem já conhece a linguagem fica com a impressão de que ela foi descaracterizada. Quem não conhece talvez não entenda o por que de tantas divisões, seções, parágrafos e comandos longos.

De qualquer forma, a melhor maneira de mostrar o COBOL “OO” na prática é usando um exemplo simples.

Imagine uma classe ALUNO que tenha três atributos (digamos NOME, NOTA1 e NOTA2) e um método (CALCULA_MEDIA). Estou usando uma convenção de nomenclatura parecida com a que estamos acostumados em COBOL, mas nada impediria, por exemplo, que usássemos os nomes “Aluno”, “nome”, “nota1”, “nota2” e “CalculaMedia”, como é comum em Java, C e outras linguagens.

A construção dessa classe em COBOL ficaria assim:

IDENTIFICATION DIVISION.
CLASS-ID. ALUNO INHERITS BASE.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
REPOSITORY.
   CLASS BASE IS "java.lang.Object".
   CLASS ALUNO IS "ALUNO".
   IDENTIFICATION DIVISION.
   OBJECT.
   DATA DIVISION.
   WORKING-STORAGE SECTION.
   01 O-NOME  PIC X(030).
   01 O-NOTA1 PIC 9(003).
   01 O-NOTA2 PIC 9(003).
   PROCEDURE DIVISION.
      IDENTIFICATION DIVISION.
      METHOD-ID. "CALCULA_MEDIA".
      DATA DIVISION.
      LINKAGE-SECTION.
      01  M-MEDIA PIC 9(003).
      PROCEDURE DIVISION RETURNING M-MEDIA.
      INICIO.
         COMPUTE M-MEDIA = (O-NOTA1 + O-NOTA2) / 2
      END METHOD "CALCULA_MEDIA".
   END OBJECT.
END-CLASS ALUNO.

A definição de uma classe usa o conceito de nested programs, também introduzido em 2002. Para quem não conhece, é como se tivéssemos subprogramas codificados no mesmo código fonte do programa original.

No exemplo acima, temos um “programa” para definir a classe que começa com a declaração CLASS-ID e vai até o END-CLASS na última linha. Na CLASS-ID usamos a declaração INHERITS para indicar qual a superclasse da classe que pretendemos criar.

Na ENVIRONMENT DIVISION temos o parágrafo REPOSITORY,  declarado na CONFIGURATION SECTION. Esse parágrafo informa para o compilador quais  classes serão utilizadas.  Como na CLASS-ID dissemos que ALUNO é filho de BASE, precisamos declarar no REPOSITORY onde essa classe BASE está definida.

Repare que, no nosso exemplo, BASE é a superclasse Object do pacote java.lang. Ou seja, podemos desenvolver uma aplicação que precise dos recursos do COBOL sem ter que reescrever todas as bibliotecas disponíveis na instalação.

“Dentro” do programa principal, temos o primeiro nested program para criação do objeto. Neste subprograma declaramos os atributos da classe ALUNO na WORKING-STORAGE.

Na PROCEDURE DIVISION da definição do objeto temos outro nested program para a declaração dos métodos da classe. Em nosso exemplo só temos um método, mas se precisássemos criar outro bastaria incluir outro nested program após o END METHOD anterior.

Usei o recurso dos nested programs apenas para facilitar a demonstração. Mas imagine que seria possível escrever nosso método numa unit totalmente independente, que poderíamos reaproveitar para classes diferentes. Essa possibilidade aumenta a capacidade de reuso do COBOL, permitindo inclusive que a linguagem se beneficie de recursos disponíveis em IDEs mais poderosas, como Eclipse e Visual Studio.

Instanciando o objeto

Agora vejamos um programa que pretenda instanciar o objeto ALUNO:

*------------------------------------------------------------*
 IDENTIFICATION DIVISION.
*------------------------------------------------------------*
 PROGRAM-ID. OBTMEDIA.
 AUTHOR. PAULO.
*------------------------------------------------------------*
 ENVIRONMENT DIVISION.
*------------------------------------------------------------*
 CONFIGURATION SECTION.
 REPOSITORY.
     CLASS ALUNO AS "ALUNO".
*------------------------------------------------------------*
 DATA DIVISION.
*------------------------------------------------------------*
 WORKING-STORAGE SECTION.
 01  P-NOME   PIC X(030).
 01  P-NOTA1  PIC 9(003).
 01  P-NOTA2  PIC 9(003).
 01  P-MEDIA  PIC 9(003).
 01  O-ALUNO OBJECT REFERENCE ALUNO.
*------------------------------------------------------------*
 PROCEDURE DIVISION.
*------------------------------------------------------------*
 INICIO.
     MOVE "JOAO" TO P-NOME
     MOVE 80     TO P-NOTA1
     MOVE 60     TO P-NOTA2
     INVOKE ALUNO "NEW" 
                USING P-NOME
                      P-NOTA1
                      P-NOTA2
            RETURNING O-ALUNO
     INVOKE O-ALUNO "CALCULA_MEDIA" 
            RETURNING P-MEDIA
     DISPLAY P-MEDIA
     STOP RUN.

Neste programa também declaramos o parágrafo REPOSITORY na CONFIGURATION SECTION para informar ao compilador onde estão as classes que pretendemos utilizar.

O objeto em si é declarado na WORKING STORAGE como qualquer outra variável,  fazendo referência à classe que informamos em REPOSITORY. Esse objeto é instanciado na PROCEDURE DIVISION pelo comando INVOKE que chama o método NEW. Poderíamos instanciar vários objetos (O-ALUNO1, O-ALUNO2… O-ALUNOn, ou até mesmo um array de ALUNOs) usando a mesma definição de classes.

Nosso programa instancia um objeto ALUNO preenchendo “Joao”, 80 e 60 para NOME, NOTA1 e NOTA2, respectivamente, e em seguida chama o método “CALCULA_MEDIA”, que definimos em nossa classe para obter a média das notas.

Conclusão

Existem diversos outros recursos na linguagem para implementar herança, polimorfismo e encapsulamento e sobre isso podemos falar em outro artigo. Por ora, acho que esse exemplo dá uma ideia de como fica a “cara” de um programa COBOL orientado a objeto.

Vale mencionar que muitos fornecedores implementaram a “notação” padrão sugerida pela ISO, mas criaram também suas próprias notações alternativas. Foi o que fizeram, por exemplo, a Micro Focus e a IBM.

Existe uma próxima revisão da ISO prevista para 2020 e, particularmente, acredito que essa notação padrão ainda tem muito o que evoluir. Mas isso vai depender do quanto a orientação a objetos em COBOL vai ser realmente absorvida pelo mercado.

Para ver outras mudanças que surgiram nessa versão do COBOL, veja esse artigo disponível aqui.


Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *