Sopimuspohjainen ohjelmointi

Sopimuspohjainen ohjelmointi on tietokoneohjelmistojen suunnittelutapa. Sen mukaan ohjelmistosuunnittelijoiden tulisi määritellä muodolliset, täsmälliset ja tarkastettavat rajapintamääritykset ohjelmistokomponenteille. Nämä määritykset laajentavat tavallisten abstraktien tietotyyppien määritelmää alkuehdoilla, loppuehdoilla ja invarianteilla. Näitä määrityksiä kutsutaan sopimuksiksi konseptin käyttämän liike-elämän sopimusten ehtojen ja velvollisuuksien metaforan mukaan.

Historia

Termin otti ensimmäisenä käyttään Bertrand Meyer suunnittelemansa Eiffel-ohjelmointikielen yhteydessä ja kuvailtiin ensimmäisenä useissa artikkeleissa alkaen vuodesta 1986[1][2][3] ja kahdessa peräkkäisessä versiossa (1988, 1997) kirjastaan Object-Oriented Software Construction. Eiffel Software haki menetelmän englanninkieliselle nimelle ”Design by Contract” tavaramerkkisuojaa joulukuussa 2003, ja se myönnettiin joulukuussa 2004.[4][5] Tavaramerkin nykyinen omistaja on Eiffel Software.[6][7]

Kuvaus

Keskeinen idea sopimuspohjaisessa ohjelmoinnissa on se, kuinka ohjelmistojärjestelmän osaset työskentelevät yhdessä yhteisten ”velvoitteiden” ja ”hyötyjen” pohjalta. Metafora tulee liike-elämästä, jossa asiakas ja toimittaja sopivat sopimuksesta joka esimerkiksi määrittää, että:

  • Toimittajan tulee tarjota tietty tuote (velvoite) ja voi olettaa että asiakas on maksanut maksun (hyöty).
  • Asiakkaan tulee maksaa maksu (velvoite) ja saa tuotteen (hyöty).
  • Molempien osapuolten tulee täyttää tiettyjä velvoitteita, kuten lait ja asetukset, jotka pätevät kaikkiin sopimuksiin.

Vastaavasti, jos olio-ohjelmoinnin luokassa oleva rutiini tarjoaa tiettyä toiminnallisuutta, se voi:

  • Olettaa tietyn tilan olevan voimassa missä tahansa asiakasmoduulissa joka kutsuu sitä: Rutiinin alkuehto – velvoite asiakkaalle, ja hyöty toimittajalle (rutiini itsessään), koska se vapauttaa rutiinin käsittelemästä alkuehdon ulkopuolisia tapauksia.
  • Takaa tietyn ominaisuuden lopussa: Rutiinin loppuehto – velvoite toimittajalle, ja luonnollisesti hyöty (rutiinin kutsumisen päähyöty) asiakkaalle.
  • Pitää yllä tietty ominaisuus, joka oletetaan alussa ja taataan lopussa: Luokan invariantti.

Sopimus on näiden velvoitteiden ja hyötyjen muodollistamista (formalisointia). Sopimuspohjaisen ohjelmoinnin voi tiivistää seuraaviin ”kolmeen kysymykseen”,joita suunnittelijan tulee jatkuvasti kysyä:

  • Mitä se odottaa?
  • Mitä se takaa?
  • Mitä se ylläpitää?

Monissa kielissä on mahdollisuus tehdä tällaisia vakuutuksia. Sopimuspohjainen ohjelmointi kuitenkin pitää näitä sopimuksia niin elintärkeinä ohjelmiston oikeellisuudelle että niiden tulisi olla osa suunnitteluprosessia. Käytännössä sopimuspohjainen ohjelmointi kehottaa kirjoittamaan nämä vakuutukset ensin. Sopimuksen merkintä ulottuu metodi/proseduuri-tasolle asti; jokaisen metodin sopimus sisältää normaalisti seuraavat tiedot:

  • Hyväksyttävät ja ei-hyväksyttävät syöttöarvot tai tyypit, ja niiden tarkoitus,
  • Palautusarvot tai tyypit, ja niiden tarkoitus,
  • Niiden virhe- ja poikkeustilanteiden arvot ja tyypit, joita voi ilmetä, ja niiden tarkoitus,
  • Sivuvaikutukset,
  • Alkuehdot,
  • Loppuehdot,
  • Invariantit,
  • (Harvemmin) Suorituskykylupaukset, esim. käytetystä ajasta tai tilasta

Suhde ohjelmistojen testaukseen

Yksikkötestaus testaa moduulia eristyksessä tarkastaakseen, että se toteuttaa sopimuksensa olettaen, että alihankkijat toteuttavat omansa. Integraatiotestaus tarkastaa että eri moduulit toimivat oikein yhdessä.

Kielituki

Kielet, joissa natiivi tuki

Kieliä, jotka toteuttavat useimmat sopimuspohjaisen ohjelmoinnin ominaisuuksista, ovat esimerkiksi:

  • Cobra
  • D[8]
  • Eiffel
  • Fortress
  • Lisaac
  • Nice
  • Oxygene (ent. Chrome)
  • Sather
  • Spec#[9]

Kielet, joissa kolmannen osapuolen tuki

Monia kirjastoja, esikääntäjiä ja muita työkaluja on kehitetty olemassaoleville ohjelmointikielille ilman natiivia sopimuspohjaisen ohjelmoinnin tukea.

Yleisiä työkaluja

  • Perfect Developer voi, Perfect-määrityskielen kautta, varmistaa sopimuksia staattisella koodianalyysillä ja generoida ohjelmia kielillä kuten C++ ja Java.

Lähteet

  1. Meyer, Bertrand: Design by Contract, Technical Report TR-EI-12/CO, Interactive Software Engineering Inc., 1986
  2. Meyer, Bertrand: Design by Contract, in Advances in Object-Oriented Software Engineering, eds. D. Mandrioli and B. Meyer, Prentice Hall, 1991, pp. 1-50
  3. Meyer, Bertrand: Applying "Design by Contract", in Computer (IEEE), 25, 10.10.1992, sivut 40–51, saatavilla myös sähköisenä
  4. United States Patent and Trademark Office registration for "DESIGN BY CONTRACT" (Arkistoitu – Internet Archive)
  5. United States Patent and Trademark Office registration for the graphic design with words "Design by Contract" (Arkistoitu – Internet Archive)
  6. Current status of United States Patent and Trademark Office registration for "DESIGN BY CONTRACT"
  7. Current status of United States Patent and Trademark Office registration for the graphic design with words "Design by Contract"
  8. D Programming Language, Contract Programming 20.8.2006. Digital Mars. Viitattu 6.10.2006.
  9. https://www.microsoft.com/en-us/research/project/spec/

Kirjallisuutta

  • Mitchell, Richard & McKim, Jim: Design by Contract: by example, Addison-Wesley, 2002
  • A wikibook describing DBC closely to the original model.

Aiheesta muualla

  • An introduction to Design by Contract(TM)
  • Original IEEE Computer article
  • Isaac / Lisaac Project home
  • dlib C++ Library
  • Java Programming by Contract Class Utility (Arkistoitu – Internet Archive)
  • C2 Wiki: Design by Contract
  • Damian Conway's Class::Contract Perl module from CPAN
  • Raphael Manfredi's Carp::Datum Perl module from CPAN
  • GNU Nana
  • Digital Mars Contract Programming (DBC)
  • Class Contracts in Delphi Prism (Arkistoitu – Internet Archive)