Simplify the simple

Simple things should be simple. That’s easier said than done in a language like Objective-C. Sometimes things that are in fact simple look difficult just because of the syntax.

##Problem

I often prefer to override my getters to lazy load objects the moment they are actually required as opposed to setting up everything in init* methods. This also cleans up any init* methods by removing a chunk of boiler plate nothingness. This can get a bit hairy, consider (read: skim) the following example - the content here is really not important

- (NSCalendar *)calendar;
{
  if (!_calendar) {
    _calendar = [NSCalendar currentCalendar];
  }
  return _calendar;
}

- (NSTimeZone *)timeZone;
{
  if (!_timeZone) {
    _timeZone = [[NSTimeZone alloc] initWithName:@"GMT"];
  }
  return _timeZone;
}

- (NSDate *)minimumDate;
{
  if (!_minimumDate) {
    _minimumDate = [[NSDate alloc] initWithTimeIntervalSince1970:0];
  }
  return _minimumDate;
}

- (NSDate *)maximumDate;
{
  if (!_maximumDate) {
    _maximumDate = [[NSDate alloc] initWithTimeIntervalSince1970:MAXFLOAT];
  }
  return _maximumDate;
}

The above code looks like it is doing more than it actually is because of the if statements and all of the vertical space it consumes. This kind of code generally causes me to do a quick double take to skim the code to make sure it really is only lazy loading objects. When I have to do a double take it generally means I will make a mistake at some point later on so I prefer to avoid them if at all possible. It is also quite likely that a double take can knock me off my train of thought by taking unnecessary detours - I can only hold so much in my brain at once.

##Solution

I tend to hide this all at the bottom of a class below a #pragma mark - Properties. That’s enough to flip the bit in my head that says expect this kind of boiler plate code.

##Is that enough?

I don’t think it is, the code is still big bulky and annoying to look at. Granted I could not be so stubborn and transform the if statements into one liners but that would break my coding conventions and cause more double takes. I like to keep my if statements consistent and always use curly braces to avoid any pain later on. This also helps readability as things are always how I expect them to be. If something can be more succinctly written with ternary syntax then I will favour that - if not it’s multi-line, curly brace goodness for me.

##Experimentation

So the current solution I am experimenting with on these simple cases is to use the ternary syntax to make the simple getters as simple as possible. With this the above is transformed into the slightly more compact and easy to read

- (NSCalendar *)calendar;
{
  return _calendar = _calendar ?: [NSCalendar currentCalendar];
}

- (NSTimeZone *)timeZone;
{
  return _timeZone = _timeZone ?: [[NSTimeZone alloc] initWithName:@"GMT"];
}

- (NSDate *)minimumDate;
{
  return _minimumDate = _minimumDate ?: [[NSDate alloc] initWithTimeIntervalSince1970:0];
}

- (NSDate *)maximumDate;
{
  return _maximumDate = _maximumDate ?: [[NSDate alloc] initWithTimeIntervalSince1970:MAXFLOAT];
}

The syntax seems like a familiar old friend for a Ruby fan and is pretty concise without much compromise. I have even managed to put this class on a diet and trim 12 lines in just this simple example. (Here’s the Ruby example)

def minimum_date
  @minimum_date ||= NSDate.alloc.initWithTimeIntervalSince1970 0
end

This doesn’t help me in cases where I want to lazy load and configure an object at the same time, but my goal here is to make simple things simple. Returning a simple object is pretty simple but configuring one is not. For objects that need configuration I can go back to the warmth of those cosy curly braces, I also get the added advantage of being able to determine which methods return simple objects and which methods do a little more heavy lifting with just a glance.

// Object instantiated and needs some additional configuration
- (NSDateFormatter *)dateFormatter;
{
  if (!_dateFormatter) {
    _dateFormatter = [[NSDateFormatter alloc] init];
    _dateFormatter.dateFormat = @"yyyy-mm-DD";
  }
  return _dateFormatter;
}

// Simple object instantiated and returned
- (NSCalendar *)calendar;
{
  return _calendar = _calendar ?: [NSCalendar currentCalendar];
}

Here I can push the simple getter further down the class to emphasise even more it’s status in the class.

##Conclusion

I am still only really toying with this syntax but I currently like the additional semantic information I can get by just glancing at the code. I can quickly see which getters lazy load a simple default value and which getters lazy load objects and involve a little more setup work. I can imagine that this syntax may present an initial double take to anyone who was working on my code base and had never come across this before but it has a considerably lower barrier to entry than design patterns that are employed all of the time in large projects.