|
| Programação Defensiva no WLangage |
| Iniciado por Boller, ago., 05 2025 2:36 AM - Sem resposta |
| |
| | | |
|
| |
Membro registado 4.618 mensagems |
|
| Publicado em agosto, 05 2025 - 2:36 AM |
Programação Defensiva no WLangage
O que é?
A programação defensiva consiste em verificar dentro do próprio código as entradas e saídas de cada procedimento, de modo a antecipar e tratar possíveis erros. Esses problemas são sinalizados apenas em modo de depuração (debug), garantindo que o software funcione de forma mais segura .
Ferramentas disponíveis
O WLangage inclui funções específicas para auxiliar na programação defensiva, tais como: • dbgAssertion, dbgVérifieVrai, dbgVérifieFaux, dbgVérifieEgalité, dbgVérifieDifférence, dbgVérifieNonNull, dbgVérifieNull. • dbgErreurProvoque e dbgSurErreur: permitem lançar erros ou chamar rotinas específicas em caso de falha   .
Testes automáticos integrados
No WLangage, funções como TestVérifieEgalité, TestVérifieDifférence, TestVérifieVrai, etc., são usadas em testes unitários. Elas possuem comportamento semelhante às funções dbg…, mas são executadas em modo automático de teste, gerando relatórios ou falhas conforme o caso  .
Como funciona • Em modo execução normal, se as assertions não estiverem ativas, nenhum teste é avaliado. • Em modo depuração ou modo de teste, os testes são avaliados e, se falharem, resultam em erros ou assertivas dependendo do modo .
⸻
📋 Resumo em tabela
Conceito Objetivo Modo de execução Verificação de entradas e saídas Antecipar erros em procedimentos Sempre (em modo de depuração) dbgVérifie… Avaliações no ambiente de depuração ou testes Produz assert ou erro TestVérifie… Avaliações em testes unitários automáticos Gera relatórios ou falhas
⸻
// ================================================== // EXEMPLO 1: Verificar se um valor não é nulo // ================================================== PROCEDURE GetCustomerName(customerID)
dbgVérifieNonNull(customerID, "O ID do cliente não pode ser nulo")
IF NOT HReadSeekFirst(Customer, CustomerID, customerID) THEN dbgErreurProvoque("Cliente não encontrado no banco de dados") RETURN "" END
RETURN Customer.Name
// ================================================== // EXEMPLO 2: Verificar igualdade entre valores esperados // ================================================== PROCEDURE CalculateDiscount(price, discount)
dbgVérifieVrai(price > 0, "Preço inválido") dbgVérifieVrai(discount >= 0 AND discount <= 100, "Desconto fora da faixa")
nFinalPrice IS real = price - (price * discount / 100)
// Verificação fictícia de consistência (apenas para debug) dbgVérifieEgalité(nFinalPrice <= price, True, "O preço final não pode ser maior que o original")
RETURN nFinalPrice
// ================================================== // EXEMPLO 3: Testes automatizados com TestVérifie... // ================================================== TestVérifieEgalité(CalculateDiscount(100, 10), 90) TestVérifieDifférence(CalculateDiscount(100, 5), 94.99) // Deve falhar TestVérifieVrai(CalculateDiscount(200, 20) = 160)
// ================================================== // EXEMPLO 4: Múltiplas verificações com dbgVérifie... // ================================================== PROCEDURE TransferBalance(senderID, receiverID, amount)
dbgVérifieNonNull(senderID) dbgVérifieNonNull(receiverID) dbgVérifieVrai(amount > 0, "O valor da transferência deve ser positivo")
IF NOT HReadSeekFirst(Account, AccountID, senderID) THEN dbgErreurProvoque("Remetente inválido") END
IF Account.Balance < amount THEN dbgErreurProvoque("Saldo insuficiente") END
Account.Balance -= amount HModify(Account)
IF NOT HReadSeekFirst(Account, AccountID, receiverID) THEN dbgErreurProvoque("Destinatário inválido") END
Account.Balance += amount HModify(Account)
RETURN True
// ================================================== // DICA EXTRA: Ativando ou desativando assertions // ==================================================
// No código de inicialização do projeto: dbgActive(True) // Ativa assertions em desenvolvimento
// Em produção: dbgActive(False) // Desativa para evitar impacto no desempenho
Claro! Abaixo está um texto explicativo completo, com base nos exemplos que criamos, utilizando situações reais do dia a dia de um sistema empresarial. O objetivo é mostrar como e por que usar cada comando de programação defensiva do WLanguage para garantir segurança, estabilidade e rastreabilidade dos erros em tempo de desenvolvimento.
⸻
🛡️ Programação Defensiva em WLanguage: Como usar e por quê?
A programação defensiva é uma prática essencial para garantir que seu sistema não quebre silenciosamente durante a execução. No universo WX (WinDev, WebDev e WinDev Mobile), temos um arsenal de comandos como dbgVérifie..., dbgErreurProvoque, TestVérifie... e dbgActive que permitem aplicar essa estratégia de forma elegante.
A seguir, vamos explorar cada um desses comandos em situações reais:
⸻
✅ dbgVérifieNonNull: Garantir que o valor obrigatório foi informado
Situação real: Você está desenvolvendo uma procedure que busca o nome do cliente a partir do ID recebido como parâmetro. Mas e se esse ID vier nulo?
dbgVérifieNonNull(customerID, "O ID do cliente não pode ser nulo")
Se o customerID for nulo durante o desenvolvimento, o sistema irá parar e mostrar uma mensagem clara, evitando bugs difíceis de rastrear mais tarde. Isso é vital em sistemas com múltiplos pontos de entrada, como APIs REST, que podem receber dados malformados.
⸻
✅ dbgVérifieVrai: Validar se uma condição foi satisfeita
Situação real: Antes de aplicar um desconto em uma compra, precisamos ter certeza de que o valor do desconto é válido (por exemplo, entre 0% e 100%).
dbgVérifieVrai(discount >= 0 AND discount <= 100, "Desconto fora da faixa")
Durante o desenvolvimento, se alguém tentar dar um desconto de 110%, o sistema avisa o programador imediatamente. Isso protege a lógica de negócio desde o início e evita falhas financeiras.
⸻
✅ dbgVérifieEgalité: Confirmar resultados esperados
Situação real: Após aplicar o desconto, o valor final não pode ser maior que o original. Parece óbvio, mas isso precisa ser testado.
dbgVérifieEgalité(nFinalPrice <= price, True, "O preço final não pode ser maior que o original")
Esse tipo de verificação é excelente para garantir que fórmulas matemáticas estejam corretas — principalmente em áreas críticas como faturamento ou cálculo de impostos.
⸻
✅ dbgErreurProvoque: Forçar uma interrupção com mensagem específica
Situação real: Você está buscando um cliente ou conta no banco de dados. Se o ID informado não existe, é melhor abortar o processo imediatamente.
IF NOT HReadSeekFirst(Customer, CustomerID, customerID) THEN dbgErreurProvoque("Cliente não encontrado no banco de dados") END
O uso de dbgErreurProvoque impede que o código continue com variáveis vazias ou dados inválidos, o que poderia causar erros difíceis de identificar em produção. É uma forma de aplicar o princípio do fail fast: falhar o quanto antes.
⸻
✅ TestVérifieEgalité, TestVérifieDifférence, TestVérifieVrai: Testes automatizados
Situação real: Você quer garantir que a função de cálculo de desconto está retornando os valores esperados. Para isso, criamos testes automáticos.
TestVérifieEgalité(CalculateDiscount(100, 10), 90) TestVérifieDifférence(CalculateDiscount(100, 5), 94.99) // Deve falhar TestVérifieVrai(CalculateDiscount(200, 20) = 160)
Esses comandos são usados fora do código principal, em scripts de teste. Eles são ideais para validar módulos críticos e manter uma base de regressão para futuras alterações.
⸻
✅ dbgActive(True/False): Ativar ou desativar verificações
Situação real: Você está desenvolvendo um sistema novo e quer garantir máxima validação enquanto escreve o código. Mas, ao colocar o sistema em produção, deseja desligar essas verificações para ganhar performance.
// Em desenvolvimento dbgActive(True)
// Em produção dbgActive(False)
Essa função te dá controle total para ativar ou desativar as verificações, permitindo um ciclo de desenvolvimento seguro e uma execução rápida no cliente.
⸻
✅ Conclusão: Segurança e rastreabilidade com código limpo
A programação defensiva não é frescura, é prevenção ativa. Quando bem aplicada com as funções do WLanguage, ela: • Reduz erros em produção • Facilita a manutenção • Aumenta a confiança no código • Torna o comportamento do sistema mais previsível
Em sistemas empresariais, principalmente em áreas como financeiro, contratos, estoque e comunicações, essas práticas não são opcionais — são essenciais.
// ================================================== // EXEMPLO 5: Validação de e-mail com dbgVérifieFaux // ================================================== PROCEDURE ValidateEmail(email)
dbgVérifieFaux(email = "", "E-mail não pode ser vazio")
bIsValid IS boolean = StringCount(email, "@") = 1 AND StringCount(email, ".") > 0 dbgVérifieVrai(bIsValid, "E-mail inválido")
RETURN True
// ================================================== // EXEMPLO 6: Verificação de senha forte com dbgVérifieVrai // ================================================== PROCEDURE CheckPasswordStrength(password)
dbgVérifieVrai(Length(password) >= 8, "Senha muito curta") dbgVérifieVrai(StringCount(password, "0") + StringCount(password, "1") > 0, "Senha precisa conter números") dbgVérifieVrai(Upper(password) <> password, "Senha precisa conter letras minúsculas") dbgVérifieVrai(password <> Lower(password), "Senha precisa conter letras maiúsculas")
RETURN True
// ================================================== // EXEMPLO 7: Testes automatizados com valores calculados // ================================================== TestVérifieEgalité(ValidateEmail("teste@exemplo.com"), True) TestVérifieFaux(ValidateEmail("invalido.com")) TestVérifieEgalité(CheckPasswordStrength("Abc12345"), True) TestVérifieFaux(CheckPasswordStrength("abc"))
// ================================================== // EXEMPLO 8: Verificar se um campo obrigatório está preenchido // ================================================== PROCEDURE SaveProduct(productName, price)
dbgVérifieFaux(productName = "", "O nome do produto é obrigatório")
dbgVérifieVrai(price > 0, "Preço deve ser maior que zero")
// Simular gravação Trace("Produto salvo: " + productName + " - R$ " + NumToString(price))
RETURN True
// ================================================== // EXEMPLO 9: Prevenção de divisão por zero // ================================================== PROCEDURE CalculateAverage(total, count)
dbgVérifieVrai(count > 0, "Divisão por zero ao calcular média")
RETURN total / count
// ================================================== // EXAMPLE 1: Validate email using dbgVérifieFaux // ================================================== PROCEDURE ValidateEmail(email)
dbgVérifieFaux(email = "", "Email must not be empty")
bIsValid IS boolean = StringCount(email, "@") = 1 AND StringCount(email, ".") > 0 dbgVérifieVrai(bIsValid, "Invalid email format")
RETURN True
// ================================================== // EXAMPLE 2: Check strong password using dbgVérifieVrai // ================================================== PROCEDURE CheckPasswordStrength(password)
dbgVérifieVrai(Length(password) >= 8, "Password is too short") dbgVérifieVrai(StringCount(password, "0") + StringCount(password, "1") > 0, "Password must contain numbers") dbgVérifieVrai(Upper(password) <> password, "Password must contain lowercase letters") dbgVérifieVrai(password <> Lower(password), "Password must contain uppercase letters")
RETURN True
// ================================================== // EXAMPLE 3: Automated tests using TestVérifie... // ================================================== TestVérifieEgalité(ValidateEmail("test@example.com"), True) TestVérifieFaux(ValidateEmail("invalid-email.com")) TestVérifieEgalité(CheckPasswordStrength("Abc12345"), True) TestVérifieFaux(CheckPasswordStrength("abc"))
// ================================================== // EXAMPLE 4: Check required fields before saving a product // ================================================== PROCEDURE SaveProduct(productName, price)
dbgVérifieFaux(productName = "", "Product name is required") dbgVérifieVrai(price > 0, "Price must be greater than zero")
Trace("Product saved: " + productName + " - $" + NumToString(price))
RETURN True
// ================================================== // EXAMPLE 5: Prevent division by zero using dbgVérifieVrai // ================================================== PROCEDURE CalculateAverage(total, count)
dbgVérifieVrai(count > 0, "Division by zero when calculating average")
RETURN total / count
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianoboller http://wxinformatica.com.br/ |
| |
| |
| | | |
|
| | | | |
| | |
|