|
| |
August 6th, 2008
Never assume that the user will never encounter your crazy error condition. "I’ll put this in a message box for me to see it" is what you might think. "They’ll never see this in the field" is a tempting thought. But then your users might end up seeing something like this:
I can see a line number from a C++ file and some variables being printed to the screen, but what am I supposed to do with that? Is this error bad enough that I should reboot? Should I tell the vendor? Ok, now which application actually popped this error? Was it a browser? Outlook? or maybe Vista itself? I really have no clue. And if my mom ever got this error, she’d be even more lost than me.
So even though you’re sure that the error condition in your if-else block will never happen and there’s no way the user will ever see it, just remember this blog post.
July 16th, 2008
One of the things that was hard for me to get past when transitioning from C++ to C# was the lack of a ‘const’ keyword. Sure C# has ‘const’ (albeit a weaker version), ‘readonly’, and ”final’, but none of them have quite the same semantics as the good ol’ C++ const. In C++, I could do something like this:
void DoStuff() { const int MaxAmount = CalculateMaxForToday(); if(MaxAmount > 5) { // do stuff } . . . // do some more stuff . . . // do stuff at end Sum += MaxAmount; }
What I like about that is that I declared MaxAmount as a constant integer and it cannot be changed for its entire lifetime (at least without some semi-major hacking to get around the compiler complaining about it). What I did there was I said that MaxAmount will be constant. I don’t intend it to change for its entire scope. I like to think about that as “Intent Programming”. I program my intentions into the code. No comment is required. I don’t need to say “// MaxAmount shouldn’t change”. The compiler will enforce the const-correctness for me.
What that also means is that when I get moved off the project and someone else comes on to maintain the code, my intentions will still be enforced. The compiler will enforce them and will protect that variable from accidental or even intentional modification. If the new guy doesn’t see MaxAmount being used at the end of the function, he may decide that it’s safe to change it. He may decide to re-purpose it it in the middle of that function around the “do some more stuff” section in my example. In C++, the compiler will prevent this. In C#, there’s no way to do this. Declaring a variable as ‘static readonly‘ will accomplish this for static variables, but for local variables it just ain’t gonna happen.
This is also why I love the ‘using’ keyword in C#. I have heard that it was tacked on as an afterthought when designing C#, but I love it nonetheless. It allows you to do stuff like:
public void DoDotNetStuff() { . . . using (System.IO.Stream stream = wc.OpenRead(url)) { avatar = image.FromStream(stream); stream.Close(); } // can’t use stream over here . . . }
Outside of the using block, stream is out of scope. It’s the same as declaring it inside its own scope. You try to use it outside the using block and:
error CS0103: The name ’stream’ does not exist in the current context
As long as System.IO.Stream implements IDisposable, you can exactly control the lifetime of your variable and you don’t even have to bother messing with the Dispose method. Your variable is scoped, disposed and garbage collected all in one neat and tidy package. You programmed your intent for the usage of that variable right there in the code itself. No comments required.
Sometimes this is called ‘Self Documenting Code’. I tend to think of Self Documenting Code as a style of code organization and a usage of long names to describe what the code is doing. With intent programming, you’re using the features of the language itself to help declare your intent.
June 24th, 2008
I was called out by Dan Rigsby to do this, so here she goes:
- How old were you when you started programming?
I believe I was 12 or 13.
- How did you get started in programming?
I remember learning some BASIC in school in either 6th or 7th grade. Ya know, you draw a blocky gun and make it fire a one pixel bullet across the screen. I remember that being pretty fun. Also, right around the same time I started playing with QBASIC at home.
- What was your first language?
BASIC/QBASIC
- What was the first real program you wrote?
Not counting school, the first real program I wrote was a spaghetti code version (chock full of GOTO’s) of a Choose Your Own Adventure book.
- What languages have you used since you started programming?
BASIC, QBASIC, C, C++, MIPS Assembly Language, VB, ADA, Java, C#, ASP.NET, Javascript
- What was your first professional programming gig?
I was a lab TA for the CS101 Java course at Purdue, so that was my first job involving programming, but my first job actually programming was at Raytheon. I worked there for six years before coming to Interactive Intelligence in 2006. At Raytheon, I worked on various project for the Army and Navy involving mortar aiming applications, handheld applications, route planning applications for helicopters and many other things. If I tell you anymore I’d have to kill you.
- If you knew then what you know now, would you have started programming?
Definitely. Whenever I get asked what my dream job would be I always reply that it would be doing what I’m doing now (programming) or touring in a band. I deeply enjoy them both. But I must admit that programming for myself and writing whatever I want to write at the time would definitely be better than the maintenance programming I sometimes still have to do.
- If there is one thing you learned along the way that you would tell new developers, what would it be?
Don’t waste time. I can think of numerous times in college and after college that I just screwed around and did other things when I could have been honing my skills more and keeping myself up to date. I’m trying to get myself back up to date now and it would have been easier if I had just spent the time after college to do so.
- What’s the most fun you’ve ever had … programming?
I love programming for fun. Right now, my extracurricular programming activity is writing Bitter a Twitter/social networking client. In my spare time, I’ve also written a chat program, an email application, an account/password manager, an RSS aggregator and several Pocket PC applications including a file explorer, an RSS aggregator, a network scanner, and various other tools. I just find it a great way to learn and to me it’s extremely fun.
- Who are you calling out?
I want to call some fellow bloggers and non-bloggers alike (to see if they’ll actually start):
May 27th, 2008
I’ve been thinking about how to do this recently with Bitter. When you have an update for your application that you want your users to have, how should you push it down? I see four distinct levels of updating:
Manual Check and Web Page Download
You can require the user to manually go the web page, check for a new version, download it and copy it over the old application. This is obviously the worse way to go from a usability perspective, but also requires little to no work for the developer (other than packaging up the new version). This is probably ok for applications that are seldom used, not popular, or maybe only for a select group of users, but not ok for anything other than that.
Automatic Check and Web Page Download
In this scenario, the application would automatically check for updates and alert the user of such, but would still require the user to actively download and “reinstall” the application. This only requires the application to download a file stored on the file that contains the currently released version number and compare it against it own. The developer would also need to manage the version number file and update it accordingly. Not difficult to accomplish and it gives you a little more bang for your buck.
Automatic Check and Automatic Download
With this version, the application would both check and compare the versions and then would automatically download the new version of the application with the user’s approval. It may also even copy the application in place over itself and restart the application. This is what I’ve currently done with Bitter as I document in this post. This is still not that hard to accomplish. In .NET, I showed that doing this is only about 10 lines of code of any real meat (not counting exception handling, logging and message boxing).
Automatic Check and Automatic Install
Here the application automatically checks for updates and automatically installs updates. No user intervention required or possible.
So what’s the best way to go? With Automatic Check and Automatic Download, the user still has to tell the application to download and install the updates. It’s up to the user. In Automatic Check and Automatic Install, the user has no choice. He is going to get the update or he ain’t running the application.
One of my new favorite applications Digsby, uses the Automatic Check and Automatic Install approach. When you login, it will check for updates and automatically install them. You don’t have a choice. This is good because the user doesn’t have to do anything special. They will always be up to date. This is good for the developer too, since the developer knows that if you are running the application you will have the latest version (or at least the next time you start). But what if you don’t want the update? It’s not uncommon for developers to introduce new features as well as new bugs into an application in an update. If you know about the new bug introduced in the next version, but need to login, what are you going to do? You don’t have a choice but to accept the update, get the bug, and hope another update with the bug fixed will be coming soon (and hope that no other additional bugs will be introduced as well).
On the other hand, if you don’t force updates, your user base could become this heterogeneous mixture of versions that you have to support and that your website has to support. If version 1.0 is checking for updates in a certain path, but the current version is checking for updates in another path, you either need to support both paths for an indeterminate amount of time or just let v1.0 break. Not only that, but users running older versions might request features that are already fixed and they have no real obligation or motivation to move to the next version. They could stay there using v1.0 until our insect overlords come and take over. Is that ok (the versioning thing not the insect thing)?
One more facet to consider with support is that businesses typically want to test Windows updates before deploying them across their organization. This often means that organizations and the multitudes of computers behind them can be several versions behind the current one in whichever OS they are using. If this describes the situation of your application, then the decision is already made for you. No auto updating otherwise your application will be passed up for another that does allow less-automatic update installation. However, most of us (thankfully?) aren’t in that category.

Arguably one of the best if not the best free Photoshop-like applications out there, Paint.NET, does not force you to update. It shows you that an update is available when you start up the application and you can check for updates through the menu, but you aren’t forced to update. And you know where it’s gotten them? I’m running version 3.10 on both of my home computers even though the current version is 3.31. I’ve seen the update dialog for months now and still haven’t installed the update. I’ve not intentionally not installed the application, it’s just that the version I have seems to work fine and I really don’t know how much trouble it will be or how long it will take to install the new version even though I’ve never tried. I simply don’t want to be bothered with it.

Where does that leave us?
The Automatic Check and Automatic Download method gives the user more control and keeps the user in the loop, but… it keeps the user in the loop. Most users don’t care about versions, they always want the latest. That may mean that we should use the Automatic Check and Automatic Install method, right? But doing that will piss off the 1% of users that actually want to control their versions let alone the business users. And what’s worse is that this method is all or nothing. You can’t let most users automatically update and then let other users choose which version they want. If that’s the case, then you’re automatically back in the Automatic Check and Automatic Download way of things with the support troubles and versioning nightmare.
So what’s it going be? Should you just cater to the common case or do you want to attempt to make all your users happy?
May 21st, 2008
In my quest to make my Twitter client Bitter as easy to use as possible, one upgrade I had considered was making it auto-updateable. You click a button, it updates. Done.
As most things in .NET, it turned out to be relatively simple. You download the file, you move it on top of the running app, you restart… all neat and tidy. So without further ado, here’s the code:
private void UpdateApplication(string applicationDownloadURL) { string downloadedFilePath = System.IO.Path.Combine(System.IO.Path.GetTempPath(), “bitter.exe”);
// download the exe bool shouldContinue = true; try { WebClient wc = new WebClient(); wc.DownloadFile(applicationDownloadURL, downloadedFilePath); } catch (Exception ex) { shouldContinue = false; }
if (shouldContinue) { // get running app path string appPath = Application.ExecutablePath;
// copy over running app try { // create archive’s app path string archiveAppPath = appPath + “.old”;
// delete any old archived apps, archive the current app // and move the downloaded app in place System.IO.File.Delete(archiveAppPath); System.IO.File.Move(appPath, archiveAppPath); System.IO.File.Move(downloadedFilePath, appPath); } catch (Exception ex) { shouldContinue = false; }
// restart the app if (shouldContinue) { Application.Restart(); } } }
Of course you should add logging and user feedback where appropriate. This is just skeleton code that gets the job done. Enjoy!
May 10th, 2008
I know you’ve probably heard this before, but it bears repeating: set the default options for your application how most users will want them. Do not expect your users to go into the options and tweak them. They won’t do it. And don’t think that normal users won’t care, but advanced users will go in there and change them. They probably won’t either. Just think of all the applications you use and think of how many times you’ve tweaked the options. I know I very rarely do. Just a couple in Firefox, one or two in Visual Studio. That may speak to how well their default options are, how I simply didn’t know that I could change that option or how I just don’t know where to look. In the sea of tabs, combo boxes, and check boxes, how are most users (let alone most users’ mothers) supposed to know where to look to make cookies work or change the default formatting when replying to emails or keep iTunes on top of all windows?

I experienced this first hand tonight. My brother-in-law recently bought a new Toshiba laptop, all nice and lightweight and filled with memory that’ll never get used. Since he bought it last week he hasn’t been able to login to various sites including eBay, his bank and some other sites. Interesting isn’t it? A new computer shouldn’t have any problems like that. So we went over to their house tonight and I take a look. We open it up, I bring up eBay and the homepage shows fine. “Wait til I login” he says. Name, password, submit…

Sounds simple enough, right? I need to mess with the cookie settings. Ok, cookies, cookies… where were those again?

Lucky for me, I know that the privacy tab configures how the browser handles cookies, but my brother-in-law didn’t. He’s a pretty average user: definitely not as ignorant as my grandma, but he’s no developer either. He very well might have known where to look, but in this case he didn’t. He’s never needed to before.
Would you have known? Have you ever customized your privacy options? I always tell myself I should, but I never have. What’s there works and I’ve never had any problems… famous last words, huh? His computer for whatever reason came with all cookies being blocked by default. Sure it’s more secure, but it’s by no means usable and would never be fully usable by him until he got it reconfigured.
So why did it come so locked down? Did the OEM fall into the trap of thinking that users always customize their apps? I don’t know. But you should know better than to think this. As Jeff Atwood said:
For most users, the default value is the only value.
So always install your applications thinking that the options will never be touched again… because they probably won’t.
April 30th, 2008
How many browsers do you test with? I’ve got five… and all on the same computer at the same time. Of course, we have Firefox, Opera, and Safari. Those are usually the easy ones to get right. But wait there’s two more.
You can install the beta of IE8 right now, but doing that takes IE7 off your system, right? Not unless you have IE Tab installed. IE Tab is a Firefox add-on that loads the IE ActiveX control inside of a Firefox tab. But not from IE8 that you just installed, it loads the IE7 control. Sure you can emulate IE7 inside of IE8, but you need to restart the browser to enable and disable emulation. With the IE Tab trick, you can develop web apps and have all five browsers up at the same time.
Of course, I’m not saying that you shouldn’t test on the same browsers in other platforms. This is just a great place to start.
April 7th, 2008
What is the first thing that you think of when you think about good software design? Extensibility? Interface programming? Loose coupling? Simplicity? TDD? Everyone has an opinion on what makes a good software design, may it be a thorough use of design patterns, conforming to coding standards, or just easy to understand… everyone has an opinion. It’s not hard to find lists of good elements. Just Google for it and you might come up with this list:
10. Considers the Sophistication of the Team that Will Implement It 9. Uniformly Distributes Responsibility and Intelligence 8. Is Expressed in a Precise Design Language 7. Selects Appropriate Implementation Mechanisms 6. Is Robustly Documented 5. Eliminates Duplication 4. Is Internally Consistent and Unsurprising 3. Exhibits Maximum Cohesion and Minimum Coupling 2. Is as Simple as Current and Foreseeable Constraints will Allow 1. Provides the Necessary Functionality
We all want to create good designs… something elegant and beautiful yet works perfectly. It should be easily understandable, or maybe diligently complex (hey, some people just like complex designs). Either way, whatever good design is, we want it.
But how about bad design? We seem to always know it when we see it (usually because it’s any design other than our own) and can immediately point out each area that is “incorrect”. But what are the real characteristics of bad design? What is something that you definitely do not want in your design?
How about Rigidity?
Is your software difficult to change? Does one change in one class in one module result in a cascade of changes throughout the class, throughout the module or even throughout the application? If modifying your application even minimally becomes an enormous task, you might have a rigid design.
Is your design Fragile?
We aren’t talking about the leg lamp here. We’re talking about design that breaks easily and often. Does making another small change in one component break something in another component? Do unexpected parts break when making unrelated bug fixes? Well then it just might be fra-gi-le.
Is it as Immobile as that car on blocks down the street?
Have you written some classes for your application that are banished to be stuck there forever? Are they coupled tighter than those two weird kids at prom? If so, your code is immobile my friend.
How Viscous is it? I said viscous, not vicious.
Do you write code that makes it easy to do the right things and difficult to do the wrong things or is it much easier to cut and paste the same thing a million times rather than reuse the original code?
Is it Complex just for the heck of it?
Is your code complex just to prove how smart you are? Or maybe to secure your job at Initrode so that the new class of freshouts can’t steal it away? Or maybe because you just don’t know any better? Well, that’s needless complexity at its best.
Does it Repeat, Repeat, Repeat, and then Repeat some more?
Is your motto “copy and paste away”? Have you ever realized that one of your for loops needs an extra check and then shed a tear when you realize that you need to make that same change in 42 other files? Did you skip over the DRY design principle when cramming for your software design exam in college? If so, then you’re bound to repeat your mistakes in life… as well as in your code.
Is it and by that I mean Opaque?
Can no one else understand you code? Does everyone groan when they have fix bugs in your old code? Do you groan when you have fix bugs in your old code? Your code may just be opaque then.
There are many ways to design a software system; some are good and many, many more are bad. Next time you design anything, whether it be a complete system, an application or just a component, make sure you smellcheck it and deodorize if necessary.
March 25th, 2008
Jeff Atwood recently wrote about the Choose Your Own Adventure books and how they are early programming books. I couldn’t agree more. I owned a few in my childhood and have fond memories of them.
There were imitators like with anything that successful, and there were a few good ones (even some D&D flavored books), but the CYOA books were the originals.
For me, they more than sparked my interest in programming, they almost single handed started me programming. The first program of any real depth that I wrote was a QBASIC application that mimicked a typical book of the CYOA series. We all remember QBASIC right?
Anyone remember the one huge improvement that QBASIC had over BASIC? That’s right… no more line numbers! BASIC forced you to type a number at the beginning of each line. Don’t you try try to go back and add in too many lines near the beginning of your program, else you’ll be sitting there for a long time.
Anyway, so my program was a text based application that would basically give you a description of your current situation and ask you to make a choice. Very typical of the CYOA books. So you make the choice and then the whole thing repeats. Had I been smarter and more experienced, I would have done this in a loop with an array of objects or used a tree or something like that, but alas my original program was chock-full of goto statements. There’s no maintaining this application after the original version. But that’s ok. After a little while I could see the spaghetti-fied, spider-webbed, maze of death mess I had just created and I soon realized the difficulty and the magnitude of problems of the field in which I was entering. I grew a little that day and have tried to grow each day since.
That application was the first application I had written for fun, and it hasn’t stopped since. I’ve messed with writing an AI command prompt, a chat program, a file explorer, and a news reader, but my obsession as of late is a Twitter client named Bitter. (So now you now why the blog posts have been few and far between as of late.) When Bitter finally gets released (hopefully in a couple weeks), I can get back to blogging. In the mean time though, check out Twitter. This is yet another new Web 2.0 thing I first assumed was just for the punk kids nowadays and I wouldn’t like it, but now I can’t live without it. It’s a social site/service that allow you to post what you’re up to, what you’re thinking about, cool links you’ve found, and even allows you to use it as a public chat with other Twitterers. Here’s a cool tutorial explaining it. Anyway, I’m on Twitter as mikehall and wouldn’t mind seeing some other people on it.
So what was your first program and what’s been your latest obsession?
March 19th, 2008
I attended the Microsoft DevCares event here in Indianapolis a few weeks ago. It might not be on par with MIX, but whatcha gonna do? Anyway, the event was broken up into two sessions: security and Office.
In the security portion of the event, we looked at some common web exploits, how they work and how to fix them in your code. We went over cross-site scripting, cross-site request forgeries, SQL injection, insecure direct object references, information leakage and improper error handling, and broken authentication and session management. The presenter demo’d each one with a fictitious product website and some exploit code. It was pretty interesting although I had seen most of the demos already when I attended the previous month’s MSDN event on IIS7 and ASP.NET 2.0 application services.
We then broke in the Office integration session. Mostly talk around VSTO, WWF, Ribbon development and ClickOnce deployment. Not too bad, but not my cup of tea.
Anyway, I couldn’t get the exploit code, but I have the PowerPoint slides for anyone that wants them:
|
| |