Design by Contract® è un metodo utilizzato per sviluppare software che si basa sulla definizione di parametri di interfaccia ben definiti, o contratti, per tutte le parti di un programma. Sebbene Design by Contract® possa essere visto come uno stile di sviluppo concettuale che viene implementato attraverso la documentazione o la modellazione, è più ampiamente utilizzato per fare riferimento a un meccanismo nativo o di terze parti all’interno di alcuni linguaggi di programmazione che in realtà richiede la codifica implicita dei contratti all’interno un programma. L’obiettivo nell’utilizzo di Design by Contract® è che un programma venga sviluppato e, eventualmente, codificato in un modo molto più completo che rimuova gli errori più banali, mentre l’applicazione dei contratti da parte del linguaggio di supporto rende facilmente individuabili e catturati eventuali errori residui. Un programma che utilizza contratti per funzioni e classi può avere un design più modulare in cui le singole classi possono essere riutilizzate facilmente in altri programmi grazie alla chiara definizione dei loro contratti.
La base della filosofia di programmazione Design by Contract® è l’idea di contratti commerciali reali. In questo modello, ogni metodo e classe in un programma orientato agli oggetti definisce un contratto a cui deve attenersi qualsiasi altro metodo o oggetto che interagisce con esso. Ogni classe può anche avere un contratto, chiamato invariante di classe, che deve seguire internamente per garantire che i contratti esterni non compromettano la sua capacità di funzionare.
Le due parti di un contratto che sono più importanti durante la progettazione e la codifica sono le precondizioni e le post-condizioni. Queste due parti del modello Design by Contract® definiscono lo stato del programma prima che un metodo venga chiamato e lo stato del programma dopo che il metodo ha completato l’esecuzione. Altre parti di un contratto possono variare in base all’implementazione, ma potrebbero includere riferimenti incrociati ad altri moduli, condizioni di sincronizzazione e requisiti dell’ordine di esecuzione.
Sviluppando contratti per ogni classe e metodo, l’interazione delle diverse parti di un programma può essere facilmente mappata e prevista. L’esecuzione dei contratti, sia attraverso l’uso di asserzioni o altri meccanismi, garantisce anche che il programma non tenterà di eseguire se c’è una violazione dei contratti, perché qualsiasi output prodotto in quello stato sarebbe comunque tecnicamente non valido. Se implementato come funzionalità in lingua madre, Design by Contract® può aiutare a garantire che un prodotto finale funzioni come previsto con poche possibilità di errori imprevisti.
Alcune delle complicazioni che derivano dall’uso della filosofia Design by Contract® includono tempi di progettazione più lunghi e uno sviluppo più granulare di un sistema prima dell’inizio della codifica, che a volte può essere difficile con un progetto di grandi dimensioni. Più in pratica, il meccanismo di convalida del contratto utilizzato in un linguaggio di programmazione che supporta nativamente i contratti può rallentare l’esecuzione del programma. Una scarsa comprensione della metodologia Design by Contract® può portare a un programma che utilizza i contratti per eseguire il controllo degli errori di base, portando potenzialmente a un’applicazione soggetta a arresti anomali improvvisi dopo il rilascio.