Saturday, April 25, 2009

On dynamic vs. static polymorphism

An interesting juxtaposition in the ACCU 2009 schedule put my talk on "adopting MVC in Objective-C and Cocoa" next to Peter Sommerlad's talk on "Design patterns with modern C++". So the subject matter in each case was fairly similar, but then the solutions we came up with were entirely different.

One key factor was that Peter's solutions try to push all of the "smarts" of a design pattern into the compiler, using templates and metaprogramming to separate implementations from interfaces. On the other hand, my solutions use duck typing and dynamic method resolution to push all of the complexity into the runtime. Both solutions work, of course. It's also fairly obvious that they're both chosen based on the limitations and capabilities of the language we were each using. Nonetheless, it was interesting that we both had justifications for our chosen (and thus One True) approach.

In the Stroustroup corner, the justification is this: by making the compiler resolve all of the decisions, any problems in the code are resolved before it ever gets run, let alone before it gets into the hands of a user. Whereas the Cox defence argues that my time as a programmer is too expensive to spend sitting around waiting for g++ to generate metaprogramming code, so replace the compilation with comparitively cheap lookups at runtime - which also allows for classes that couldn't have possibly existed at compiletime, such as those added by the Python or Perl bridge.

This provided concrete evidence of a position that I've argued before - namely that Design Patterns are language-dependent. We both implemented Template Method. Peter's implementation involved a templatized abstract class which took a concrete subclass in the realisation (i.e. as the parameter in the <T>). My implementation is the usual Cocoa delegate pattern - the "abstract" (or more correctly undecorated) class takes any old id as the delegate, then tests whether it implements the delegation sequence points at runtime. Both implement the pattern, and that's about where the similiarities end.

Tuesday, April 21, 2009

Did you miss my NSConference talk?

The annotated presentation slides are now available to download in Keynote '08 format! Sorry you couldn't make it, and I hope the slides are a reasonable proxy for the real thing.

Monday, April 20, 2009

I may have not been correct

When I said Apple should buy Sun, whether that was a good idea or not, it seems to have failed to occur. Instead, we find that Oracle have done the necessary. Well, there goes my already-outdated SUNW tag. Presumably they'll keep Java (the licensing revenue is actually pretty good), MySQL (I've heard that Oracle make databases), the OS and a subset of the hardware gear. Then they'll become the all-in-one IT industry in a box vendors that Cisco have yet to organise, with (presumably x86) servers running the Solaris-Glassfish-Oracle-Java app stack in some insanely fast fashion. I wonder how many of the recent leftfield hardware projects they'll just jettison, and who will end up running the Santa Clara business unit...

Sunday, April 19, 2009

On default keychain settings

After my presentation at NSConference there was a discussion of default settings for the login keychain. I mentioned that I had previously recommended some keychain configuration changes including using a different password than your login password. Default behaviour is that any application can add a secure item to the keychain, and the app that did the adding is allowed to read and modify the entry without any user interaction. As Mike Lee added, all other apps will trigger a user dialogue when they try to do so - the user doesn't then need to authenticate but does have to approve the action.

That almost - but not quite - solves the issue of a trojan horse attempting to access the secure password. Sure, a trojan application can't get at it without asking the user. What about other trojan code? How about a malicious SIMBL hijack or a bundle loaded with mach_override? It should be possible to mitigate those circumstances by using custom code signing requirements, but that's not exactly well documented, and it's not really good usability for an app to just die on its arse because the developer doesn't like the other software their user has.

There's a similar, related situation - what if the app has a flawed design allowing it to retrieve a keychain item when it doesn't need it? Sounds like something which could be hard to demonstrate and harder to use, until we remember that some applications have "the internet" as their set of input data. Using a web browser as an example, but remembering that I have no reason to believe whether Safari, Camino or any other browser is designed in such a way, imagine that the user has stored an internet password. Now all that the configuration settings on the user's Mac can achieve is to stop other applications from accessing the item. If that browser is itself subject to a "cross-site credentials request" flaw, where an attacking site can trick the browser into believing that a login form (or perhaps an HTTP 401 response, though that would be harder) comes from a victim site, then that attacker will be able to retrieve the victim password from the keychain without setting off any alarms with the user.

If the user had, rather than accepting the default keychain settings, chosen to require a password to unlock the keychain, then the user would at least have the chance to inspect the state of the browser at the time the request is made. OK, it would be better to do the right thing without involving the user, but it is at least a better set of circumstances than the default.

Friday, April 17, 2009

NSConference: the aftermath

So, that's that then, the first ever NSConference is over. But what a conference! Every session was informative, edumacational and above all enjoyable, including the final session where (and I hate to crow about this) the "American" team, who had a working and well-constructed Core Data based app, were soundly thrashed by the "European" team who had a nob joke and a flashlight app. Seriously, we finally found a reason for doing an iPhone flashlight! Top banana. I met loads of cool people, got to present with some top Cocoa developers (why Scotty got me in from the second division I'll never know, but I'm very grateful) and really did have a good time talking with everyone and learning new Cocoa skills.

It seems that my presentation and my Xcode top tip[*] went down really well, so thanks to all the attendees for being a great audience, asking thoughtful and challenging questions and being really supportive. It's been a couple of years since I've spoken to a sizable conference crowd, and I felt like everyone was on my side and wanted the talk - and indeed the whole conference - to be a success.

So yes, thanks to Scotty and Tim, Dave and Ben, and to all the speakers and attendees for such a fantastic conference. I'm already looking forward to next year's conference, and slightly saddened by having to come back to the real world over the weekend. I'll annotate my Keynote presentation and upload it when I can.

[*] Xcode "Run Shell Script" build phases get stored on one line in the project.pbxproj file, with all the line breaks replaced by \n. That sucks for version control because any changes by two devs result in a conflict over the whole script. So, have your build phase call an external .sh file where you really keep the shell script. Environment variables will still be available, and now you can work with SCM too :-).

Friday, April 03, 2009

Controlling opportunity

In Code Complete, McConnell outlines the idea of having a change control procedure, to stop the customers from changing the requirements whenever they see fit. In fact one feature of the process is to be heavy enough to dissuade customers from registering changes.

The Rational Unified Process goes for the slightly more neutral term Change Request Management, but the documentation seems to imply the same opinion, that it is the ability to make change requests which must be limited. The issue is that many requests for change in software projects are beneficial, and accepting the change request is not symptomatic of project failure. The most straightforward example is a bug report - this is a change request (please fix this defect) which converts broken software into working software. Similarly, larger changes such as new requirements could convert a broken business case into a working business case; ultimately turning a failed project into a revenue-generator.

In my opinion the various agile methodologies don't address this issue, either assuming that with the customer involved throughout, no large change would ever be necessary, or that the iterations are short enough for changes to be automatically catered for. I'm not convinced; perhaps after the sixth sprint of your content publishing app the customer decides to open a pet store instead.

I humbly suggest that project managers replace the word "control" in their change documentation with "opportunity" - let's accept that we're looking for ways to make better products, not that we need excuses never to edit existing Word files. OMG baseline be damned!