4 ms·
So say you replace it with a DateRange class so you end up with range1 = new DateRange(start1, end1); range2 = new DateRange(start2, end2); DateRange overlap
by JamesBarney 7y ago
So say you replace it with a DateRange class so you end up with
range1 = new DateRange(start1, end1);
range2 = new DateRange(start2, end2);
DateRange overlapRange = GetOverlap(range1, range2);
You still don't know what happens when start1 is greater than end1?
What happens when they have no overlap? What does overlap return if it doesn't return null?
What happens if start1 and end1 are in local vs UTC time?
What happens if range1 and range 2 are in local vs UTC time?
When you get overlapRange.Duration.Days is this days in 24 hr increments or days by date?
And this is a really simple example. Things like ORMs are very leaky abstractions which make this mcuh worse.
- lmm 7y ago> You still don't know what happens when start1 is greater than end1? That's DateRange's responsibility, it's not a concern for getOverlap. By the time you get as far as getOverlap you already have a valid DateRange. Small, reusable, compositional pieces. > What happens when they have no overlap? What does overlap return if it doesn't return null? It can't "return null", we're talking about using a decent type system here. The types should express what kind of failures are possible, so perhaps getOverlap returns a maybe, or an either where the left hand side is some structured "reason" value that expresses what went wrong. > What happens if start1 and end1 are in local vs UTC time? You get a compilation error because that distinction is part of the type. > What happens if range1 and range 2 are in local vs UTC time? You get a compilation error because that distinction is part of the type. > When you get overlapRange.Duration. Days is this days in 24 hr increments or days by date? That's Duration's responsibility, not getOverlap's; again, small, reusable, compositional pieces. You shouldn't ever be calling overlapRange.duration.days (obvious law of demeter violation); rather you should be calling something that can do the right thing with overlapRange.duration (e.g. display it, compare whether it's longer than some limit). But to answer the question: check its type, that will tell you. Any value that you actually pass around and use in business logic should have a type that tells you what kind of thing it is; primitives should only ever be used within the very lowest level functions.
- marcosdumay 7y agoJust to add to lmm's comment: > What happens when they have no overlap? You get the empty range. Because any sane modeling of a range will have an empty value for completeness, and modeling it without those overlaps and date specialization clobbering your screen will make it patently obvious wether your type is complete or not. And if you still forgot to include the empty value, you won't be able to write the overlap function, so you will have to go back.