Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which contract (Design by contract) is better?

Suppose I have a method

public Patient(int id)
{
    ----
}

that returns Patient object given an id.. I could define contract in 2 ways

  1. Method would return null if patient does not exist
  2. Method would throw an exception if patient does not exist. In this case I would also define a query method that returns true if the Patient exist in the database or false otherwise...

Which contract should I use? Any other suggestions?

Update: Please comment on this case too... If it is not an database assigned Id and it is something a user enter in UI.. like SSN .. then which one is better..

Comment about Null pattern from Steve that I think is valid: probably not a good idea here, as it would be really useful to know immediately when an ID did not exist.

And I also think Null pattern here would be somewhat heavy weight

Comment from Rob Wells on throwing exception because its bad Id: i don't think a typo in a patient's name is an exceptional circumstance" IMHO

like image 326
StackUnderflow Avatar asked Jan 05 '09 19:01

StackUnderflow


People also ask

What is the best contract type?

Fixed Price Contracts. This is the best contract type when someone knows exactly what the scope of work is. Also known as a lump sum contract, this contract is the best way to keep costs low when you can predict the scope.

Which contract type is the best for buyers?

A time and materials contract is great for buyers who don't necessarily know what they want when they begin their project. Sellers use time and materials contracts when it's difficult to determine the amount of time they need to spend on the project and the types of materials required to complete the project.

Why is design by contract useful?

DbC assists engineers clarify whether a caller or a callee should take charge of fixing a defect. DbC declares what should be met by a client (caller) in pre-conditions, what should be met by a supplier (callee) in post-conditions and what is forever true in all conditions.


2 Answers

Keep in mind that going "over the wire" to another tier (whether a database or an application server) is one of the most expensive activities you can do - typically a network call will take several orders of magnitude longer than in-memory calls.

It's therefore worth while structuring your API to avoid redundant calls.

Consider, if your API is like this:

// Check to see if a given patient exists
public bool PatientExists(int id);

// Load the specified patient; throws exception if not found
public Patient GetPatient(int id);

Then you are likely to hit the database twice - or to be reliant on good caching to avoid this.

Another consideration is this: In some places your code may have a "known-good" id, in other places not. Each location requires a different policy on whether an exception should be thrown.

Here's a pattern that I've used to good effect in the past - have two methods:

// Load the specified patient; throws exception if not found
public Patient GetExistingPatient(int id);

// Search for the specified patient; returns null if not found
public Patient FindPatient(int id);

Clearly, GetExistingPatient() can be built by calling FindPatient().

This allows your calling code to get the appropriate behaviour, throwing an exception if something has gone wrong, and avoiding exception handling in cases where it is not needed.

like image 193
Bevan Avatar answered Oct 31 '22 19:10

Bevan


Another option would be the Null Object pattern.

like image 45
Chris Shaffer Avatar answered Oct 31 '22 17:10

Chris Shaffer