Projeto por contrato

Da Wikipédia, a enciclopédia livre
Ir para a navegação Saltar para pesquisar
Um projeto por esquema de contrato

Design por contrato ( DbC ), também conhecido como programação de contrato , programação por contrato e programação de design por contrato , é uma abordagem para projetar software .

Ela prescreve que os designers de software devem definir especificações de interface formais , precisas e verificáveis ​​para componentes de software , que estendem a definição comum de tipos de dados abstratos com pré -condições , pós -condições e invariantes . Essas especificações são chamadas de "contratos", segundo uma metáfora conceitual com as condições e obrigações dos contratos comerciais.

A abordagem DbC pressupõe que todos os componentes do cliente que invocam uma operação em um componente do servidor atenderão às pré-condições especificadas conforme necessário para essa operação.

Onde essa suposição é considerada muito arriscada (como na computação multicanal ou distribuída ), a abordagem inversa é adotada, o que significa que o componente do servidor testa se todas as pré-condições relevantes são verdadeiras (antes ou durante o processamento da solicitação do componente cliente ) e responde com uma mensagem de erro adequada se não.

História [ editar ]

O termo foi cunhado por Bertrand Meyer em conexão com seu projeto da linguagem de programação Eiffel e descrito pela primeira vez em vários artigos começando em 1986 [1] [2] [3] e as duas edições sucessivas (1988, 1997) de seu livro Object- Construção Orientada de Software . A Eiffel Software solicitou o registro de marca para Design by Contract em dezembro de 2003, e foi concedido em dezembro de 2004. [4] [5] O atual proprietário desta marca registrada é Eiffel Software. [6] [7]

O projeto por contrato tem suas raízes no trabalho de verificação formal , especificação formal e lógica Hoare . As contribuições originais incluem:

Descrição [ editar ]

A idéia central do DbC é uma metáfora sobre como os elementos de um sistema de software colaboram entre si com base em obrigações e benefícios mútuos . A metáfora vem da vida empresarial, onde um "cliente" e um "fornecedor" acertam um "contrato" que define, por exemplo, que:

  • O fornecedor deve fornecer um determinado produto (obrigação) e tem o direito de esperar que o cliente tenha pago sua taxa (benefício).
  • O cliente deve pagar a taxa (obrigação) e tem direito a receber o produto (benefício).
  • Ambas as partes devem cumprir certas obrigações, como leis e regulamentos, aplicáveis ​​a todos os contratos.

Da mesma forma, se o método de uma classe na programação orientada a objetos fornece uma certa funcionalidade, ele pode:

  • Espere que uma certa condição seja garantida na entrada por qualquer módulo cliente que o chame: a pré- condição do método — uma obrigação para o cliente e um benefício para o fornecedor (o próprio método), pois o libera de ter que lidar com casos fora do a pré-condição.
  • Garantir uma certa propriedade na saída: a pós -condição do método — uma obrigação para o fornecedor e, obviamente, um benefício (o principal benefício de chamar o método) para o cliente.
  • Manter uma certa propriedade, assumida na entrada e garantida na saída: a classe invariante .

O contrato é semanticamente equivalente a um triplo Hoare que formaliza as obrigações. Isso pode ser resumido pelas "três perguntas" que o designer deve responder repetidamente no contrato:

  • O que o contrato espera?
  • O que o contrato garante?
  • O que o contrato mantém?

Muitas linguagens de programação têm facilidades para fazer afirmações como essas. No entanto, a DbC considera esses contratos tão cruciais para a correção do software que devem fazer parte do processo de design. Com efeito, a DbC defende que as afirmações sejam escritas primeiro . [ citação necessária ] Os contratos podem ser escritos por comentários de código , aplicados por um conjunto de testes , ou ambos, mesmo se não houver suporte de linguagem especial para contratos.

A noção de contrato estende-se ao nível do método/procedimento; o contrato para cada método normalmente conterá as seguintes informações: [ citação necessária ]

  • Valores ou tipos de entrada aceitáveis ​​e inaceitáveis ​​e seus significados
  • Valores ou tipos de retorno e seus significados
  • Valores ou tipos de condição de erro e exceção que podem ocorrer e seus significados
  • Efeitos colaterais
  • Pré-condições
  • Pós-condições
  • Invariantes
  • (mais raramente) Garantias de desempenho, por exemplo, para tempo ou espaço usado

Subclasses em uma hierarquia de herança podem enfraquecer pré-condições (mas não fortalecê-las) e fortalecer pós-condições e invariantes (mas não enfraquecê-las). Essas regras se aproximam da subtipagem comportamental .

Todos os relacionamentos de classe são entre classes de clientes e classes de fornecedores. Uma classe de cliente é obrigada a fazer chamadas para recursos do fornecedor onde o estado resultante do fornecedor não é violado pela chamada do cliente. Posteriormente, o fornecedor é obrigado a fornecer um estado de retorno e dados que não violem os requisitos estaduais do cliente.

Por exemplo, um buffer de dados do fornecedor pode exigir que os dados estejam presentes no buffer quando um recurso de exclusão é chamado. Posteriormente, o fornecedor garante ao cliente que quando um recurso de exclusão terminar seu trabalho, o item de dados será, de fato, excluído do buffer. Outros contratos de design são conceitos de invariante de classe . A invariante de classe garante (para a classe local) que o estado da classe será mantido dentro das tolerâncias especificadas ao final de cada execução de recurso.

Ao usar contratos, um fornecedor não deve tentar verificar se as condições do contrato estão satisfeitas - uma prática conhecida como programação ofensiva - a ideia geral é que o código deve "falhe com força", com a verificação do contrato sendo a rede de segurança.

A propriedade "fail hard" do DbC simplifica a depuração do comportamento do contrato, pois o comportamento pretendido de cada método é claramente especificado.

Essa abordagem difere substancialmente da programação defensiva , onde o fornecedor é responsável por descobrir o que fazer quando uma pré-condição é quebrada. Na maioria das vezes, o fornecedor lança uma exceção para informar ao cliente que a pré-condição foi quebrada e, em ambos os casos – DbC e programação defensiva – o cliente deve descobrir como responder a isso. Nesses casos, o DbC facilita o trabalho do fornecedor.

Design por contrato também define critérios de correção para um módulo de software:

  • Se a pré-condição AND invariante de classe for verdadeira antes de um fornecedor ser chamado por um cliente, então a condição AND invariante será verdadeira depois que o serviço for concluído.
  • Ao fazer chamadas para um fornecedor, um módulo de software não deve violar as pré-condições do fornecedor.

O design por contrato também pode facilitar a reutilização de código, pois o contrato de cada parte do código é totalmente documentado. Os contratos para um módulo podem ser considerados como uma forma de documentação de software para o comportamento desse módulo.

Implicações de desempenho [ editar ]

As condições do contrato nunca devem ser violadas durante a execução de um programa livre de bugs. Os contratos são, portanto, normalmente verificados apenas no modo de depuração durante o desenvolvimento do software. Mais tarde, no lançamento, as verificações de contrato são desativadas para maximizar o desempenho.

Em muitas linguagens de programação, os contratos são implementados com assert . Asserts são, por padrão, compiladas no modo de lançamento em C/C++, e desativadas da mesma forma em C# [8] e Java.

Iniciar o interpretador Python com "-O" (para "otimizar") como argumento também fará com que o gerador de código Python não emita nenhum bytecode para asserções. [9]

Isso elimina efetivamente os custos de tempo de execução das assertivas no código de produção – independentemente do número e do gasto computacional de asserts usadas no desenvolvimento – pois nenhuma dessas instruções será incluída na produção pelo compilador.

Relação com teste de software [ editar ]

O design por contrato não substitui as estratégias de teste regulares, como teste de unidade, teste de integração e teste de sistema . Em vez disso, complementa os testes externos com autotestes internos que podem ser ativados tanto para testes isolados quanto em código de produção durante uma fase de teste.

A vantagem dos autotestes internos é que eles podem detectar erros antes que eles se manifestem como resultados inválidos observados pelo cliente. Isso leva a uma detecção de erros mais precoce e específica.

O uso de assertivas pode ser considerado uma forma de oráculo de teste , uma forma de testar o design pela implementação do contrato.

Suporte a idiomas [ editar ]

Idiomas com suporte nativo [ editar ]

As linguagens que implementam a maioria dos recursos DbC nativamente incluem:

Idiomas com suporte de terceiros [ editar ]

Várias bibliotecas, pré-processadores e outras ferramentas foram desenvolvidas para linguagens de programação existentes sem design nativo por suporte de contrato:

Veja também [ editar ]

Notas [ editar ]

  1. ^ Meyer, Bertrand: Design by Contract , relatório técnico TR-EI-12/CO, Interactive Software Engineering Inc., 1986
  2. ^ Meyer, Bertrand: Design by Contract , em Advances in Object-Oriented Software Engineering , eds. D. Mandrioli e B. Meyer, Prentice Hall, 1991, pp. 1–50
  3. Meyer, Bertrand: Applying "Design by Contract" , em Computer (IEEE), 25, 10, outubro de 1992, pp. 40–51, também disponível online
  4. ^ "Registro do Escritório de Patentes e Marcas Registradas dos Estados Unidos para "DESIGN POR CONTRATO"" .
  5. ^ "Registro do United States Patent and Trademark Office para o design gráfico com as palavras "Design by Contract"" .
  6. ^ "Status da marca registrada e recuperação de documentos" . tarr.uspto.gov .
  7. ^ "Status da marca registrada e recuperação de documentos" . tarr.uspto.gov .
  8. ^ "Asserções no código gerenciado" . msdn.microsoft . com .
  9. ^ Documentos Python oficiais, declaração assert
  10. ^ Brilhante, Walter (2014-11-01). "Linguagem de Programação D, Programação de Contrato" . Marte Digital . Recuperado 2014-11-10 .
  11. ^ Hodges, Nick. "Escrever código mais limpo e de alta qualidade com contratos de classe no Delphi Prism" . Embarcadero Technologies . Recuperado em 20 de janeiro de 2016 .
  12. ^ Findler, Contratos Felleisen para funções de ordem superior
  13. ^ "Documentos da Biblioteca Padrão Scala - Asserções" . EPFL . Recuperado 2019-05-24 .
  14. Forte tipagem como outro "cumprimento de contrato" em Scala, veja discussão em scala-lang.org/ .
  15. ^ "Contratos de Código" . msdn.microsoft . com .
  16. ^ "Especificação de validação de feijão" . beanvalidation.org .
  17. ^ "Ajuda de teste de software dos peritos | Recursos da Parasoft" (PDF) .
  18. ^ "Cópia arquivada" (PDF) . Arquivado a partir do original (PDF) em 28/03/2016 . Recuperado 2016-03-25 . {{cite web}}: CS1 maint: archived copy as title (link)pág. 2
  19. ^ "Sem chance de lançamento sob licença Apache/Eclipse/MIT/BSD? · Edição #5 · nhatminhle/cofoja" . GitHub .

Bibliografia [ editar ]

  • Mitchell, Richard e McKim, Jim: Design by Contract: by example , Addison-Wesley, 2002
  • Um wikibook descrevendo o DBC próximo ao modelo original.
  • McNeile, Ashley: Uma estrutura para a semântica de contratos comportamentais . Anais do Segundo Workshop Internacional de Modelagem do Comportamento: Fundamentos e Aplicações (BM-FA '10). ACM, Nova York, NY, EUA, 2010. Este artigo discute noções generalizadas de Contrato e Substituibilidade .

Links externos [ editar ]