Having the Same Object Handle Multiple Tasks

It’s often tempting to write some code to do a task and make it generic enough to handle similar but different tasks.  A great example that we dealt this this week was a picker dialog that was used generically for people, organizations, and skill sets in a Xojo web app.

It made sense.  The dialog is called from multiple places and it does the exact same thing in each place (displays a list and the user can filter on the list).  What’s different is what data we pass into it for initialization and what data it loads for display.  We wanted the exact same UI in all three cases.

We all want to write as little code as possible.  That’s what’s great about being a lazy programmer.  Do more with less.  That works until it doesn’t and, to be honest, we’ve learned, the hard way, that sometimes the best approach is to make your objects do one thing and one thing only.  Why?  Because inevitably the client will say, this is great, but we want to filter for ‘x’ on people, and ‘y’ on organizations, and neither of those things are interchangeable UI-wise and neither x nor y make zero sense for skill sets.

The first approach is to put lots of if-then-else blocks into what was once a very generic picker dialog.  Now it’s a complex UI that has three distinct code paths.  This complicates testing since every time you make a change it now has to be tested in all three areas.  What worse is the code becomes complex and if you’re in a hurry (and who isn’t?) it’s easy to change the WRONG bit of code.

Our solution was to write the first dialog, get the UI working properly, and then duplicate the entire object and customize it for its new task.  <Gasp>  I know, bad OO programming, right?  We disagree and that’s coming from the school of hard knocks.

The end result is that we have specific pickers for people, organizations, and skill sets.  It’s now simple for a developer to make a change for the picker in question.  No longer do they have to think, “gee, which datatype am I fixing this time,” and possibly get it wrong.  Keeping it simple reduces accidental coding bugs and it reduces unintended bugs due to code changes.

Testing also becomes easier because if we’ve done something to the employee picker, we don’t have to test organizations or skill sets.  Likewise for the other two areas.  Simple is good.

The one area that it does become a bit messier is if we have to do general user interface overhaul.  Now you potentially have three places to do it.  However, since we have WebStyles with web apps this becomes trivial unless you’re rearranging UI elements.  Xojo Desktop apps are a little harder since there are no styles but in those cases it’s actually fairly easy to copy/paste UI from one form to another (assuming that’s possible).

Call me cynical, but I would gladly work on UI for an hour to ensure they’re identical to futzing around with code in three separate code branches that are nearly identical.  I am a lazy developer after all.

Our experience says that generic, reusable objects, often lead us into trouble, so we tend simply not to do them.  But how do you teach that to a new developer and one that’s trying to do their best to use good OO conventions?  And when do you reach that breaking point where the generic way makes it harder than its worth?  Good questions that I don’t have good answers for.

Happy coding!

How Do We Read Code?

I was directed to a blog post today that I felt was interesting so I’m sharing it with you.  The author participated in an experiment to to see how people comprehend programs.  The goal is “to figure out some way of measuring what features in programming systems help programmers understand what they are doing.”

Interesting post and pretty cool video showing the eye movements while he was figuring out a Python program.  I highly recommend viewing it.

What caught my eye though, was this statement:

…there seems to be some evidence that following variable naming conventions helps experienced programmers understand the code much quicker, while breaking these conventions leads to a severe penalty.

From my own experience this is true.  When I’m working with code that someone from my own development team wrote it’s very easy to follow and understand and modify.  OPC (Other People’s Code) projects take longer to figure out because invariably they don’t use the same standards (if they even have standards).

So I guess the moral of the story is that as you become more proficient in whatever language you use you should start using naming standards.  It’ll help you in the long run become a more efficient programmer.

Happy Coding and Happy Holidays!

Cocoa Tip

I’ve been playing around with Cocoa in Real Studio.  It’s come a long way in the past couple of releases and I urge you to start testing your apps to find those pesky Cocoa bugs.  Real Software is making a huge effort for the 2011 R2 release to fix as many Cocoa bugs as possible.  It’s that close.

Yesterday I ran across a problem where my app was crashing immediately upon startup.  The crash log gave a very odd error message:

Dyld Error Message:  Library not loaded: /System/Library/Frameworks/user32.framework/user32

Wha?  User32?  That sounds like a Windows library and certainly nothing I’ve ever seen on Mac OS X.  I actually wrote the ‘bug’ up and sent it in via Feedback and then did some more research.  The answer wasn’t really all that surprising.

I have a lot of old code that I’ve developed, bought, and found over the years that make it into most of my projects.  It’s there and I don’t even think about it.  One of the pieces of code that I bought from someone works cross-platform Mac/Windows and so it has a ton of #if statements.  Things like this:

#if targetcarbon then

//Do Mac stuff

#else

//Do Windows stuff

#endif

See the problem?  If I wasn’t making a Carbon application, which Cocoa most definitely is not, it attempts to run the Windows code.  So now the crash log makes total sense.  I suspect that a lot of people will have a similar problem.

Check your projects for compiler switches like this.  If you’re developing cross-platform applications you’ll probably have this problem.  In the long run all I did was do a simple global search for #if targetcarbon and replaced it with the target for Mac OS.  That won’t work for all cases, but it should get you close.

Ideally I would love for the Real Studio compiler to give me a warning for this case but I don’t think that’s even possible.  Really, how many libraries are there in the world to know about for each platform?  Impossible I say.  At a minimum, however, I would think that it would be possible to get a better runtime error.  Sort of like how you get error messages if you don’t have the plugin libraries where the executable expects them (much more of a problem in Windows if you move the Libs directory).

What say you my fellow REALbasic geeks?  Have you tried Cocoa yet with 2011 R1.1?  Any major problems?

Yeah, Right. You Can Do It

I ran across this post today:  http://blog.bitquabit.com/2009/07/01/one-which-i-call-out-hacker-news/ The basic story is that the author is refuting the claim that StackOverflow.com could be replicated “easily”.

I think this is an awesome post because it’s a warning to others and reminder to myself that everything is not as easy as it seems.  Often we look at an application and say, “I could do that.”  Yes, you could.  Without a doubt.

Here’s my advice though:  Take your estimate of weeks and make it months and turn months into years and you’ll probably be closer to the truth.  Even copying user interface and data structures verbatim I think most people would still have a hard time replicating an existing application quickly.

One project I worked on was a QuickBooks-like accounting application.  On a four person team.  Five days a week.  For FIVE YEARS!  And we had QuickBooks as the blueprint, if you will, for the accounting side of the application.  Guess what?  Even though I’ve moved on they’re STILL adding to and modifying the accounting engine.  QuickBooks is a moving target and I wish my old teammates luck in striving for it.

Every now and then someone gets a hair up their rear end and brag that THEY could do REALbasic better than REAL Software (because some bug has really pissed them off).  It’s quite possible that someone out there is working on an awesome RB clone and someday release it.  But don’t expect it anytime soon.

The same goes with claims of “I could easily make the RB IDE do this or that!”  If it was easy no doubt RS would already have done it.  Let’s face it, software is often a case of the mistakes of the father now make our lives a living nightmare.  This is not to knock our forefather developers just that what seemed like the best way five or ten years ago is woefully inadequate in today’s terms and to make it do ‘x’ (which seems easy) isn’t because the infrastructure isn’t there to do it.  So the whole thing has to be redone and done so you don’t break backwards compatibility.

Again, sorry for the blog about another persons blog.  I hope you find these discussions helpful and thought provoking.  Thoughts?