Thursday, December 17, 2009

Loadtesting As Functional Testing

I'm a fan of automated testing that exercises code and checks its results.

But I don't believe in striving for 100 percent coverage. Should I really spend time writing unit tests that exercise our database interactions given that Hibernate, our ORM layer, is heavily tested and community-vetted? I create mock versions of the service layer we put on top of our ORM to allow testing of the service clients, but I don't (usually) write tests to exercise the services themselves.

This works out fine. Except when I need to do a big refactor in the service layer, as I did yesterday. I moved common functionality to a base class and used Java Generics [pdf] to define methods in the base class that would, in the context of the child class, compile as if they returned the type appropriate to that child class.

How could I ensure that I hadn't broken anything before checking in the code? I thought of our load testing scripts, which I've been diligent about maintaining. They do a full CRUD cycle on a variety of object types.

I didn't need to test load, but this would exercise virtually all the code I had changed. I brought them up, set the thread count to 1, pointed them at my machine, and pressed go. Sure enough, they uncovered a few bugs. I fixed them, re-ran the scripts, and they all passed.

Automated testing is good. No matter what form it's in.

Friday, December 11, 2009

Facebook's Puzzles

A co-worker of mine pointed me to Facebook's Puzzle Page, a suite of challenging puzzles. The puzzles exist to find skilled programmers that Facebook might like to hire by letting those programmers sift themselves out, rather than taxing Facebook employees' time with trying to find wheat in the chaff of job applicants who come through normal channels.

But even if you're not interested in working at Facebook, they're a nice set of programming challenges. Especially if you're learning a new language and want some meaty exercises.

Even as someone who has challenged interviewees with logic puzzles — a standard practice for software companies — I find these types of puzzles to be interesting but not necessarily useful in finding good hires. Yes, it helps you find the bright folks who can figure out clever algorithms.

But those aren't necessarily the people who make good software engineers. Software engineering is about delivering quality code on schedule and within the budget. It's about writing code that other people will be able to work with and maintain, even years later. It's about debugging, but it's also about exposing bugs as early as possible. It's about understanding trade-offs, risks, and benefits. I spend a very small percentage of my time sussing out clever algorithms: I spend a very large percentage figuring out how to deliver scalable, high-quality features in a cost-effective way.

Being a good puzzle solver doesn't preclude those skills, of course, but it doesn't point to them, either. Puzzles test that you're bright in one way; they don't tell your employer if you can actually do your job.

On the other hand, Facebook is no doubt swamped with would-be employees, so these puzzles offer a way for someone to prove that they can be internally motivated (the only effective form of motivation) and self-starting. And they do test for one sort of programming intelligence. And, finally, I haven't yet figured out a way to test for the kind of programmer I look for, other than interviewing people.

Wednesday, December 9, 2009

Learning Ruby

Recently, I decided to learn Ruby, the programming language du jour of Internet startups.

The main reason was an essay in The Thoughtworks Anthology, a collection of essays about software development from some of my field's luminaries. The essay argued for polyglot programming, especially since the Java Virtual Machine enjoys wide distribution; a mature, scalable implementation; and a number of languages that compile down to Java bytecode. It showed a typical "isBlank" method in Java and an implementation in Ruby (in particular, JRuby) that was one-third the length and much more readable. The end result: code that's easier to maintain overall.

There were a few other reasons. If I'm laid off, Ruby knowledge would be a good resume item. I'm also drawn to the language's "Behavior Driven Development" testing tools Cucumber and RSpec, which a co-worker showed me. But the Thoughtworks essay was the catalyst.

I bought the "pickaxe" book and dug in.

As I've said before, I have a standard programming project I assign myself when I'm learning a new language: a solver for various types of word puzzles that you'd find in the monthly publication of the National Puzzlers' League. By the end of writing it, I have a good sense of the language's syntax, I've dug into the established class library a bit, and I've even learned something about performance: The dictionary I use is 838,000 lines, which means that I often have to optimize the code that runs in the loop over those lines.

I got my program up and running pretty quickly, and it's easy to see why people like Ruby. Even complicated tasks come together in some form pretty quickly in a much less verbose form than they would in, say, Java. I like that the language includes mixins, a way to fake multiple inheritance, and I like that you can add behavior to an existing class (which you can also do in Objective-C via categories) without subclassing it. I added a method to the String class with no effort.

And, though I haven't tried this yet, Ruby can plug in to the Open Scripting Architecture (do they still call it that?) on Mac OS X so you can control your applications via a Ruby script. At this stage in my life, I'd prefer writing a Ruby script to writing something in AppleScript.

Next, I'll try and put up a simple Ruby on Rails app. I haven't fully embraced Ruby as the one true path, but it's definitely a worthwhile addition to your programming toolkit.

Sunday, November 29, 2009

Knowledge Creates Possibilities

When I first left college 16 years ago — a bio major with a head for computers — I worked for Bank of America. I helped design software for a lucrative trading desk. One of the strongest memories I have from that time is showing a piece of software to the head of the trading desk, a tall, nervous, white-haired man who stuttered when his thoughts outpaced his ability to voice them. My boss and I had taken his requirements and created software that met them. He looked at the software and said, "That's nice. I wonder: Could it do this, too?"

I don't remember what the "this" was, but it wasn't a feature he had originally mentioned. This happened again. And again. And again. Couldn't he just tell us what he wanted the first time around? It took me a year or so to realize what was happening: He couldn't define the features he wanted because he didn't know what was possible. Once he saw one feature, it expanded his horizon of what was doable, and he could then make the mental leap to bigger, and ultimately better, feature ideas.

It may be the most important thing I learned on that job.

It's certainly one reason that Agile programming made sense to me when I first learned about it: The mindset urges you to get functional software in front of customers as early as possible so that they can give feedback. The stated reason for this idea is that customers can tell you what's important and get what they want. I have always added a mental note: It also lets them know what's possible.

But there's no line between users and developers here. I think everyone works this way. Well, everyone except those few people who are truly visionaries.

A co-worker and I are both prototyping features that require APIs. Being modern web programmers, we're building them as RESTful APIs. REST simply means that you present data organized hierarchically by "nouns," or resources (compare flickr.com/photos and flickr.com/photos/melissanicole, for instance). You typically present it as XML or JSON via HTTP so that even inexperienced programmers can retrieve the data and parse it.

He showed me a page he had set up at the top level of his API. It didn't reference any particular resource. Instead, it presented a list of all the calls in the API. I thought it was a good idea: Rather than have the documentation in some separate place, he had put it right in front of the user. At the time, he was updating this manually. I've maintained API documents before, and it's a pain in the ass.

But seeing his page, I realized that I could generate a similar page by having the system itself analyze its own internals. Look at all the request mappings you've set up, see which ones are under the path for your API calls, and add them to the page. Voila! Documentation that keeps itself up to date. (See below if you want some of the details.)

It took some effort. I dug around in Spring code, read through tips on forums, and yelled at my computer. But by the end of the day, I had a page of API documentation, in the normal format of the API, that I would never have to maintain or remember to update. New API calls would get added without me thinking about it. A simple annotation on the method that handles the request gives a human-readable definition of what the call does. (I also added an exclude capability for calls that we don't want to expose.) You could argue that the time I spent on this feature was greater than the time I would spend maintaining the documentation. That may be true.

But a week later, I had an epiphany.

As I've said, I'm experimenting with the idea of having load testing scripts that run early and often for new features. To that end, I had a JMeter script where I manually added the API calls as I added them to the system.

See the problem?

What if I could make a load testing script that would hit that top-level page and use it to figure out all the other calls that were possible? I'd have a script that would, with no maintenance on my part, load test every API call as I added it.

Or when someone else added one. They wouldn't even have to know about the load testing script, and their call would get load tested.

It took a bit of digging in JMeter's sparse documentation, but I got it working after a few hours. I add an API call, it shows up in the generated documentation page, and then the loadtesting script picks it up. Beyond my initial excitement of seeing the flow work, I stopped thinking about it. (Again, see below for some tips.)

I felt like the head of the trading desk from all those years ago. I didn't start with a vision of a load testing script that would dynamically adjust itself. But when I implemented one feature, that script came into view. And now I will always see it as a possibility, and that knowledge will create new possibilities I can't see today.

A Self-Documenting API
I'm using Spring 3.0 as a framework, and that's what made this work. If you're in the same boat, there are a few things that will frustrate you along the way.

You'll want a reference to the DefaultAnnotationHandlerMapping object that Spring maintains. However, you can't autowire a reference into your class, because Spring doesn't, by default, register the DefaultAnnotationHandlerMapping as a bean. But you can create a bean of your own for that class, and then it will work. (Note that you'll probably want to Autowire for an array of AbstractUrlHandlerMapping objects, in case you add more down the road.)

DefaultAnnotationHandlerMapping will give you a map of all the request mappings in your system, but the values in that map are controllers, not methods. You'll have to use reflection to go through all the methods in the class and figure out which ones actually have the @RequestMapping annotation for the given request mapping.

On that note, keep in mind that you may actually be getting a CGLIB proxy for the controller, so you'll need to get the actual class name in order to use reflection.

A Self-Discovering Load Testing Script

Because my API documentation page returns its results in XML, I was able to use JMeter's XPath Extractor to derive all the URLs to hit. Couple that with a ForEach controller, and you've got a loop that will iterate over each URL in the document. Put an Http Request Sampler in that loop, set the path field to the iteration variable created by the controller, and you're hitting whatever the current URL is. That's the basic format.

Spring's request mapping syntax looks something like /foo/bar/{id}, where {id} gets replaced at request time by whatever's in that space. (This is, incidentally, an awesome feature.) But /foo/bar/{id} is not a useful URL. I wrote a preprocessor for the Http Request Sampler that replaces {id} with some other value. You may be clever enough to do it with a Regex preprocessor; I did it with a BeanShell script that takes the current path — /foo/bar/{id} — and transforms it to /foo/bar/1234. Then it puts that value into a new variable called correctedPath.

JMeter allows you to use variables in the name field for a component. This is very useful. If you leave the sampler's name as Http Request Sampler, every single URL will get put in the "Http Request Sampler" test name, which will make your load testing reports useless. If you set the sampler's name to — using the above example — ${correctedPath}, the test name will get set to /foo/bar/1234, and each discovered URL will get its own line item in your report.

Sunday, November 15, 2009

Learning JMeter

At work recently, I set up automated load testing for some new features I'm working on. There are teams within EA that do large-scale load testing, but I have a need they can't meet. I want to know, every single day, if our performance metrics have changed in a marked way even against a development server. If they have, the change probably came from code that was checked in that day. If performance went down, our team can find the fix quickly or acknowledge the new baseline. If performance went up, we can figure out why and see if the fix can be applied in other places.

I downloaded JMeter and started giving myself a crash course on the software. I've used it in the past, but it was much simpler in those days. So were my requirements.

A simple case was pretty easy: hit a couple URLs that don't require parameters but do return dynamic data. I set up a thread group, the "how many threads should I use" required container, then I added HTTP requests that hit the URLs to that thread group, and then I added a "listener" that parses the responses. That gave me basic familiarity with the tool and allowed me to set up an automatic, nightly run of any checked-in JMeter tests. We use Hudson as a build system, and it has a nice little JMeter plugin that will graph the response times over time and also give you a simple per-run breakdown of performance.

But then I wanted a test suite that would hit a URL, parse the response, and run subsequent tests based on the data (an ID) that came back in the first response. There are plenty of hints that JMeter can do this kind of thing, but it took a lot of muddling to get it right.

I often say that I should contribute to open-source projects not as a professional programmer but as a professional writer. Documentation is often sparse and unclear, even on an established project like JMeter. Where is the "cookbook" section with "you want to do this common thing; here's how" entries? Where is the list of best practices?

You read their manual, you read the FAQ and the wiki, and you still spend a lot of time bumbling about, poking this and prodding that to see if the errors clear up. And I've barely touched the more powerful features.

Here are a few of the things I learned along the way, which I'm posting mostly for my own benefit.


  • JMeter can't do anything with a response — even show it to you — without knowing the MIME type. On the one hand, that forced me to return a clean response. On the other hand, I feel like JMeter should fall back to plain text if it has no other information.


  • Extract data from a response with a post-processor. If you want to use the response data from one http request in subsequent calls, you make the post-processor a child of that http request. (You can make a post-processor a sibling, in which case it runs after every request in the thread group.) I used a regular expression post-processor that matched the entire response. Even though there was no other data, I still needed to enclose the regex in (). I also needed the $1$ default template, even though I wasn't doing anything with multiple values.


  • It seems like every JMeter tutorial suggests that you add a Graph Results listener to your test plan. It shows you a graph of your response time. Ooh. Aah. Pretty. Also? Useless for debugging. I moved through errors at a rapid pace after I added a View Results Tree listener to the thread group. With that listener, you can drill down on the request/response for each and every server call. I also found the Summary Report listener to be more useful than Graph Results. Keep the pretty picture in to show your boss — it doesn't add time — but add the others to make your life easier.


  • Learn to love the JMeter functions. They're buried in Chapter 19 of the JMeter manual, but they're essential for making scripts that can be re-used in multiple places. I sprinkled the ${__P(name)} function throughout the text fields of my scripts so that I could fetch command-line properties such as TARGET_SERVER and TARGET_PORT. That means that running my scripts against a different environment will require nothing more than a different set of command-line arguments (prefaced with -J).

Friday, November 13, 2009

Profiling With Spring's AOP

Recently, at work, I wanted to set up an easy way to get lightweight profiling information about method calls in our system. There are lots of heavyweight profilers out there that give you great features at the cost of bogging down the machine they're profiling. Fine if it's a development box; less so if it's a production machine your users are using.

Because we're using Spring, we have access to a pretty decent aspect-oriented-programming system. (AOP is basically a way to add system-wide concerns to objects without those objects having to be aware of the systems in any way: no subclassing or encapsulation.) Since profiling is a classic cross-cutting concern — something you need throughout the system but don't want any individual object to know anything about — Spring's mechanism works pretty well.

In my final system, a programmer only needs to add a @Profile annotation on a method, and it will generate profiling information in the logs. I didn't want to profile every method all the time because of the noise it would generate and the performance hit it would cause. The programmer can refine the output of the profiling system a bit, but the default is to show method name, args, return value, and timing information.(Spring's AOP framework is limited to non-private methods that are proxied by the Spring system, so private methods and intraobject calls don't get tracked. If that becomes a problem, I'll add in true AspectJ support, but that shouldn't require any real changes in my code, since Spring's support uses AspectJ syntax.)

Here are the key parts.

First, the profiling method, with a pointcut/advice combination that says "run this code around any method annotated with a @Profile annotation.


@Around("@annotation(profileAnnotation)")
public Object profileMethod(ProceedingJoinPoint pjp,
Profile profileAnnotation) throws Throwable {

StringBuilder buf = new StringBuilder("method: " +
pjp.getSignature().getName());
if (profileArgs(profileAnnotation)) {
buf.append("; args: ");
if (pjp.getArgs() != null &&
pjp.getArgs().length > 0) {
buf.append("[");
for (Object o : pjp.getArgs()) {
buf.append(o.toString() + ",");
}
buf.append("]");
} else {
buf.append(" (no args)");
}
}

long currentTime = System.currentTimeMillis();
Object retVal = pjp.proceed();
if (profileReturnValue(profileAnnotation)) {
buf.append("; returnValue: " +
String.valueOf(retVal)); // valueof prevents NPEs
}

if(profileTiming(profileAnnotation)) {
buf.append("; timing: " + (System.currentTimeMillis() - currentTime));
}
log.info(buf.toString());
return retVal;
}



The Profile annotation looks like this:


/** Annotation to demark methods that should be profiled. */
@Retention( RetentionPolicy.RUNTIME )
@Target( ElementType.METHOD )

public @interface Profile {
ProfilingType[] value() default {ProfilingType.ALL};
}



And the ProfilingType enum looks like this:
public enum ProfilingType {ARGS,RETURN,TIMING,ALL}

The default output (ProfilingType.ALL) looks something like this:
method: [methodName]; args: [each arg as String]; returnValue: [returnValue]; timing: [some number of milliseconds]

Thursday, November 5, 2009

Sad, But Probably True

Reading the website for Apache Jmeter, I noticed this line: "JMeter's target audience is the testing community, which is generally not the hangout of developers or technical people."

Except for those developers who understand that the sooner you catch an issue, the cheaper it is to fix. Which, granted, is not as many as there should be.

Wednesday, October 7, 2009

Rounded Corners on UITableView

The iPhone UI is a soft, graceful collection of rounded corners. Your application icon is cropped and smoothed out with the ubiquitous curves. The highlight on the selected tab of a tab bar has tiny ones. Grouped table views, the corners of navigation items, the little buttons in toolbars. You can't escape the smooth arcs.

Which would be fine if Apple didn't require you to hand craft them yourself on your UI components. You might expect a "draw this with rounded corners" method. Actually, given their prevalence, you'd expect it to be a setting on UIView: cornerRadius or something like that.

But since that doesn't exist, every developer has to write his or her own take on it. So far, mine has become fairly standard. My UIView classes implement drawRect to set a curvy clip region. I have a utility method that takes any rect, with a desired radius, and returns a path for a rounded rectangle. Add that to the graphics context, call CGContextClip, and voila, I have voluptuousness. This has worked well.

Then I tried to do it on a UITableView embedded in a larger view. It's a view, right? So this should work, right? Except that UITableView's drawRect method doesn't really do anything. The corners don't get clipped if you subclass it and clip within drawRect.

Searching on this topic suggests that this is a common problem. I read various ideas, didn't really like them for one reason or another, and then came up with my own strategy. Why not overlay my table with a view that would act as a window? It would draw the part that I normally clip off and then make the interior transparent. And with a bit of work, I could make it a reusable view I could put atop other views that didn't behave the way I wanted. No more mucking around with clipping in random subviews!

I am not a graphics programmer. Not only did this take me a while, but there are probably better ways to do it. However, you may find yourself wondering how to do the same thing, and so I'm sharing my results.

Here's my init method. I used bgColor to represent the color on the outside of the corners, and I set the actual backgroundColor to clearColor I tried using clearColor as the fill color for my rounded path, but that didn't work. It was transparent over the view's background color, which meant the whole rectangle was filled in with the view's background, not the view underneath.



- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
bgColor = [UIColor blackColor].CGColor;
self.backgroundColor = [UIColor clearColor];
self.userInteractionEnabled = YES;
}
return self;
}


And here's the drawing code. I used EOFillPath to ensure that my interior was empty. Yes, I hardcoded the radius. Yes, that's lame. I'll fix it in a refactor pass.


- (void)drawRect:(CGRect)rect {
// Drawing code
CGContextRef ctxt = UIGraphicsGetCurrentContext();

CGContextSetFillColorWithColor(ctxt,bgColor);
CGContextAddRect(ctxt,rect);
CGPathRef curvePath = [Utils roundedCornerPathFromRect:rect withRadius:10.0];
CGContextAddPath(ctxt, curvePath);
CGPathRelease(curvePath);

CGContextEOFillPath(ctxt);
[super drawRect: rect];
}


That's the result of a fair amount of fiddling, and it now works. Except for one problem: You've covered the view you want the user to see with another view, effectively removing the user's ability to interact with it. To get around this, I created a "coveredView" reference within RoundedCornerOverlay and set it in the view controller managing the whole view. I overrode nextResponder in my view to return this reference. Then I overrode the various event methods you inherit from UIView. The final step was to realize I needed to convert incoming points to be relevant within the covered view.



- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[[self nextResponder] touchesBegan:touches withEvent:event];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[[self nextResponder] touchesMoved:touches withEvent:event];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[[self nextResponder] touchesEnded:touches withEvent:event];
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
[[self nextResponder] touchesCancelled:touches withEvent:event];
}

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
return [[self coveredView]
hitTest:[self convertPoint:point toView:[self coveredView]] withEvent:event];
}

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
return [[self coveredView]
pointInside:[self convertPoint:point toView:[self coveredView]] withEvent:event];
}

Saturday, October 3, 2009

Independent Developer

I assume that if anyone reads this blog — anyone? hello? — they also read my main blog, An Obsession With Food. So you've probably already seen the announcement: I launched 1.0 of my iPhone app, which helps home cooks organize the prep tasks for a dish.

What that really means is that for the first time in my professional career, I'm an independent developer. Of course, I also work for a company that can pay me. I am not planning my retirement based around sales of my application in the App Store. But I'll be the one doing the marketing — ugh — tech support, and project management. Now I'll have users. At least I hope I will.

So far, I've been the primary user of this app. In a way, this is good, because it's forced me to use the app day in and day out, finding the things that annoy me and then fixing them. But it's also bad. The app is tailored to the way I do things, even though most people probably have different menu planning strategies. I've had testers, of course, who have offered feedback. But, as of today, I have four times as many users as I did before I launched. I'm hoping they'll take the time to write me and offer suggestions, but who knows what will happen?

Monday, September 14, 2009

The Simplest Thing That Could Possibly Work

One of the maxims of Agile development — and especially Extreme Programming — is to write the simplest thing that can possibly work.

There are a few driving forces behind this motto. First, a core tenet of Agile development is to get testable, functional code up and running as soon as possible. If you don't spend a lot of time writing complex code, you can get it running sooner. And complex code is harder to maintain and thus more likely to have subtle bugs. Second, Agile assumes that requirements will change. This in part because requirements always change, but also because the mere act of showing a user a current piece of software will give them new ideas for the features that will really solve their problems. Users aren't good at articulating what they need until they see something "tangible" that isn't what they need. If you get a piece of code up sooner, you give your users the chance to steer the application in the direction they really want, not the direction they thought they wanted. And when they present this abrupt change in direction — as they inevitably will — you don't have to dismantle a complex system.

A close cousin of the "simplest thing" motto is "You're Not Gonna Need It." Experienced programmers tend to think in terms of frameworks they can build, good object-oriented principles, and so forth. But if you spend a lot of time building a nice, modular system with layers and abstraction, you may have wasted your time and effort if there will only ever be one module, one implementation of a given interface, or one class in a layer.

This is not to say that you should be sloppy, or churn out quick and dirty, copy-paste code. You are a professional and should act like one. Your "simplest thing" should be tested and it should be clean code. As the requirements change beyond what your "simplest thing" can do, you can then start to build layers on top of it, refactor to make it more modular, and so on.

All these arguments came back to me when I had to implement templatable text at work. I wanted text that a non-programmer could modify, but it needed to allow variable substitution.

Java's localization system allows this to some degree, except that its variables are numeric, not symbolic. So item zero is always the same, item one is always the same, etc. regardless of where they show up in the string. This makes sense for localization, but is fragile for more general templates. What if we wanted the text to use a different set of variables from one week to the next?

There are a number of general-purpose templating systems for Java: Probably the best-known is Velocity. As I started researching what it would take to implement it, however, the "simplest thing" motto came back to mind. Not that Velocity is difficult to implement, but we only needed to support five variables, and we didn't need any of the flow-of-control logic that Velocity offers.

So I wrote a very simple set of methods that allows me to do string replaces on the five symbolic variables I allowed. The (internal) user can write any text, using some or all of those variables once, twice, or whatever they want. And just in case we ever need to move to Velocity, I used the same variable naming syntax to define our variables.

The code is simple. It has noticeable restrictions (can't use undefined variables, can't define new ones), but in this case, it works exactly the way I need it to. It satisfied the business need, and truthfully, will probably never need to support more. When I needed to add an additional piece of templated text with the same variables, it took about 15 minutes including 10 minutes of testing.

Friday, September 4, 2009

Tutorial System, Part 2: Variadic Methods

In my last post, I mentioned a simple tutorial system that I wrote for my iPhone app: When I pass a key to the system, new users get a text box explaining the purpose of each screen, tap to close it, and then never see it again.

It worked well enough, though my testers have some usability comments that I need to address. But as I started working on version 1.1 of my app*, I realized that I had new needs. I had written, as I try to remember to do despite the temptation to overdesign, the simplest thing that could possibly work. That no longer fit the bill. (Writing the simplest thing that can possibly work assumes that design requirements will change. But since you can't predict those changes, even when you're the one creating them, you shouldn't waste time designing for requirements that don't yet exist. Address the problem in front of you, get functional code up and testable, and then refactor to simplify.)

I wanted the system to handle upgraders, so that upgraders would see text just about the new features, while new users would see a screen giving an overview of the page, including the new features. The key was that when a new user dismissed the tutorial box, s/he would never see the one for upgraders (because there would be no need).

I toyed with a few ideas, but I finally settled on one: Rather than passing a single key to the system, I'd pass a list of keys. The system would iterate through the keys until it found one the user hadn't seen, show the tutorial text for that key, register that the user had seen the key, and then register every subsequent key in the list.

In order to make this work, I used a variadic method, one with an indeterminate number arguments. It's been a while since I've been deep in a C-based language, so I had to refresh my memory about implementing them. (Curiously, the Objective-C bible, Programming in Objective-C, doesn't tell you how to implement them. Perhaps the new edition does.) They rely on the stdargs.h macros, va_start, va_arg, and va_end. In Objective-C, the convention is that the last item in the list be nil. For example, see NSArray's initWithObjects: method.

If you want to implement your own variadic method in Objective-C, here's the basic pattern (you don't need to import stdarg.h if you're importing the Foundation classes):


- (void) method: (id) arg, ... {
va_list argList; // special datatype for the argument list
va_start(argList,arg); // sets up the iteration

id curArg = arg;
while (curArg != nil) {
// do something
curArg = va_arg(argList,id); // pass the datatype you expect to find
}
va_end(argList);
}



Here's the code in the context of my Tutorial system:


+ (void) showTutorialForKey: (NSString *)key, ... {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
va_list argPtr;
va_start(argPtr,key);

NSString *curArg = key;

while (curArg != nil) {
if ([TutorialSystem userHasSeenKey:curArg]) {
curArg = va_arg(argPtr,id);
continue;
}

NSString *titleKey = [NSString stringWithFormat:@"%@ Title",curArg];

NSString* title =
[[NSBundle mainBundle] localizedStringForKey:titleKey value:@"" table:@"Tutorial"];
NSString* text =
[[NSBundle mainBundle] localizedStringForKey:curArg value:@"" table:@"Tutorial"];

TutorialController *controller =
[[TutorialController alloc] initWithTitle:title tutorialText:text];
[[[self appDelegate] window] addSubview:[controller view]];

// clear the user for all the rest of the args
while (curArg != nil) {
[TutorialSystem registerUserSeesKey:curArg];
curArg = va_arg(argPtr,id);
}
}

va_end(argPtr);
[pool release];
}



* I should note that 1.0 of my app is not yet out, despite being published on the App Store, because of some bureaucracy with my employer. Assuming it's going to get resolved. I've started on 1.1.

Sunday, May 31, 2009

Tutorial Mode For An iPhone App

One of my testers suggested that I have a "tutorial" for new users of my app: Help screens that pop up the first time a user visits a feature. There are many ways to do this, of course, but here's the implementation I designed. A client invokes the tutorial system in a simple way:


[TutorialSystem showTutorialForKey:@"Welcome"];



The TutorialSystem class takes over the rest through a series of class methods. (There's never an instance of a TutorialSystem object. Not a very object-oriented approach, but the tutorial system doesn't need to maintain state between invocations.)

Obviously I only want to show a tutorial screen once, so showTutorialForKey: first checks to see if the user has already seen the screen. I have an "application state" dictionary file that gets used for miscellaneous persistence: the last tab the user looked at before shutting down, the date they were looking at in the "by day" view, and so forth. The tutorial system uses the same dictionary to keep track of which tutorial screens the user has seen. In particular, it looks for a key named "hasSeen" followed by the name of the key passed in to the showTutorialForKey method. For the example above, the dictionary would have a key named "hasSeenWelcome."


+ (BOOL) userHasSeenKey: (NSString *)key {
if (ALWAYS_SHOW_HELP) {
return NO;
}
NSMutableDictionary *prefs = [[TutorialSystem appDelegate] appState];
NSNumber *didSee = [prefs objectForKey:[TutorialSystem prefsSeenKeyForKey:key]];

return didSee != nil && [didSee intValue] != 0;
}



(I have a #define that lets me always have tutorial screens show up. This is helpful for testing.)

If the system decides that it needs to show the tutorial screen, it uses the passed-in key as the key for a line in a strings file, the resource files Cocoa uses for localization of text. It also uses the key plus the text " Title" as the key in the strings file for the title of the tutorial screen. That means there's a line in my strings file that maps the tutorial body text to the key "Welcome" and another line that maps the tutorial screen title to "Welcome Title."

From there, it loads an xib file that I built in Interface Builder and lays it over the existing view. That file contains a screen-sized view that doesn't allow user interaction, but has an opaqueness level of .4. That way the underlying screen will still be visible. The xib file also contains a "tutorial screen" view that contains three subviews: a UILabel for the title, a UITextView for the tutorial body, and a UILabel that says "Tap to continue." The tutorial screen view handles all the user interactions, and interprets any touch to mean "go away." Here's what it looks like.



Finally, of course, I register that the user has seen the tutorial screen by placing the appropriate entry into the application state dictionary.

Here's the full showTutorialForKey: method:


+ (void) showTutorialForKey: (NSString *)key {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
if ([TutorialSystem userHasSeenKey:key]) {
[pool release];
return;
}

NSString *titleKey = [NSString stringWithFormat:@"%@ Title",key];

NSString* title = [[NSBundle mainBundle]
localizedStringForKey:titleKey value:@"" table:@"Tutorial"];
NSString* text = [[NSBundle mainBundle]
localizedStringForKey:key value:@"" table:@"Tutorial"];

TutorialController *controller =
[[TutorialController alloc] initWithTitle:title tutorialText:text];
[[[self appDelegate] window] addSubview:[controller view]];

[TutorialSystem registerUserSeesKey:key];

[pool release];

}

Thursday, May 28, 2009

Simulator Versus Device

I had an amusing realization this morning as I finished up a feature for my iPhone app. I implemented a "touch and hold" mechanism (see this excellent description of how to do it) and tested it last night on the simulator, Apple's "virtual iPhone" that makes it faster to turn around and test new code. It worked perfectly.

This morning, I put it on my phone, and it barely worked at all. It took me a few minutes, but I finally figured out the issue.

In my original code, touchesMoved dismissed the timer that eventually puts an indicator in place that you're in editing mode. On the simulator, that's not a problem: You take your finger off the mouse. But in the real world, your finger does not sit perfectly still. Mine doesn't, at any rate. So I had to add literal wiggle room. If you stay within a small radius of touches, the code won't dismiss the timer. Now it works just the way I want.

Sunday, May 24, 2009

I Am Not a Graphics Programmer

I consider myself a good programmer. I can comfortably chat about anything from high-level topics such as methodologies and architecture to the minutiae of multithreaded code and Java virtual machine idiosyncracies. I understand how to solve a wide range of scalability issues. I have a good eye for the subtle details that cause bugs. I know at least the basics of when one algorithm is better suited for a task than another.

Put me in front of a graphics library, however, and I freeze up. I've been doing some simple graphics work in my iPhone app — filling an area with a gradient, for instance — and it's been slow going. I don't have the terminology in my head for this work to come naturally. Transforms, alpha channels, drawing paths, blending modes. I might as well be reading Greek. And it doesn't help that Quartz, the graphics drawing system on the iPhone, is all based on C, a procedural language, instead of Objective C, an object-oriented language. It's been a very long time since I've worked in a low-level procedural language on a regular basis. (I will say, though, that Quartz tries its best to encapsulate the C code in macros that provide a straightforward coding experience. The graphics folks around me at Maxis think that it's pretty sweet, which makes me wonder what sort of libraries Microsoft gives to Windows programmers.)

Some of my frustration comes from simple lack of experience. I didn't used to know a lot about server-side programming, after all. As I do more graphics programming, I suppose more of it will come naturally, and I will learn more of the subtleties. But I've also never been drawn to that side of the coding fence. I like to say that I have no design sense. This isn't strictly true: I did the design work for Obsession With Food, and I've got some stunning quilt tops that I designed. But I'm always surprised when something I design comes out well.

Yet here I am, literally a one-man development team for this application. I can manage the architecture just fine — and it's pretty good — but there's no one I can hand off the graphics work to. It's just me. I speed through the object-oriented development side and slow to a crawl when I'm dealing with Quartz. In the long run, it's good for me to expand my horizons. But in the short term, the part of me that's used to quickly getting code up and running is growling at the long periods of time it takes me to implement the simplest little things in the graphics world.

Back to figuring out why my transparent blue is sometimes the only thing in the rectangle and is sometimes on top of the gradient that's supposed to be gone at that point. And why doesn't my grey rectangle show up at all? All this for a tiny-but-necessary bit of visual feedback on an already functional feature.

Friday, May 22, 2009

Federal Data Coming to a Web App Near You

The Federal government is releasing tons of data in web-friendly formats. See the perfectly named data.gov.

Must. Finish. One. App. Before. Starting. Another.

Friday, May 15, 2009

Real-World iPhone Rotation, Part 1

When I researched the techniques for supporting rotation (portrait vs. landscape) in my iPhone app, I found a few tutorials that all did the same thing: Stick a label in the middle of an otherwise unadorned view and override one method.

Simple, yes? Yes. If you're writing a boring application that just has one line of text in the middle of the screen.

My application has a tab bar. It has multiple screens. It has custom views that pop up from the bottom of the screen. It is not well served by the tutorials I found. Here, then, is one part of my tutorial, based on my own experience.

First, the default mode for any UIViewController is to not support rotation. It's easy to change that if you have a custom class that inherits from UIViewController: Override shouldAutorotateToInterfaceOrientation: to return YES. (You can get fancy with the argument passed in and only support certain orientations, but I didn't.)

But what if you're using a UITabBarController? The same idea applies, unfortunately. Make a subclass of UITabBarController and override that method. In Interface Builder, then, set your custom class as the handler. My class, RotatingTabController, does nothing except override that method and return YES. Yay for class bloat! There may be some way to just set a property in a normal tab bar controller and have it magically start handling rotation, but I haven't found it. So a brand-new class that exists solely to override a boolean return value it is.

However, once you've overridden that method for UITabBarController, you don't need to do it for all the views that hang off of it. But you do need to make sure your views behave when rotated.

The rotation animation on the iPhone is snazzy: Views arc around the screen and rearrange themselves. Get too wrapped up in the idea that you're rotating the view, however, and you'll hurt your head. Instead, think of it as resizing the view, since that's actually what it's doing. It's much easier to grok if you imagine going from this:


to this:


If you're using a built-in data view (table view, image view, etc.) as the sole item on the screen, it probably already behaves the way you want. If you're using a custom layout like this one, which includes a UITableView, controls, and buttons, you'll need to use the Size Inspector in Interface Builder. To control positioning, the Size Inspector uses the "springs and struts" metaphor: Views are locked to superviews (or not) based on the "struts" around the edge , and they expand or contract within their superview based on the "springs" on the inside of the rectangle. Click a strut or spring to enable it or disable it.

The first step in reocnfiguring your view is to set up the autosizing for the main UIView that contains all your subviews. This one's easy: Just enable every strut and spring. That ensures that each edge of the view stays a fixed distance from the corresponding edge of the superview (the application window) and changes its width or height as the window resizes.

I set up the UITableView in the picture the same way: Its top edge is a fixed distance from the top edge of the view (to make room for those other controls), and I want it to expand or shrink based on the containing view. It will expand to fill the width of the superview in landscape mode, and it will add height (and shrink its width) in portrait mode.

I wanted the button in the upper left to stay in the upper left, regardless of the orientation. In that case I enabled the strut on the left side and the strut on the top. I disabled every other strut and every spring. That ensures that the button doesn't change its size based on the orientation and that it stays in the upper left. Not surprisingly, I set up the add button in the upper right and the Today/All control next to it to be locked to the upper right corner, again without shrinking or growing.

A little bit of tinkering got all my views to look nice in either rotation. But I add my own custom views to the UIWindow object, and that is simply not working yet. The view pops out of the edge next to the home button, regardless of the phone's orientation, and it resizes in a sloppy way. When I figure that out, I'll post part 2.

Saturday, May 9, 2009

Refactoring Pays Down Technical Debt

One of my first posts on this site mentioned technical debt, a brilliant metaphor for the way that hurrying imperfect code out the door provides short-term gains but long-term costs for new features. Enough technical debt, and your feature development slows to a crawl. One way to pay down technical debt is to refactor code: Refactoring's main role is to adapt a code base to requirements that weren't on the table when the programmers started typing.

I've talked about continual refactoring before, which I do as a general rule in any code I find myself in, but that is usually directionless cleanup. A deliberate refactoring phase is even better. (As long as you don't fall into the "rewrite everything" trap that Netscape found itself in, which caused such a long delay in version 6 that the company essentially handed the entire browser market to Internet Explorer.)

In my iPhone app, I have three "detail" views that, when I first wrote them, had only surface-level similarities.* They had different DAL requirements, used different objects, and so forth. But as I added new functionality to each, such as my ScheduleButton widget and my date picker widget, they began to look more alike than not. I entered a bug for myself to refactor all the common code into one base class.

A week later, I did the work. There was no design requirement driving this: I just knew the code would end up in a better place at the end. I abstracted common functionality into superclass utility methods and used the template method design pattern to put a flow into the base class that used abstract methods ("abstract," because Objective C doesn't support this) to fill in view-specific details.

A week after that, I realized I needed to change the method signature for my date picker delegate methods to support a new feature. That meant going into all the delegates and updating the code. A simple search/replace wouldn't do what I needed.

Before my refactor, that fix would have affected eight methods in four classes. After my refactor, it affected four methods in two classes. I halved the development effort it took to support this new feature. But I also halved the testing effort. Since all my detail views descend from a base class that handles all the date chooser work, I only had to test one of them — plus one unrelated view — to ensure that all three were working. If I need to add a feature across all the detail views, it will take me one-third the time it would have before.

* As always, I should point out that my iPhone app just isn't that big. I'm unlikely to ever have a vast amount of technical debt in it. Still, it illustrates the point in a microcosm. Larger systems have proportionally more complexity and thus more opportunity for technical debt.

Friday, May 1, 2009

Girls On Rails

Martin Fowler has a nice essay about a recent controversy in the Rails community: A presenter gave a talk from a slide deck garnished with scantily clad pretty women. The Rails community, he notes, eschews typical corporate values. But they can't ignore decades of professional discrimination against women.

Thursday, April 30, 2009

Database Updates, Redux

Before I came up with my solution for updating the embedded database in my iPhone app, I had a different strategy that I couldn't figure out how to implement. Of course, after I had the new solution in place, I figured out how to implement my first idea.

I wanted to figure out how to construct method names on the fly and invoke them. That way, I could have dbChangeScript0,dbChangeScript1, and so forth, and then invoke them in a while loop that ran until the application didn't have a method with the relevant name. I wanted JavaScript's eval function in Objective C. I didn't see how to do it, though.

Today, I discovered NSSelectorFromString, a function that transforms a string into a selector (essentially, a function pointer). I used it to implement Plan A as follows:

- (void) installChangeScripts {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

int versionNum = [self dbVersionNumber];
SEL curSelector = NSSelectorFromString([NSString stringWithFormat:@"dbChangeScript%d",versionNum + 1]);
while ([self respondsToSelector:curSelector]) {
[self performSelector:curSelector];
[self updateDbVersion:versionNum +1];

versionNum = [self dbVersionNumber];
curSelector = NSSelectorFromString([NSString stringWithFormat:@"dbChangeScript%d",versionNum+1]);
}
[pool release];

}


Is this a better version? I've lost the self-documenting method names such as makeVersionTable, but I've removed an in-memory array and a #define that I had to remember to update when I updated the array. In other words, I've increased the code's maintainability. (The code looks shorter, but only because I also factored out the version update into a new method.) Overall, I consider this a win.

The Ruby on Rails community has a mantra: convention over configuration. In Rails, you can get a full website up and running just by following a few naming conventions — ones you probably would have used anyway. A class of name X will translate to a database table named Y and so on. Compare that to Spring, a powerful Java framework that requires constant work in the XML-based configuration files.

In essence, I voted for the convention side of the fence in this code. By following a consistent naming scheme, I can write a small method that will do all the work. All I have to do is add a new method with a predictable name. Compare that to an array that I had to remember to configure properly.

On-The-Fly Database Updates

I love the fact that the iPhone comes with an installation of SQLite*. As someone who's worked with relational databases and the SQL language for his entire professional career, I happily use it to store the information I need for my iPhone app.

But with an embedded database comes the need to alter its structure on the fly as my data requirements change. I'm still in beta testing, so I could tell all my testers to nuke their data the next time they install my application, but I'd prefer to avoid that, and I certainly won't tell my future customers to do that.

Instead, I came up with a simple system for making the app run its own database updates. I have a class, DBAccess, that puts an object-oriented wrapper around the very procedural SQLite calls. I created a new method, installChangeScripts, that looks like this:



- (void) installChangeScripts {
SEL changeScripts[CHANGE_SCRIPTS];

changeScripts[0] = @selector(makeVersionTable);
changeScripts[1] = @selector(addTaskDuration);

int versionNum = [self dbVersionNumber];

for (int changeScriptIndex = versionNum + 1;
changeScriptIndex < CHANGE_SCRIPTS;
changeScriptIndex++) {
[self performSelector:changeScripts[changeScriptIndex]];
NSString *versionUpdateQuery =
[[NSString alloc]
initWithFormat:@"update app_version set version_num = %d",
changeScriptIndex];
[self executeUpdate:versionUpdateQuery];
[versionUpdateQuery release];
}
}



The gist is straightforward: Make an array of method selectors (Objective C's way to find a method at runtime), iterate through them starting at the database's current version number + 1, and update the version number after the script has run. The only tricky part is that the version table doesn't exist in the default version of the database, so I have logic to handle the case where it doesn't exist:


- (int) dbVersionNumber {
int versionNum = -1;
// get the current version. handle this case differently since it drives the rest
// of the logic
NSArray *queryResult = [self executeQuery:@"select version_num from app_version"];
if ([queryResult count] > 0) {
// handle the result
NSDictionary *versionResult = [queryResult objectAtIndex:0];
versionNum = [[versionResult objectForKey:@"version_num"] intValue];
}
[queryResult release];
return versionNum;
}



Originally, this logic was in the installChangeScripts method, but that was an easy refactor: self-contained logic that only produces a single value used by the rest of the method. See the Extract Method refactoring sequence.


Not surprisingly, the first change script creates the version table.


- (void) makeVersionTable {
[self executeUpdate:@"create table app_version (version_num integer)"];
[self executeUpdate:@"insert into app_version values (0)"];
}



There's at least one other good refactoring target here: The setup of the list of install scripts should be in its own method because it's a separate concept from actually running the scripts. I just need to remind myself how to deal with calloc, free, and other denizens of the pointer/array abyss.

* I also love the group's motto, "Fast. Small. Reliable. Choose any three." A nice spin on the various "choose two" sayings such as "Fast. Scalable. Cheap. Choose two."

Wednesday, April 29, 2009

Old-School Coding Techniques

Computerworld takes a look at old-school programming techniques we should all be happy to forget. But what about old-school techniques that are still relevant or should be revived?

Tuesday, April 28, 2009

Meaty Learning Projects

My job description implicitly includes understanding current technologies, philosophies, and methodologies. Usually, this is just a surface-level knowledge about what's going on in the industry, but occasionally I decide to dig deeper.

For instance, right now I'm learning Scala because I think it will solve some thorny performance issues at work. But it's a Catch-22: I don't want to introduce a whole new language without knowing if it will really benefit us, but I can't know if it will benefit us until I try it with a meaty project. And it's even worse than normal in this case: The feature I really want to explore — actors — requires a decent chunk of knowledge before I can take advantage of it.

Over the years, I've developed a solution to this problem. I have a substantial, but not overly complicated, program that I write whenever I come to a new platform. I write a program that assists me in finding solutions to the kind of thorny word puzzles you get from the National Puzzlers League. It requires me to open a file, read in words, and see if they match the pattern the user is searching for. No network connection. No database work. No scalability issues.

It's a problem space I understand, so I can dive in without much thought. I get a deeper knowledge of the language than I'd get from working through a tutorial's abstract problems. It forces me to probe and dig through the libraries to accomplish what I need. I don't get a thorough understanding of the language, but I get pretty far.

Overall, it's a plan that's worked well for me.

Article On EasyMock

IBM's DeveloperWorks features an article about EasyMock, a framework for building mock objects for unit testing.

Friday, April 24, 2009

The Root Of All Evil

In my most recent round of interviews, I chatted with the founder of U1 Technologies. He and I had a lot in common philosophically and, with a slight shift in timing, I might very well have been working for him instead of Maxis.

One of the things that caught my attention was his phone screen questions. I've been on both ends of these things, and they usually consist of simple questions that ensure that the candidate isn't obviously inflating his or her resume. Things like: "Explain how an Iterator works." or "When would you use a List versus a Map?" (Yes, I've actually been asked these.)

Nathaniel's first question reflected his company's decision to only hire senior engineers: "When should you optimize your code?" Fifteen years of software engineering provided a quick answer: "When you know there's a performance problem with it."

"Premature optimization is the root of all evil," is a quote that's been attributed to both Donald Knuth and C.A.R. Hoare. (Most people cite Knuth, who cites Hoare, who denies saying it, according to Wikipedia.)

This may sound at odds with one of my other favorite programming axioms: "The earlier you find the bug, the cheaper it is to fix." But optimizing code usually goes hand in hand with making it less maintainable and reusable. Specializing algorithms, caching values, adding different control structures, and more all add complexity. If you don't have performance numbers to back up that work, you're adding the complexity and (probably) not getting any benefit from it.

You may have inefficient code that rarely gets called. You may think something's inefficient when in fact the compiler or optimizer or processor does just fine with it. Or your code could actually be inefficient and it might just not matter enough to affect the user.

I've seen this in practice for years. And yet the temptation to optimize is always there, coaxing even the best programmers into a fen of tangles and mazes and confusion.

While I was working on the "real time time update" feature of my reusable date picker pop-up, I set it up so that the delegate would be called for every UIControlEventValueChanged message from the UIDatePicker.

I envisioned the date and time changing as the wheels in the date picker spun to their new locations, so I decided to be smart about calling the delegate method.

I could have written this in my event-handling method:

if ([delegate respondsToSelector:@selector(dateChangedWithoutSaving:)]) {
[delegate dateChangedWithoutSaving: date];
}


But I assumed that respondsToSelector would be a relatively expensive call. I also assumed that the runtime binding to dateChangedWithoutSaving: method would be costly. And I didn't want that cost slowing down the user's interaction with the date picker wheels. Instead, I made a boolean in the controller that tracked whether or not the delegate actually supported the method and set it at the same time I stored the reference to the delegate:

- (void) setDelegate: (id) delegate {
...

delegateRespondsToContinuousDateChanged = [delegate respondsToSelector:@selector(dateChangedWithoutSaving:)];
}


I changed my event-handling logic accordingly:

if (delegateRespondsToContinuousDateChanged) {
[delegate dateChangedWithoutSaving:[myDatePicker date]];
}


Then I fired up my app.

And discovered something I didn't know. That UIControlEventValueChanged message only gets sent once the date picker wheels have finished spinning. Rather than sending a message for every number that cruises by, it only sends, essentially, one message per gesture. My optimization didn't buy me much, since the code can't possibly interfere with the spinning wheel animation.

So what did my "clever" optimization get me?

  • My own implementation of setDelegate (rather than the one created by Objective C's synthesize keyword)

  • An extra layer of logic in my event-handling code.



I've added more complexity (the extra layer of logic) and more lines of code (the setDelegate method) with the concurrent possibility of bugs.* Performance gain: virtually none.

Premature optimization is the root of all evil.

* Yes, of course, this isn't much extra complexity or code. But add up enough items like this, and you get a significant amount of technical debt

Wednesday, April 22, 2009

Delegation And Redesign

One side effect of programming for the iPhone (or Mac OS X) is a heightened awareness of the delegation pattern. It seems like every class in the framework has delegate information.

When I started my UI redesign work in my iPhone app, I saw a perfect opportunity for implementing my own delegate pattern.

The idea behind delegation is straightforward. Object A holds a reference to Object B. Object A goes about its merry way performing its duties, except that every now and then it says to Object B, "Hey, I need you to handle this, okay?" To everyone else, it looks like Object A did the work. A good example is the UITableview in the iPhone framework. It supports two delegates, one for supplying the table's data, one for handling the table's behavior. The data delegate has methods such as numberOfSectionsInTableView; the behavior delegate has methods such as tableView:didSelectRowAtPath:. The table view doesn't care about anything else those objects might do: It just expects them to do what it needs.

The pattern encourages code reuse (I have a single instance of a delegate that handles common behavior for all of my text fields) and separates business logic from other layers (I have specialized objects that act as my tableview data sources, leveraging a model object in different ways, all without modifying UITableView in any way). It lets you make complex object compositions from subsystems. It makes breakfast for you in the morning. It's great. (As with all general-purpose design patterns, you may need to consider performance and threading issues when putting it into practice.)

In Objective C, it's easy to use a delegate:

id delegate; // set by an outside client
[delegate invokeDelegateMethod]


Even though the compiler doesn't know if delegate implements invokeDelegateMethod, it compiles this code with only a warning. (id is shorthand for "an otherwise untyped object.") Of course, if you try and run this, and delegate does not implement invokeDelegateMethod, you'll get a runtime exception. This may be what you want, but you can also use:

id delegate;
if ([delegate respondsToSelector:@selector(invokeDelegateMethod)]) {
[delegate invokeDelegateMethod];
}


This makes the method optional. You can be formal and specify a protocol that the object must declare to get yourself some type safety, but it's not strictly necessary. Java has similar "rummage around in an object's belly and see what it contains" tools in its reflection API, so you could easily hook up delegate patterns the same way in that language.

For my redesign, I had several places where I needed to pop up a view that had a UIDatePicker, a Done button, and a Cancel button. The idea being that the user needs to pick a date and tell me when s/he's done. The delegate pattern seemed to be the perfect approach, since I had one class that I needed to reuse throughout the application and have it fit seamlessly into the flow of each area.

In my first pass, I implemented two delegate methods, dateSaved: (NSDate *)date and datePickerViewDismissed.

I made the first one optional: Why should the date choosing view care whether the client actually wants to know about the date that was chosen? I made the second method required (i.e., I don't check to see if the delegate supports the method before calling) because that's the method that triggers the client to release any memory it used for the view. I wanted to make sure that I'd know right away if I forgot to implement that method.

I wired the view into the first use case: A screen that shows one date at a time would let the user jump to any arbitrary day, rather than nexting and previousing a bunch. Everything worked fine, so I started to wire it into the next part of the app, where you set the time for a single task. That's when I had the eye candy idea for my ScheduleButton. With a bit more work, I could make a delegate method for the date picker view that would fire as the date changed, which meant that I could update the button's text as the user spun the wheels.

My new version added a new delegate method, dateChangedWithoutSaving: (NSDate *)date. But what if the user cancels? My architecture didn't support that, so I changed the datePickerViewDismissed method into datePickerViewDismissedWithButton: (DateChooserButton)btn (DateChooserButton being an enum representing the two choices). Now a client could grab a copy of the date, bring up the view, update the ScheduleButton helper object as the date changed, and then reset it to the original date if the user pressed cancel.

Tuesday, April 21, 2009

Enhancing UIButton. Or Not.

As part of a UI redesign in my iPhone app, I realized I had a few concepts that would be repeated in various places, so of course I wanted to bundle them into reusable components.

One idea was a button whose text would always read "<some fixed prefix>: <some mutable date>." The date changes as the containing view is visible, but the prefix is fixed early in the button's lifecycle.


I made a new class, called ScheduleButton, that subclassed UIButton. I added methods for setting the date format, the actual date, and the prefix. These call down into a single "updateButtonText" method that constructs the appropriate string and would have used the inherited UIButton methods to change the text.

So far, so good.

I dragged a UIButton object from Interface Builder into my app, and set the class to ScheduleButton (instead of UIButton, the default). I launched my app and saw the button,but without a border.

I could probably figure out the reason for this. I suspect it has something to do with the fact that UIButtons are made with a class method, buttonForType, rather than a normal alloc/initWithFrame flow (at least from a client's perspective: I imagine initWithFrame gets called in there somewhere).

But after hitting my head against several other issues during this redesign, I pretty much just said, "Fuck it." (Did I mention that I'd swear on this blog? Well, I will.) Instead, I converted ScheduleButton into a helper class that holds a reference to a UIButton. The controller still interacts with ScheduleButton, using the same methods, and they feed into one centralized method, but that one method now invokes setTitle on the contained UIButton rather than inheriting it. That means that other objects can muck with the UIButton on their own, without my helper being the wiser, though that's not likely to be a problem since I'm the sole user. (There's probably yet another solution involving Objective-C's category functionality, but I don't want to modify every instance of the UIButton class in my application: I just want to modify particular objects.)

I tried to lend credence to this implementation by convincing myself that this was an instance of the Decorator design pattern, but it's pretty clearly not. A proper Decorator shares a parent with the decorated object and implements every method by calling into the (completely contained) decorated object. It then adds extra functionality that the decorated object doesn't know about.

Ah, well. Sometimes you just need something to work.

Evolutionary Architecture and Emergent Design

IBM's DeveloperWorks has an interesting series on finding the design inherent in systems through test-driven development and other strategies.

Sunday, April 19, 2009

Constant Refactoring: A Practical Benefit

As I program, I continually refactor the code I'm in. It's habit at this point. I rarely get the opportunity to do a massive change, but even the basic work I do — removing duplicated code, generalizing logic, dividing up large functions, and so on — reaps unexpected benefits.

Refactoring partly makes code more maintainable, but its main purpose is to make the code flexible enough to respond to new design requirements. I try to code on the assumption that change will come, but if I could predict the exact direction of every future change and thus craft a perfect design, I'd be writing this from my French Chateau.

Here's a simple example I recently found in my iPhone app.

One of the tabs lets you move between dates, one at a time, to see your schedule for that particular date. In my initial design, I didn't let you change dates because that view exists to show you what's going on today. But I quickly realized that I wanted to at least see what tomorrow would bring.

When I made that change, I had two buttons that would switch to either the next date or the previous date. They each called separate methods — nextDay and previousDay — that were fairly similar to each other. I was working through the basic functionality, so I didn't register the commonality. I think this is common enough: You're so focused on one thing that you don't notice something else.

On a later pass through the code, fixing something else, I realized how similar the methods were, and I wrote a new method that would just adjust the date based on some time interval. I gutted nextDay and previousDay and replaced them with calls to the new method that passed either 86400 or -86400. (The number of seconds in a day.)

After that, one of my testers suggested that I let the user swipe across the date to move to the next or previous day, depending on the direction. Once I figured out the gesture system for the iPhone, I just made each swipe call either of the two appropriate methods, which in turn called into that common method.

But then I realized that I needed to add animation to show the user what was happening. I put the animation logic into the generalized method and made it smart enough to know that a negative number meant animate one way, while a positive number meant animate the other way (animate from the left in the first case, because you're moving to the previous day, and animate from the right in the second). That handled the animation for the two cases.

A couple of my testers asked for the ability to jump to an arbitrary day. I decided to look into implementing that this morning, and once I opened the code, I realized it would be a snap. I bring up a UIDatePicker, the "choose from a list" UI in the iPhone, and then just pass the time interval between the user-selected date and the current date to that one common method. The logic is the same, and the code animates appropriately: If you jump to some arbitrary, far-future date, the screen wipes from right to left, as you'd expect. Aside from bringing up the date picker, I wrote exactly one line of code to enable the feature.

For this simple example, I probably would have found my way to the same end result: an all-purpose method for jumping to any given date. But the fact that I had refactored earlier — just because — made the solution obvious and quick.

When I started this feature, you couldn't switch dates at all. Piece by piece, I built the infrastructure so that now you can jump to any date with gestures and animations. That wasn't the original design, but constant refactoring allowed me to eventually support this radically new direction with a minimum of "from scratch" code.

iPhone Mail Reformatting

I recently wired up the ability to email lists from an iPhone app I'm writing. Setting this up was pretty straightforward (see the Apple docs on the subject).

But since I'm sending lists, and since my list might have headings with one level of subitems, I wanted to create an email that looked like this:

Heading
Item 1
Item 2
Item 3


I added the appropriate spaces to my email body, URL encoded it with NSString's stringByAddingPercentEscapesUsingEncoding method, and shipped it off to Mail with [[UIApplicaton sharedApplication] openUrl:]

What I saw when Mail started was this:

Heading
Item 1
Item 2
Item 3


I assumed my indent code didn't work, so I looked at the result in the debugger. The encoded string had the three spaces in front of each item; Mail had decided it didn't like the spaces at the beginning of the line. I tried using a tab instead. No dice.

Thinking that I could trick Mail by putting a different character at the beginning, I sent it email that should have looked like this:

Heading
- Item 1
- Item 2
- Item 3


What I got was:

Heading
- Item 1
- Item 2
- Item 3


Mail not only doesn't like white space at the beginning of the line; it doesn't like multiple spaces at all.

I find this very annoying. I'm sending Mail a piece of text that I want it to use, and it's making its own decisions about that text. Mail would let me type " Item 1"; it just won't take it from a passed-in URL.

Grr. In the end, I decided to just live with the last version of the list. A friend suggested "--Item 1" but I don't like the way the dashes run into the text in that form. Maybe "-- Item 1."

Technical Debt

Some time in the last year, I learned the term Technical Debt. It's a brilliant metaphor for the more hurried, less-thought-out code that crops up in any project with a ship date.

The idea is simple: Just as you actively take on financial debt to give yourself new opportunities, you take on technical debt to ship a product out the door and make money from it. Financial debt is simple money, but technical debt is more complex. Any decision you make to ship the product at the expense of a clean code base qualifies. Every test you don't write is technical debt. Every piece of duplicated code that hasn't been refactored into common functionality is technical debt. Every todo comment is technical debt. Every bug you ship with is technical debt.

But too much technical debt, and you never pay down the principal, in this case the ability to quickly add new features or fix old bugs. That duplicated code? If you never refactor it, every bug fix in that code has a cost proportional to the number of places it's used. And that's if you actually remember where all those pieces are. That todo comment you never go back to? Some day you'll need to enhance the code around it, and that todo will add to the cost of the work. Add enough of these little debts, and the cost for any given feature multiplies.

Unfortunately, while it's easy to measure financial debt, it's tough to measure technical debt, which makes it difficult to use when arguing for time to fix things up in the code base. If you never need to fix a bug in that duplicated code, for instance, you'll never experience the extra cost of fixing it in every location. Of course, the idea that a chunk of code will sit forever untouched once it's written is ludicrous, but you can't sell the idea that something might be a problem someday outside of development teams.

There's also no good way to flag technical debt. Perhaps as programmers we need a more formal way — beyond todo comments — to note down that we made a deliberate choice to take on technical debt. But then we have to advertise to the larger world that we deliberately did something not in the best possible way. I know that won't sell.

About This Blog

I'm a programmer, both professionally and passionately. This blog will contain all my thoughts, explorations, and ramblings about my programming antics.

For the most part, this blog will cover my personal programming projects, but work topics will sneak in from time to time if they don't have any confidential information.

Most people would call me a Java programmer, but that's just how my career has shaken out. I consider myself an "all-purpose" programmer. The topic itself intrigues me, regardless of the particulars of any one language.