Fundamentals 8 min read

Defensive Programming vs Contract Programming: Handling Unexpected Data in Software Development

The article explores defensive programming and contract programming, discussing how to handle unexpected JSON data, the role of assertions and exceptions, and the trade‑offs between strict error handling and contractual code design for building robust software.

Qunar Tech Salon
Qunar Tech Salon
Qunar Tech Salon
Defensive Programming vs Contract Programming: Handling Unexpected Data in Software Development

Author

Xu Yisheng works in the Android development team at Shanghai Hujiang Net, writes technical blogs on CSDN, and is an author of Android books.

Background

The discussion starts with a common scenario: a JSON response is expected to be either a valid format or empty, but sometimes an unexpected value is returned. Developers debate whether the program should tolerate such anomalies internally or propagate an error, illustrating the classic dilemma between NullPointerException handling and explicit null checks.

Defensive Programming

Inspired by a passage from "Code Complete", defensive programming is defined as assuming that humans are unreliable and that code must anticipate all possible errors so that a program does not fail because of others' mistakes. It emphasizes checking inputs (e.g., division by zero) and using assertions or exceptions for error handling.

Assertions

Assertions are development‑time checks that cause the program to abort when a condition is false. They are meant for debugging and are typically removed in production; the paradox is that while defensive programming advocates compatibility, assertions cause immediate termination.

Exceptions

Exceptions allow a program to signal an error to the caller. If the caller cannot handle it, the exception propagates outward. Overusing try‑catch everywhere is discouraged, as it indicates a lack of trust in the code.

Contract Programming

Contract programming introduces preconditions, postconditions, and invariants that each party must satisfy. Violating a contract (e.g., passing a null where non‑null is required) should cause the contract to break, assigning responsibility to the caller. Modern languages like Swift support such constraints, and the approach aligns with interface‑oriented design.

Utopia

In an ideal world, both defensive and contract programming would be fully adopted, but practical constraints (cross‑team communication, interface mismatches) make it difficult. The author suggests promoting contract programming at the organizational level to improve efficiency and trust, while retaining necessary defensive checks for robustness.

Warning

Readers are encouraged to adopt a defensive reading mindset, acknowledge that everyone makes mistakes, and engage in discussion.

software engineeringerror handlingcontract programmingdefensive programmingAssertions
Qunar Tech Salon
Written by

Qunar Tech Salon

Qunar Tech Salon is a learning and exchange platform for Qunar engineers and industry peers. We share cutting-edge technology trends and topics, providing a free platform for mid-to-senior technical professionals to exchange and learn.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.