Kontraktbaseret programmering er en tilgang til design af software. Den foreskriver at designere af software bør definere formelle, præcise og verificérbare specifikationer til softwarens grænseflader. Det er meningen at disse specifikationer skal udvide de sædvanlige definitioner for abstrakte datatyper med såkaldte forhåndsbetingelser, postconditions og invarianter, der kan betragtes som efterviselige, logiske udsagn som skal stemme overens med softwarens forventede adfærd. Disse specifikationer omtales som kontrakter og kan sammenlignes med betingelser og forpligtelser i juridiske kontrakter.
Formålet med kontraktbaseret programmering er at forsøge at garantere korrekt opførsel for software.
Begrebet blev først anvendt af Bertrand Meyer i forbindelse med designet af programmeringssproget Eiffel, og det blev først beskrevet i forskellige artikler i 1986 og uddybet i bogen Object-Oriented Software Construction i 1988 af samme. Begrebet Design by Contract er et varemærke i USA, hvorfor man på engelsk benytter en række varianter som Programming by Contract eller Contract Programming for at undgå problemer med varemærker.
Kernen i kontraktbaseret programmering hviler på en metafor, kontrakten, og analogien til hvordan dele af computersystemer samarbejder på basis af fælles forpligtelse og fælles fordele. Metaforen kommer fra forretningslivet hvor en klient og en leverandør laver aftaler på basis af en kontrakt. Disse kunne være:
Betingelser i kontraktbaseret programmering opdeles i forhåndsbetingelser, postconditions og invarianter, der henholdsvis kan forklares ved spørgsmålene Hvilke udsagn forventes at være sande her?, Hvilket arbejde kan garanteres at have været udført her? og Hvilke tilstande er garanteret fastholdt her?
Et objekt-orienteret softwareeksempel kunne være:
Kontraktbegrebet strækker sig her til funktions-/metode-/procedureniveau, og kontrakten for disse indeholder oftest informationer om:
Inden for kontraktbaseret programmering ses disse spørgsmål som så vigtige at tage stilling til, at man helst definerer kravene i designfasen samtidigt med udformningen af grænseflader, før man påbegynder programmeringen. Idet softwaren overholder kravene, kan en kontrakt ses som en del af softwarens dokumentation.
Ved brug af kontrakter er det desuden ikke meningen at verifikation af den samme del af kontrakten skal ske flere steder som en ekstra forsikring, men at softwaren fejler hårdt, altså udmelder en kørselsundtagelse, sådan at man ved fejlfinding kan drage nytte af fejlens placering i henhold til hvilken del af programmeringskoden der er ansvarlig for at fejlen ikke forekommer. Denne praksis står som modsætning til begrebet defensiv eller sikker programmering.