« Three Blogs? No way. | Main | Pomopro - the 1st International Conference on Post-Modern Programming »

September 04, 2006

Comments

jerith

"""
DateRange vacation = new DateRange(startingDate);
vacation.addWeek();
vacation.addDay();
"""

You've actually just moved the preconditions. You still need to check that addWeek() and addDay() only take positive arguments. Sure, you can abs() them, but that breaks expectations. What if you want to be able to reduce the range as well? You're back to checking preconditions. If you're requiring a positive range, you could just take the first and abs() the difference between the two dates.

I'm not disagreeing with your general point, just your example. It isn't as easy as it looks...

Alex

If you want strong static guarantees in your code, you should really look into a more expressive statically-typed language. Ocaml and Haskell are likely candidates.

shaurz

A shame Java doesn't have unsigned ints, eh?

I agree with the principle. The same can be said for the design of file formats.

Michael Feathers

> You've actually just moved the preconditions. You still need to check that addWeek() and addDay() only take positive arguments.

No, they don't take any arguments at all; addWeek just adds one week. So yes, it's possible to remove the precondition entirely in this case, but like I said in the blog, it would be funky.

Bob Evans

Actually, now someone can construct date ranges that are not really date ranges anymore, just starting dates. So, it is not only funky, but it still begs the question of what do you do when you're committed.

Perhaps a static creation method, along the lines of createDateRangeFromTo(start, end)?

Then you can say,

DateRange vacation = DateRange.createDateRangeFromTo("Aug/01/2006", "Aug/15/2006");

Michael Feathers

Bob: "Actually, now someone can construct date ranges that are not really date ranges anymore, just starting dates."

Michael: I guess that gets down to the question of whether an empty range is a range. It could be defined that way, and I've seen that in problems similar to this one.

Bob: "So, it is not only funky, but it still begs the question of what do you do when you're committed. Perhaps a static creation method, along the lines of createDateRangeFromTo(start, end)?"

Michael: I like the name. It definitely helps, but the precondition is still there. It's still possible to pass an end that occurs before the start, and when that happens at runtime you have to decide what to do. I've seen systems which treat intervals with (end < start) as empty intervals. They allow an error just to keep the system running. Not pretty, and definitely domain-specific. In any case, I just wanted to show how preconditions can be eliminated at times. Many people just assume that they are fixed.

keith ray

Make the normal "constructor" actually be a factory function in Date. Yeah, I know Java doesn't allow adding methods to existing classes, but Objective-C, Smalltalk, Ruby, and some other languages do.

DateRange range2daysInJan = Date( "Jan 01, 2006" ).rangeTo( Date( "Jan 02, 2006" ) );

Seems like in this case, we could also not care what order the dates come in:

DateRange same2daysInJan = Date( "Jan 02, 2006" ).rangeTo( Date( "Jan 01, 2006" ) );

assertEqual( range2daysInJan, same2daysInJan );

wonk

I think you should have worked a little harder and made a working example rather than a clearly silly example.

Jason Gorman

I'm confused, Michael. The code in your example appears to be doing something different.

Mark Grant

This article is spot on, because Java is imperative the constraint/relationship between a start and an end date is specified as a pre-condition. I the concept of removing pre-conditions makes sense, but its still impossible to remove null arguments.

Try the following:

TimeDuration duration = New TimeDuration(unitsOftime);
DateRange vacation = New DateRange(startingDate, duration);

as a duration is a size we don't care if it is positive or negative (we just make it positive), and by creating the duration prior to the daterange we don't need to "inflate" it.

The comments to this entry are closed.