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 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. Tavaramerkin nykyinen omistaja on Eiffel Software.

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
 Eiffel
 Fortress
 Lisaac
 Nice
 Oxygene (ent. Chrome)
 Sather
 Spec#

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

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 
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 

Ohjelmointi