image

Acesse bootcamps ilimitados e +650 cursos

50
%OFF
Article image
Lilian Santos
Lilian Santos14/12/2024 14:48
Compartilhe

O que é Programação Orientada a Aspectos?

    Recentemente, desenvolvi um microshell como parte de um exercício prático sobre Programação Orientada a Aspectos (AOP), um paradigma de programação abordado na Formação C/C++ Developer da DIO . Este projeto foi uma oportunidade para explorar a aplicação de AOP em um contexto prático, integrando conceitos como modularização de aspectos transversais em um sistema.

    O que é um paradigma de programação?

    A evolução da programação de computadores resultou em diversas abordagens e estilos para resolver problemas de forma eficiente e modular. Essas abordagens são conhecidas como paradigmas de programação, que representam diferentes formas de organizar e estruturar o código. Cada paradigma tem características e filosofias próprias, e a escolha de um paradigma pode influenciar diretamente a legibilidade, manutenção e escalabilidade do software.

    Principais paradigmas de programação:

    • Programação Imperativa: Foca na execução de uma sequência de instruções para alterar o estado do sistema (ex: C ou Python).
    • Programação Funcional: Baseia-se em funções matemáticas, evitando o uso de estados mutáveis (ex: Haskell ou Lisp).
    • Programação Orientada a Objetos (POO): Organiza o código em objetos e classes para refletir entidades do mundo real (ex: Java ou Python).
    • Programação Estruturada: Organiza o código em blocos lógicos e sequenciais, utilizando estruturas de controle como laços e condicionais, visando melhorar a legibilidade e reduzir a complexidade (ex: C ou Pascal).
    • Programação Declarativa: Foca no "o que" o programa deve fazer, em vez de "como" fazer, como ocorre em linguagens de consulta (SQL) ou em frameworks de desenvolvimento reativos.
    • Programação Orientada a Eventos: Baseia-se em eventos (como cliques de mouse ou entradas de teclado), reagindo a esses eventos para determinar o fluxo do programa (ex: JavaScript).

    Programação Orientada a Aspectos (AOP), por sua vez, é um paradigma que complementa a Programação Orientada a Objetos, focando na separação de preocupações transversais (como logging, segurança e monitoramento) e permitindo que esses aspectos sejam aplicados de maneira centralizada, sem alterar o código principal do programa.

    Esse paradigma motivou o desenvolvimento de um projeto em meu campo de interesse: o desenvolvimento de um Shell em linguagem C. O objetivo foi criar uma versão simplificada do Shell, focando em aspectos transversais, como logs e tratamento de erros, de maneira modular, sem alterar a lógica central de execução de comandos.

    AOP em C: um desafio

    Embora AOP seja tradicionalmente associado a linguagens orientadas a objetos, como Java, que utiliza o AspectJ para modularizar aspectos transversais, eu me deparei com o desafio de aplicar AOP em um projeto em C. Isso exigiu uma abordagem manual para implementar a separação de preocupações, o que me proporcionou uma compreensão prática da aplicação desse paradigma.

    Durante o desenvolvimento do microshell, pude identificar claramente como AOP pode ser útil para lidar com preocupações transversais, como:

    • Logs: Registrar comandos digitados pelo usuário, erros e execuções.
    • Tratamento de erros: Centralizar a verificação e o tratamento de erros sem misturar com a lógica principal.
    • Validação: Garantir que os comandos recebidos sejam válidos antes de executá-los.

    Para ilustrar como cada um desses aspectos pode ser aplicado, trago exemplos práticos em C.

    1. Funções Decoradoras para Logs e Erros

    Uma função decoradora em AOP é uma técnica que permite adicionar funcionalidades a uma função ou método sem modificar seu código original. Ela "envolve" o comportamento da função, adicionando aspectos transversais como logging, segurança ou cache.

    O decorador atua como um advice, sendo aplicado em pontos específicos da execução de uma função, chamados joinpoints. Dependendo de como é aplicado, o decorador pode executar código antes (Before Advice), depois (After Advice) ou ao redor (Around Advice) da execução do método original, estendendo ou alterando seu comportamento sem alterar seu código principal.

    Neste pseudocódigo, um exemplo de função decoradora para interceptar chamadas a uma função:

    image

    2. Modularização de Preocupações Transversais

    Além dos logs, podemos aplicar modularização para separar funções que lidam com partes transversais, como:

    • Validação de Entrada: Verificar se os comandos passados são válidos.
    • Gerenciamento de Variáveis de Ambiente: Gerenciar o comportamento de variáveis de ambiente de forma separada da execução principal.

    Por exemplo, para adicionar um comportamento de validação antes da execução de um comando:

    image

    3. Aspectos Usando Funções Callback

    Outra forma de aplicar algo parecido com AOP em C é usar funções callback. Como por exemplo, definir uma função genérica que aceita uma função como argumento, e assim adicionar logs ou validações sempre que uma função de execução de comando for chamada.

    image

    4. Separar Lógica Principal de Aspectos com Arquivos Diferentes

    Se for grande, outra abordagem que se aproxima de AOP é separar as diferentes preocupações em módulos ou arquivos distintos:

    • logs.c: Funções que tratam de logging.
    • validacao.c: Funções para validar comandos.
    • execucao.c: Funções de execução de comandos.
    • main.c: Lógica principal que faz uso dessas funções.

    Isso cria uma modularização que facilita o reúso e a manutenção do código.

    Neste repositório compartilho o projeto microshell feito com a aplicação desses conceitos e outros projetos desenvolvidos na Formação C/C++ Developer.

    Conclusão

    Esse estudo mostrou, na prática, como conceitos da programação orientada a aspectos podem ser aplicados até mesmo em um projeto simples, como criar um micro shell em C. Trabalhar com logs e tratamento de erros de forma separada ajudou a deixar o código mais organizado e fácil de entender. Apesar de ser uma versão muito reduzida de um shell completo, a experiência serviu para mostrar como práticas modernas de desenvolvimento podem ser adaptadas para diferentes contextos como em em linguagens de baixo nível. Foi um exercício interessante que reforça a importância de buscar maneiras mais claras e eficientes de escrever código, mesmo em projetos pequenos.

    LilianMS

    Compartilhe
    Comentários (0)