Recent from talks
Nothing was collected or created yet.
Design by contract
View on WikipediaThis article needs additional citations for verification. (July 2025) |

Design by contract (DbC), also known as contract programming, programming by contract and design-by-contract programming, is an approach for designing software.
It prescribes that software designers should define formal, precise and verifiable interface specifications for software components, which extend the ordinary definition of abstract data types with preconditions, postconditions and invariants. These specifications are referred to as "contracts", in accordance with a conceptual metaphor with the conditions and obligations of business contracts.
The DbC approach assumes all client components that invoke an operation on a server component will meet the preconditions specified as required for that operation.
Where this assumption is considered too risky (as in multi-channel or distributed computing), the inverse approach is taken, meaning that the server component tests that all relevant preconditions hold true (before, or while, processing the client component's request) and replies with a suitable error message if not.
History
[edit]The term was coined by Bertrand Meyer in connection with his design of the Eiffel programming language and first described in various articles starting in 1986[1][2][3] and the two successive editions (1988, 1997) of his book Object-Oriented Software Construction. Eiffel Software applied for trademark registration for Design by Contract in December 2003, and it was granted in December 2004.[4][5] The current owner of this trademark is Eiffel Software.[6][7]
Design by contract has its roots in work on formal verification, formal specification and Hoare logic. The original contributions include:
- A clear metaphor to guide the design process
- The application to inheritance, in particular a formalism for redefinition and dynamic binding
- The application to exception handling
- The connection with automatic software documentation
Description
[edit]The central idea of DbC is a metaphor on how elements of a software system collaborate with each other on the basis of mutual obligations and benefits. The metaphor comes from business life, where a "client" and a "supplier" agree on a "contract" that defines, for example, that:
- The supplier must provide a certain product (obligation) and is entitled to expect that the client has paid its fee (benefit).
- The client must pay the fee (obligation) and is entitled to get the product (benefit).
- Both parties must satisfy certain obligations, such as laws and regulations, applying to all contracts.
Similarly, if the method of a class in object-oriented programming provides a certain functionality, it may:
- Expect a certain condition to be guaranteed on entry by any client module that calls it: the method's precondition—an obligation for the client, and a benefit for the supplier (the method itself), as it frees it from having to handle cases outside of the precondition.
- Guarantee a certain property on exit: the method's postcondition—an obligation for the supplier, and obviously a benefit (the main benefit of calling the method) for the client.
- Maintain a certain property, assumed on entry and guaranteed on exit: the class invariant.
The contract is semantically equivalent to a Hoare triple which formalises the obligations. This can be summarised by the "three questions" that the designer must repeatedly answer in the contract:
- What does the contract expect?
- What does the contract guarantee?
- What does the contract maintain?
Many programming languages have facilities to make assertions like these. However, DbC considers these contracts to be so crucial to software correctness that they should be part of the design process. In effect, DbC advocates writing the assertions first.[citation needed] Contracts can be written by code comments, enforced by a test suite, or both, even if there is no special language support for contracts.
The notion of a contract extends down to the method/procedure level; the contract for each method will normally contain the following pieces of information:[citation needed]
- Acceptable and unacceptable input values or types, and their meanings
- Return values or types, and their meanings
- Error and exception condition values or types that can occur, and their meanings
- Side effects
- Preconditions
- Postconditions
- Invariants
- (more rarely) Performance guarantees, e.g. for time or space used
Subclasses in an inheritance hierarchy are allowed to weaken preconditions (but not strengthen them) and strengthen postconditions and invariants (but not weaken them). These rules approximate behavioural subtyping.
All class relationships are between client classes and supplier classes. A client class is obliged to make calls to supplier features where the resulting state of the supplier is not violated by the client call. Subsequently, the supplier is obliged to provide a return state and data that does not violate the state requirements of the client.
For instance, a supplier data buffer may require that data is present in the buffer when a delete feature is called. Subsequently, the supplier guarantees to the client that when a delete feature finishes its work, the data item will, indeed, be deleted from the buffer. Other design contracts are concepts of class invariant. The class invariant guarantees (for the local class) that the state of the class will be maintained within specified tolerances at the end of each feature execution.
When using contracts, a supplier should not try to verify that the contract conditions are satisfied—a practice known as offensive programming—the general idea being that code should "fail hard", with contract verification being the safety net.
DbC's "fail hard" property simplifies the debugging of contract behavior, as the intended behaviour of each method is clearly specified.
This approach differs substantially from that of defensive programming, where the supplier is responsible for figuring out what to do when a precondition is broken. More often than not, the supplier throws an exception to inform the client that the precondition has been broken, and in both cases—DbC and defensive programming alike—the client must figure out how to respond to that. In such cases, DbC makes the supplier's job easier.
Design by contract also defines criteria for correctness for a software module:
- If the class invariant AND precondition are true before a supplier is called by a client, then the invariant AND the postcondition will be true after the service has been completed.
- When making calls to a supplier, a software module should not violate the supplier's preconditions.
Design by contract can also facilitate code reuse, since the contract for each piece of code is fully documented. The contracts for a module can be regarded as a form of software documentation for the behavior of that module.
Design by contract may look something like this:[8][9]
int f(const int x)
pre(x != 1) // a precondition assertion
post(r : r == x && r != 2) // a postcondition assertion; r names the result object of f
{
contract_assert(x != 3); // an assertion statement
return x;
}
Performance implications
[edit]Contract conditions should never be violated during execution of a bug-free program. Contracts are therefore typically only checked in debug mode during software development. Later at release, the contract checks are disabled to maximize performance.
In many programming languages, contracts are implemented with assert. Asserts are by default compiled away in release mode in C/C++, and similarly deactivated in C#[10] and Java.
Launching the Python interpreter with "-O" (for "optimize") as an argument will likewise cause the Python code generator to not emit any bytecode for asserts.[11]
This effectively eliminates the run-time costs of asserts in production code—irrespective of the number and computational expense of asserts used in development—as no such instructions will be included in production by the compiler.
Relationship to software testing
[edit]Design by contract does not replace regular testing strategies, such as unit testing, integration testing and system testing. Rather, it complements external testing with internal self-tests that can be activated both for isolated tests and in production code during a test-phase.
The advantage of internal self-tests is that they can detect errors before they manifest themselves as invalid results observed by the client. This leads to earlier and more specific error detection.
The use of assertions can be considered to be a form of test oracle, a way of testing the design by contract implementation.
Language support
[edit]Languages with native support
[edit]Languages that implement most DbC features natively include:
- Ada 2012
- Ciao
- Clojure
- Cobra
- C++ (since C++26)
- D[12]
- Dafny
- Eiffel
- Fortress
- Kotlin
- Mercury
- Oxygene (formerly Chrome and Delphi Prism[13])
- Racket (including higher order contracts, and emphasizing that contract violations must blame the guilty party and must do so with an accurate explanation[14])
- Sather
- Scala[15][16]
- SPARK (via static analysis of Ada programs)
- Vala
- Vienna Development Method (VDM)
Additionally, the standard method combination in the Common Lisp Object System has the method qualifiers :before, :after and :around that allow writing contracts as auxiliary methods, among other uses.
See also
[edit]Notes
[edit]- ^ Meyer, Bertrand: Design by Contract, Technical Report TR-EI-12/CO, Interactive Software Engineering Inc., 1986
- ^ Meyer, Bertrand: Design by Contract, in Advances in Object-Oriented Software Engineering, eds. D. Mandrioli and B. Meyer, Prentice Hall, 1991, pp. 1–50
- ^ Meyer, Bertrand: "Applying "Design by Contract"", in Computer (IEEE), 25, 10, October 1992, pp. 40–51.
- ^ "United States Patent and Trademark Office registration for "DESIGN BY CONTRACT"". Archived from the original on 2016-12-21. Retrieved 2009-06-22.
- ^ "United States Patent and Trademark Office registration for the graphic design with words "Design by Contract"". Archived from the original on 2016-12-21. Retrieved 2009-06-22.
- ^ "Trademark Status & Document Retrieval - 78342277". USPTO Trademark Application and Registration Retrieval.
- ^ "Trademark Status & Document Retrieval - 78342308". USPTO Trademark Application and Registration Retrieval.
- ^ Joshua Berne, Timur Doumler, Andrzej Krzemieński (13 February 2025). "Contracts for C++" (PDF). open-std.org. WG 22.
{{cite web}}: CS1 maint: multiple names: authors list (link) - ^ "Contract assertions (since C++26)". cppreference.com. cppreference. Retrieved 9 November 2025.
- ^ "Assertions in Managed Code". Microsoft Developer Network. 15 November 2016. Archived from the original on Aug 22, 2018.
- ^ Official Python Docs, assert statement
- ^ Bright, Walter (2014-11-01). "D Programming Language, Contract Programming". Digital Mars. Retrieved 2014-11-10.
- ^ Hodges, Nick. "Write Cleaner, Higher Quality Code with Class Contracts in Delphi Prism". Embarcadero Technologies. Archived from the original on 26 April 2021. Retrieved 20 January 2016.
- ^ Findler, Felleisen Contracts for Higher-Order Functions
- ^ "Scala Standard Library Docs - Assertions". EPFL. Retrieved 2019-05-24.
- ^ Strong typing as another "contract enforcing" in Scala, see discussion at scala-lang.org/.
Bibliography
[edit]- Mitchell, Richard, and McKim, Jim: Design by Contract: by example, Addison-Wesley, 2002
- A wikibook describing DBC closely to the original model.
- McNeile, Ashley: A framework for the semantics of behavioral contracts. Proceedings of the Second International Workshop on Behaviour Modelling: Foundation and Applications (BM-FA '10). ACM, New York, NY, USA, 2010. This paper discusses generalized notions of Contract and Substitutability.
External links
[edit]- The Power of Design by Contract(TM) A top-level description of DbC, with links to additional resources.
- Building bug-free O-O software: An introduction to Design by Contract(TM) Older material on DbC.
- Benefits and drawbacks; implementation in RPS-Obix
- Using Code Contracts for Safer Code
Design by contract
View on GrokipediaCore Concepts
Preconditions
In Design by Contract (DbC), preconditions are boolean conditions that must evaluate to true immediately before a subroutine (such as a method or function) is invoked, verifying that the inputs and context satisfy the necessary criteria for the routine to operate correctly.[1] These conditions form part of the explicit contract between the caller (client) and the callee (supplier), outlining the assumptions under which the routine is valid.[2] Preconditions delineate the responsibilities of the caller, requiring them to ensure these conditions hold; if violated, the supplier bears no obligation to produce correct results or avoid failure, thereby shifting accountability and preventing the supplier from needing to handle invalid scenarios defensively.[1] This delineation promotes a clear division of labor in software design, where the supplier can focus on specified behaviors without redundant validation.[2] For instance, in an array access routine, a precondition might stipulate that the provided index is non-negative and within the array's bounds to ensure safe retrieval. Similarly, for inserting an element into a bounded collection like a stack or table, the precondition could require that the collection is not already at full capacity. These can be expressed in pseudocode as assertions checked at entry:precondition array_access(index):
require index >= 0 and index < array.length
// Routine body proceeds only if true
precondition array_access(index):
require index >= 0 and index < array.length
// Routine body proceeds only if true
precondition insert(element):
require collection.size < collection.capacity
// Routine body proceeds only if true
precondition insert(element):
require collection.size < collection.capacity
// Routine body proceeds only if true
Postconditions
Postconditions in Design by Contract represent the obligations of a subroutine to its caller, consisting of boolean expressions that must evaluate to true upon the subroutine's completion, assuming the preconditions have been satisfied. These expressions define the expected outcomes, including return values, modified states, and any side effects, thereby establishing clear guarantees about what the subroutine achieves.[1] In practice, postconditions are often expressed using language-specific syntax, such as theensure clause in Eiffel, where multiple assertions can be combined to specify various properties of the resulting state. For instance, in a routine that inserts an element into a table, postconditions might ensure that the table's size increases by one, the inserted element is retrievable via its key, and no other elements have been altered. If a postcondition fails during runtime checking, an exception is raised to signal the contract violation, allowing the caller to handle the failure appropriately and attributing responsibility to the subroutine's implementation. Some formulations explicitly include exception handling by stating that the postcondition holds or an exception has been raised, accommodating cases where the subroutine cannot fulfill its guarantees due to unforeseen errors.[1][1]
A representative example is a sorting subroutine, where the postcondition guarantees that the output array is sorted in non-decreasing order and contains exactly the same elements as the input, preserving the multiset of values. This can be illustrated in pseudocode as follows:
procedure sort(input: array of comparable elements) returns sorted_array
require: input is non-null and elements are comparable
// Implementation of sorting algorithm (e.g., quicksort)
ensure: forall i from 0 to length(sorted_array)-2: sorted_array[i] <= sorted_array[i+1]
ensure: multiset(sorted_array) == multiset(input)
procedure sort(input: array of comparable elements) returns sorted_array
require: input is non-null and elements are comparable
// Implementation of sorting algorithm (e.g., quicksort)
ensure: forall i from 0 to length(sorted_array)-2: sorted_array[i] <= sorted_array[i+1]
ensure: multiset(sorted_array) == multiset(input)
Class Invariants
Class invariants in Design by Contract represent boolean properties that must hold true for every instance of a class at all times when the object is in a stable state, ensuring the consistency and reliability of the object's internal representation. These invariants encapsulate the essential constraints on the class's data, promoting encapsulation by hiding implementation details while guaranteeing that the object's state remains valid throughout its lifecycle.[6][7] The scope of class invariants extends to key points in an object's lifecycle: they must be established upon object creation, preserved between calls to public (exported) routines, and verified after the execution of such routines, as well as upon object destruction if applicable. Private routines inherit the invariant as an implicit obligation but do not explicitly check or enforce it at their boundaries, allowing internal operations flexibility while relying on the enclosing public routines to maintain overall consistency. This selective enforcement applies specifically to public operations, where the invariant is conjoined with the routine's precondition before entry and with its postcondition after exit.[6][8] A representative example is a bank account class, where the invariant ensures the balance never falls below the negative of the credit limit, preventing invalid financial states. In pseudocode inspired by Eiffel's syntax, the invariant might be declared as follows:class ACCOUNT
attribute
balance: INTEGER
credit_limit: INTEGER
invariant
credit_limit >= 0
balance >= -credit_limit
create
make (initial_balance: INTEGER; limit: INTEGER)
-- Establish initial state satisfying invariant
do
balance := initial_balance
credit_limit := limit
ensure
balance = initial_balance
credit_limit = limit
end
routine
withdraw (amount: INTEGER)
-- Reduce balance by amount, preserving invariant
require
amount > 0
balance - amount >= -credit_limit -- Temporary precondition check
do
balance := balance - amount
ensure
balance = old balance - amount
end
end
class ACCOUNT
attribute
balance: INTEGER
credit_limit: INTEGER
invariant
credit_limit >= 0
balance >= -credit_limit
create
make (initial_balance: INTEGER; limit: INTEGER)
-- Establish initial state satisfying invariant
do
balance := initial_balance
credit_limit := limit
ensure
balance = initial_balance
credit_limit = limit
end
routine
withdraw (amount: INTEGER)
-- Reduce balance by amount, preserving invariant
require
amount > 0
balance - amount >= -credit_limit -- Temporary precondition check
do
balance := balance - amount
ensure
balance = old balance - amount
end
end
withdraw routine, confirming balance >= -credit_limit holds.[8]
In object-oriented inheritance, class invariants propagate from parent to child classes through logical conjunction, requiring subclasses to satisfy both their own invariants and those of their ancestors. Subclasses may strengthen the inherited invariant by adding more restrictive conditions but cannot weaken it, ensuring behavioral compatibility and preventing violations of the parent's contract in derived types. For instance, a base TREE class might invariant that a child's parent references the tree root, which a subclass BINARY_TREE inherits and potentially augments with constraints on left and right children.[6]
Class invariants subsume and contextualize preconditions and postconditions by providing a persistent framework for the entire class state, where routine-specific assertions operate within the bounds of the invariant to maintain long-term object integrity across multiple operations.[6][7]
Historical Development
Origins with Bertrand Meyer
Bertrand Meyer, a French computer scientist and software engineer, originated the Design by Contract (DbC) methodology as a foundational principle for reliable software construction, deeply influenced by advancements in formal methods and software engineering during the late 20th century.[1] His approach emphasized specifying clear obligations for software components through assertions, drawing inspiration from the systematic program verification techniques pioneered by Edsger W. Dijkstra and C.A.R. Hoare.[1] Dijkstra's work on structured programming and disciplined development, as outlined in his 1976 book A Discipline of Programming, provided a framework for rigorous program design that Meyer extended to object-oriented contexts.[1] Similarly, Hoare's axiomatic semantics, introduced in his 1969 paper "An Axiomatic Basis for Computer Programming," supplied the theoretical basis for preconditions, postconditions, and invariants, which Meyer adapted to enforce contractual guarantees in software modules.[1] Meyer first formally described Design by Contract in 1986, in the technical report Design by Contract (TR-EI-12/CO), published by Interactive Software Engineering Inc. as part of the design specifications for the Eiffel programming language.[9] This introduction coincided with the development of Eiffel, which Meyer conceived in 1985 to promote object-oriented programming with built-in support for reliability mechanisms.[10] The methodology emerged amid growing concerns over software reliability in the 1980s, a period marked by high-profile failures in complex systems that highlighted the limitations of ad-hoc debugging and testing practices.[1] By integrating DbC into Eiffel's syntax and semantics, Meyer aimed to shift software development toward a more verifiable and maintainable paradigm, where errors could be anticipated and localized through explicit specifications rather than discovered post-deployment. Central to Meyer's innovation was the business contract metaphor, which analogized software interactions to legal agreements between parties, imposing mutual responsibilities on callers and callees in a subroutine or method.[1] In this model, a client (the calling code) must satisfy preconditions to invoke a supplier (the routine), while the supplier guarantees postconditions upon successful execution, fostering accountability and reducing ambiguity in component interfaces.[10] This analogy not only clarified the division of labor in software design but also aligned with formal verification principles, enabling developers to treat assertions as enforceable clauses that could detect violations at runtime.[1] In recognition of its significance, "Design by Contract" was registered as a trademark by Eiffel Software in December 2004, following an application in December 2003, underscoring its proprietary role in the Eiffel ecosystem.[10]Evolution and Standardization
Following its introduction in the Eiffel programming language in the 1980s, Design by Contract (DbC) saw significant adoption in other languages during the 1990s, particularly through academic research and extensions that integrated it with object-oriented paradigms. Researchers explored DbC's application beyond Eiffel, influencing languages like Java, where assertions were added in Java 1.4 (2002) to support lightweight contract checking, though full DbC required libraries such as JML (Java Modeling Language).[6] In parallel, DbC principles began shaping broader methodologies; by the late 1990s, it contributed to formal methods by providing a practical bridge between rigorous specification and implementation, as seen in extensions to Hoare logic for runtime verification. Its influence extended to agile practices in the 2000s, where DbC was combined with test-driven development (TDD) to form specification-driven development, enabling iterative refinement of contracts alongside code.[11] Standardization efforts solidified DbC's role in the 2000s and 2010s. The Eiffel language, central to DbC, was formalized as ISO/IEC 25436:2006, which explicitly incorporates contract mechanisms like preconditions, postconditions, and invariants as core elements of the language standard. Similarly, Ada's 2012 ISO standard (ISO/IEC 8652:2012) introduced native support for preconditions and postconditions, marking a milestone in embedding DbC into a widely used systems programming language for safety-critical applications. Proposals for C++ followed, with contracts initially targeted for C++20 but deferred; by 2025, the P2900 proposal for a minimal viable product of contracts—covering preconditions, postconditions, and assertions—was advanced into the C++26 working draft at the February 2025 ISO C++ committee meeting, with ratification expected in 2026. Key milestones in the 2020s reflect growing library and native integrations. In Python, libraries likedeal emerged around 2020 to provide DbC decorators for runtime checks, while a March 2025 Python Enhancement Proposal discussion advocated for native class invariants to enhance built-in support.[12][13] Scala, building on its functional-object hybrid nature, incorporated contract features through libraries like ScalaCheck in the early 2020s. These developments underscore DbC's evolution from a niche Eiffel feature to a cross-language methodology, influencing both formal verification tools and agile workflows without native implementations dominating adoption.
Language Implementation
Native Language Support
Eiffel was the first programming language to provide full native support for design by contract, with its initial implementation available since early 1986.[14] The language includes dedicated keywords for specifying preconditions (require), postconditions (ensure), and class invariants (invariant), enabling runtime assertion checking by default, though compile-time verification is also possible via tools like AutoProof.[15] For example, a routine might be defined as:
feature
divide (numerator, denominator: REAL): REAL
require
denominator_not_zero: denominator /= 0.0
do
Result := numerator / denominator
ensure
correct_result: Result = numerator / old denominator
end
feature
divide (numerator, denominator: REAL): REAL
require
denominator_not_zero: denominator /= 0.0
do
Result := numerator / denominator
ensure
correct_result: Result = numerator / old denominator
end
Pre), postconditions (Post), type invariants, and subtype predicates.[4] These are specified in subprogram declarations using aspect clauses, with runtime checks enabled via compiler options such as GNAT's -gnata switch. For example:
function Square (A : Positive) return Positive with
Post => Square'Result > A;
function Square (A : Positive) return Positive with
Post => Square'Result > A;
Square exceeds the input A. Ada's contracts align closely with the DbC model and are particularly used in safety-critical systems.[4]
The D programming language offers built-in contract programming through language constructs for preconditions, postconditions, and invariants, integrated since its initial design.[16] These are specified using attributes like in for preconditions and out for postconditions, with runtime evaluation enabled via compiler flags (-checkaction=context for halting on violation).[16] Compile-time checks occur where feasible, such as for constant expressions. An example function contract appears as:
int divide(int numerator, int denominator)
in
{
assert(denominator != 0);
}
out(result; // can use 'result' to refer to return value
{
assert(result * denominator == numerator);
}
do
{
return numerator / denominator;
}
int divide(int numerator, int denominator)
in
{
assert(denominator != 0);
}
out(result; // can use 'result' to refer to return value
{
assert(result * denominator == numerator);
}
do
{
return numerator / denominator;
}
require and ensure within methods, as in:
method Divide(numerator, denominator: [Single): Single](/page/Single_&_Single);
require
DenominatorNotZero = denominator <> 0;
ensure
CorrectResult = result = numerator / denominator;
begin
result := numerator / denominator;
end;
method Divide(numerator, denominator: [Single): Single](/page/Single_&_Single);
require
DenominatorNotZero = denominator <> 0;
ensure
CorrectResult = result = numerator / denominator;
begin
result := numerator / denominator;
end;
[[expects]] for preconditions and [[ensures]] for postconditions, supporting runtime checking via compiler options while allowing future compile-time analysis.[21] For instance:
int divide(int numerator, int denominator)
[[expects: denominator != 0]]
[[ensures: result * denominator == numerator]]
{
return numerator / denominator;
}
int divide(int numerator, int denominator)
[[expects: denominator != 0]]
[[ensures: result * denominator == numerator]]
{
return numerator / denominator;
}
Library and Framework Support
In languages without native support for design by contract (DbC), third-party libraries and frameworks provide mechanisms to implement preconditions, postconditions, and invariants through annotations, decorators, or bytecode instrumentation, enabling DbC without requiring changes to the compiler or runtime environment.[23] These tools facilitate adoption in legacy codebases and promote defensive programming practices by integrating contract checks at runtime or compile time. For C++, the Boost.Contract library offers comprehensive DbC support, including subcontracting, class invariants (including static and volatile variants), and postconditions that access old values and return results.[24] It uses macros and lambda expressions to define contracts, allowing customizable failure handling such as throwing exceptions or terminating execution. A simple example demonstrates precondition and postcondition checks for an increment function:#include <boost/contract.hpp>
#include <limits>
void inc(int& x) {
boost::contract::old_ptr<int> old_x = BOOST_CONTRACT_OLDOF(x);
boost::contract::check c = boost::contract::function()
.precondition([&] { BOOST_CONTRACT_ASSERT(x < std::numeric_limits<int>::max()); })
.postcondition([&] { BOOST_CONTRACT_ASSERT(x == *old_x + 1); });
++x;
}
#include <boost/contract.hpp>
#include <limits>
void inc(int& x) {
boost::contract::old_ptr<int> old_x = BOOST_CONTRACT_OLDOF(x);
boost::contract::check c = boost::contract::function()
.precondition([&] { BOOST_CONTRACT_ASSERT(x < std::numeric_limits<int>::max()); })
.postcondition([&] { BOOST_CONTRACT_ASSERT(x == *old_x + 1); });
++x;
}
x is not at its maximum before incrementing and verifies it increased by 1 afterward.[24]
In Java, historical libraries like jContractor (introduced in 2005) and Contract4J5 (last updated 2009, now dormant) enabled DbC via reflective bytecode instrumentation and annotations, respectively, supporting contract inheritance where subclasses can weaken preconditions and strengthen postconditions.[25] jContractor uses standard Java methods following a naming convention (e.g., pre_myMethod()) for contracts, which are instrumented at class loading to enforce runtime checks without modifying source code.[25] Contract4J5 leverages Java 5 annotations and AspectJ for weaving contract logic, marking classes with @Contract and methods with @Pre, @Post, or @Invar. An example from Contract4J5 illustrates invariant and precondition enforcement:
import com.contract4j5.Contract;
import com.contract4j5.Pre;
import com.contract4j5.[Invar](/page/Invar);
@Contract
public class MyClass {
@[Invar](/page/Invar)("name != null")
private String name;
@Pre("n != null")
public void setName(String n) {
name = n;
}
@Post("$return != null")
public String getName() {
return name;
}
}
import com.contract4j5.Contract;
import com.contract4j5.Pre;
import com.contract4j5.[Invar](/page/Invar);
@Contract
public class MyClass {
@[Invar](/page/Invar)("name != null")
private String name;
@Pre("n != null")
public void setName(String n) {
name = n;
}
@Post("$return != null")
public String getName() {
return name;
}
}
name field remains non-null as an invariant and rejects null inputs to setName. More recent efforts include projects like C4J, but adoption remains limited.[26]
For Python, PyContracts (last updated around 2020) provides decorator-based DbC with a domain-specific language for constraints, supporting type checking, arithmetic conditions, and variable binding in function annotations or docstrings.[27] It allows disabling checks in production for zero overhead and includes specialized support for libraries like NumPy. Contracts are specified using the @contract decorator, as in this matrix multiplication example:
import numpy
from contracts import contract
@contract
def matrix_multiply(a, b):
'''Multiplies two matrices together.
:param a: The first matrix. Must be a 2D [array](/page/Array).
:type a: array[MxN],M>0,N>0
:param b: The second matrix. Must be of compatible dimensions.
:type b: array[NxP],P>0
:rtype: array[MxP]
'''
return numpy.dot(a, b)
import numpy
from contracts import contract
@contract
def matrix_multiply(a, b):
'''Multiplies two matrices together.
:param a: The first matrix. Must be a 2D [array](/page/Array).
:type a: array[MxN],M>0,N>0
:param b: The second matrix. Must be of compatible dimensions.
:type b: array[NxP],P>0
:rtype: array[MxP]
'''
return numpy.dot(a, b)
a and b are compatible 2D arrays with positive dimensions and ensures the result is a valid MxP array. As of 2025, proposals for native DbC support in Python, such as class invariants, are under discussion.[28][13]
Microsoft's Code Contracts framework for .NET languages like C# extends DbC support to interoperable scenarios, such as C++/CLI wrappers, by specifying contracts via attributes and static analysis tools that rewrite code for runtime verification.[29] This allows .NET assemblies to enforce preconditions and invariants across managed and native boundaries without full recompilation.
For JavaScript and TypeScript, the Decorator Contracts library by Michael Haufe, published in mid-2025, provides a comprehensive implementation of Design by Contract support using decorators, serving as a superior and actively maintained alternative to earlier tools.[30] It targets web applications where native support is absent, enforcing preconditions via @demands, postconditions via @ensures, and class invariants via @invariant, while supporting principles such as the Liskov substitution principle through subcontracting and a Contracted base class with Proxy-based enforcement. The library includes a checked mode for runtime toggling of contract verification, ensuring low overhead in production. At version 1.0.0 as of 2026, it remains current and feature-rich. An example demonstrates contract enforcement for a simple Stack class:
import { demands, ensures, invariant } from '@final-hill/decorator-contracts';
class Stack {
@invariant('this.items.length >= 0')
constructor() {
this.items = [];
}
@demands('item !== undefined')
@ensures('this.items.length === __old__.items.length + 1')
push(item) {
this.items.push(item);
}
}
import { demands, ensures, invariant } from '@final-hill/decorator-contracts';
class Stack {
@invariant('this.items.length >= 0')
constructor() {
this.items = [];
}
@demands('item !== undefined')
@ensures('this.items.length === __old__.items.length + 1')
push(item) {
this.items.push(item);
}
}