Defensive Programming X Design by Contract

Fala Pessoal.

Ando lendo ultimamente sobre estas duas técnicas de desenvolvimento e não tenho certeza se percebi a diferença entre elas.

Não consegui ver se no Design By Contract, devo checar as pre-condições dentro da implementação do método (e jogar uma runtime exception se falhar) ou se devo confiar que o cliente vai me mandar argumentos válidos segundo o contrato (ou seja, não checar nada de pre-condições dentro do método; somente garantir as pós-condições dentro do meu método)

Poderiam comentar um pouco sobre essas duas técnicas, especialmente sobre suas diferenças ?

PS: Quem quiser ler mais a respeito comecei com esse artigo: http://fragmental.com.br/wiki/index.php?title=Contratos_Nulos

Valeu

[quote=rfa1989]Fala Pessoal.

Ando lendo ultimamente sobre estas duas técnicas de desenvolvimento e não tenho certeza se percebi a diferença entre elas.

Não consegui ver se no Design By Contract, devo checar as pre-condições dentro da implementação do método (e jogar uma runtime exception se falhar) ou se devo confiar que o cliente vai me mandar argumentos válidos segundo o contrato (ou seja, não checar nada de pre-condições dentro do método; somente garantir as pós-condições dentro do meu método)

Poderiam comentar um pouco sobre essas duas técnicas, especialmente sobre suas diferenças ?

PS: Quem quiser ler mais a respeito comecei com esse artigo: http://fragmental.com.br/wiki/index.php?title=Contratos_Nulos

Valeu[/quote]

Em DbC cada método deve verificar suas pré-condições (o que deve ser válido para que o método possa executar), garantir suas pós condições (o resultado esperado da execução) e manter as invariantes da classe (aquilo que deve ser verdadeiro ao final da execução de todos os métodos de uma classe).

Então está ok em eu começar a implementação de um método checando a validade dos argumentos que ele recebe e jogar exceções caso o argumento não seja válido (dentro daquilo que eu espero ser válido na seção de pré-condições do meu contrato ) ??

Como isso pode ser diferente do que é proposto pela programação defensiva?
Me parece exatamente a mesma técnica de abordagem.

Programação Defensiva é um conceito mais amplo. Você pode implementar DbC como parte de uma estratégia de Programação Defensiva. Além disso, a verificação de parâmetros de entrada é apenas parte de DbC. O que DbC propõe é a definição explícita dos contratos de cada operação de cada classe e do tratamento a ser dado, caso esse contrato seja quebrado.

Eu confesso que sou um fã de carteirinha de DbC…

Aqui está tudo o que consegui entender de DbC. Corrija ou valide pra mim, por favor:

Quando estiver escrevendo meu método, devo pensar num contrato firmado entre ele e o meu código cliente (que vai usar o método).
Como Java não possui recursos próprios pra lidar com DbC (como Eiffel), está ok em explicitar este contrato na forma de documentação do método.

O contrato consistirá basicamente de 3 comprometimentos:

  1. pré-condições: O código cliente deve garantir que os argumentos que ele passará para o meu método estão cumprindo um certo espaço de valores.
    Se os argumentos não estiverem ok (quebra do contrato) posso jogar uma runtime exception.
  2. pós-condições: Eu, como implementador do método, garanto que as pós-condições serão cumpridas ao final da execução do meu método.
  3. invariantes: São estados fixos dentro do meu método. Normalmente se o cliente respeita as pré-condições que atestei no contrato e eu escrevo um método que se compromete a cumprir as pós-condições, as invariantes não são violadas.

É isso mesmo?

E se eu não iniciar o meu método checando os argumentos recebidos.
Digo, se não houver essa fase inicial de validação (e throw de exceptions) na qual checo se os argumentos cumpriram a faixa de valores do contrato.

Considerando isso nas linhas acima, eu ainda posso dizer que minha técnica trata-se de DbC ?

[quote=rfa1989]
Aqui está tudo o que consegui entender de DbC. Corrija ou valide pra mim, por favor:

Quando estiver escrevendo meu método, devo pensar num contrato firmado entre ele e o meu código cliente (que vai usar o método).
Como Java não possui recursos próprios pra lidar com DbC (como Eiffel), está ok em explicitar este contrato na forma de documentação do método.

O contrato consistirá basicamente de 3 comprometimentos:

  1. pré-condições: O código cliente deve garantir que os argumentos que ele passará para o meu método estão cumprindo um certo espaço de valores.
    Se os argumentos não estiverem ok (quebra do contrato) posso jogar uma runtime exception.
  2. pós-condições: Eu, como implementador do método, garanto que as pós-condições serão cumpridas ao final da execução do meu método.
  3. invariantes: São estados fixos dentro do meu método. Normalmente se o cliente respeita as pré-condições que atestei no contrato e eu escrevo um método que se compromete a cumprir as pós-condições, as invariantes não são violadas.

É isso mesmo?[/quote]

Você pode explicitar em Java através de APIs de terceiros ou através de asserções. Contrato no papel não conta! :slight_smile:

Invariantes são condições que TODOS os métodos da classe devem respeitar. Por exemplo: Classe Defunto possui data de nascimento e data de falecimento e possui a seguinte invariante: “A data de nascimento não pode ser posterior a data de falecimento.”. Após a execução de qualquer método da classe Defunto, essa invariante deve ser verdadeira.

[quote=rfa1989]E se eu não iniciar o meu método checando os argumentos recebidos.
Digo, se não houver essa fase inicial de validação (e throw de exceptions) na qual checo se os argumentos cumpriram a faixa de valores do contrato.

Considerando isso nas linhas acima, eu ainda posso dizer que minha técnica trata-se de DbC ?[/quote]

Quem define o contrato é você. Se você acha que os parametros de entrada não fazem parte do contrato, não teste. Mas normalmente fazem!

Caro esmiralha,

obrigado pelas respostas.