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