ADVPL é a linguagem estrutural clássica do Protheus; TLPP é a extensão orientada a objetos. Elas não competem — se complementam. O problema aparece quando se usa a errada para o problema certo.
ADVPL: rápido, direto e onipresente
Para customizações pontuais, pontos de entrada e rotinas de pequeno porte, ADVPL é imbatível: baixo custo de escrita, execução direta e qualquer desenvolvedor Protheus lê o código.
- Pontos de entrada (PEs) e validações simples.
- Jobs e rotinas lineares sem estado.
- Manutenção de legados existentes — a maioria da base instalada é ADVPL.
TLPP: organização para sistemas que crescem
Quando a regra de negócio ganha volume — validações compartilhadas, integrações com múltiplos canais, regras fiscais complexas — TLPP entrega o que ADVPL estrutural não consegue: encapsulamento, herança simples e organização em camadas.
- Serviços e APIs com camadas (controle + regra + acesso a dados).
- Regras reutilizadas em várias rotinas sem copiar código.
- Equipes maiores, onde o código precisa ser autodocumentado.
Comparação lado a lado
Veja a mesma regra — cálculo de desconto por faixa de volume — implementada nas duas linguagens:
User Function CalcDesc(nQtd, nPreco) Local nDesc := 0 If nQtd >= 100 nDesc := nPreco * 0.15 ElseIf nQtd >= 50 nDesc := nPreco * 0.10 ElseIf nQtd >= 20 nDesc := nPreco * 0.05 EndIf Return nDesc
// TLPP — Mesma regra com classe #Include "totvs.ch" Class CalculadoraDesconto Data nQtd As Numeric Data nPreco As Numeric Public Method New(nQtd, nPreco) Public Method Calcula() EndClass Method New(nQtd, nPreco) Class CalculadoraDesconto ::nQtd := nQtd ::nPreco := nPreco Return Self Method Calcula() Class CalculadoraDesconto Local nDesc := 0 If ::nQtd >= 100 nDesc := ::nPreco * 0.15 ElseIf ::nQtd >= 50 nDesc := ::nPreco * 0.10 ElseIf ::nQtd >= 20 nDesc := ::nPreco * 0.05 EndIf Return nDesc // Uso: // ATENÇÃO: instancie com parênteses — CalculadoraDesconto():New(...) // (no TLPP, a classe é chamada com () antes de :New; sem () não compila) Local oCalc := CalculadoraDesconto():New(80, 150) nDesc := oCalc:Calcula()
A versão ADVPL tem 10 linhas. A TLPP tem 25. Para uma regra pontual, ADVPL vence. Mas quando essa regra precisa ser reusada em 15 rotinas diferentes, a classe TLPP se paga em uma semana.
#Include "totvs.ch" e, quando derivam de outra classe, o construtor chama _Super:New() antes de inicializar os próprios dados. O exemplo acima está simplificado para focar na comparação.Onde TLPP é obrigatório
No Protheus moderno, existem contextos onde TLPP não é opcional — é obrigatório:
- MVC (Model-View-Controller): telas de cadastro usam classes Model e Grid. O framework exige TLPP.
- Integrações fiscais via TSS (TOTVS Sped Service): o serviço que gerencia NF-e/CT-e/MDF-e trabalha com classes.
- PO-UI Backend: APIs REST que alimentam o PO-UI são mais organizadas com classes de serviço.
- Regras fiscais complexas: cálculo de impostos com múltiplas exceções se beneficia de herança e polimorfismo.
Performance: TLPP é mais lento?
Não. O overhead de TLPP vs ADVPL é desprezível em operações normais. A diferença aparece apenas em:
- Milhares de objetos instanciados em loop: criar 10k objetos TLPP em um loop tem overhead vs vetores ADVPL.
- Introspecção pesada: usar
ClassDataArr()em loop pode ser lento.
Na prática: a maioria dos cenários de negócio não nota diferença. Meça o seu caso antes de atribuir lentidão à linguagem — normalmente o gargalo está em query, índice ou E/S, não em TLPP.
Critérios objetivos de escolha
Um bom exercício é responder: a regra será reutilizada? Vai crescer? Precisa de teste isolado?
Se regra é pontual e sem reuso -> ADVPL (PE / rotina curta) Se regra é compartilhada e cresce -> TLPP (classe + serviço) Se é legado e estável -> manter ADVPL, extrair só o que muda Se é API/integração -> TLPP para o contrato, ADVPL no ponto de entrada Se é MVC ou PO-UI -> TLPP obrigatório
Armadilhas comuns
- TLPP por moda: transformar um PE de 20 linhas numa árvore de classes é desperdício.
- ADVPL gigante: uma rotina de 2.000 linhas estruturais é impossível de manter — nesse ponto, TLPP.
- Mistura sem critério: o ambiente aceita as duas, mas a decisão precisa ser documentada no código.
- Esperar herança múltipla: TLPP não suporta. Use composição ou interfaces.
Na prática, a regra que usamos: ADVPL para intervenções cirúrgicas, TLPP para engenharia de software. O resultado é código que o próximo desenvolvedor entende sem susto.
Quer revisar a arquitetura do seu desenvolvimento Protheus?
Falar com a ELP