Is Good Code Impossible? Part 2: Project Manipulation Patterns
This blog is the second part of my post, Is Good Code Impossible?. In it, I go through a case study of a project with “Gorilla Mart” that illustrates how difficult it is to maintain good coding practices in contract- and commercial-based software.
I’ve gotten a lot of feedback on Part 1 of this blog series and quite a few of you have been quick to lay blame on the developer, while the rest have sympathized as having been there before. You’re all right! And what I hope to lay out for you now is not some generic contracting checklist we’ve seen a million times, but for once begin to outline a very clear, clever, and repeated strategy that clients will use to manipulate a project. When we’re all done, we’ll tie it all back to good code and why it’s so difficult to execute on it and how we *CAN* change things to make it possible once more.
Oooooooooh it sounds cool, let’s go!
The Basic Project Manipulation Patterns
The client is bright. You, the developer, are also bright. Two smart entities should be able to run a project that’s smooth and free of problems. But, we know that never happens! So, why not? Well, the reason is that the client and developer are not on the same side. Neither is good or bad, but both are expectedly self-serving.
The developer’s goal is to either finish a flat-rate contract under-time or up-sell features for an hourly-rate job. In either case, profits are maximized. When a project has risks, the developer hopes those risks are unfounded. If new technologies are required to complete the job, the developer holds hopes that their inexperience in those areas does not cause delays. In summary, the developer wants maximum money for minimum work.
The clients’s goal is to get the most work possible from a flat-rate contract or get the most work done in the fewest hours for an hourly-rate job. They expect bug-free code — done fast! They want the project to be done on time, preferably early, and have their product (A) making them money right away and/or (B) be able to bring it in-house to plan out future money-making updates. In short, the client’s goals are the exact opposite of yours.
Now, think back to every project that didn’t go as planned. You’ve no-doubt taken a host of lessons from these: maybe you didn’t nail down the requirements well enough, you mis-estimated the client, or perhaps there were too many bugs and you spent too much time fixing them to cut a good profit (i.e., your hourly rate dropped too much). Think about each of them. And, if you do, you’ll realize that there are several patterns that emerge.
Yes, patterns. Like design patterns. What I’m about to tell you is that clients have a set of patterns, strategies if you will, to meet their goals for a project. So let’s do this thing — we’re on to you, fellas! Let’s reveal the client gameplan!
False Representation
The next time you’re establishing a contract with a new client, pay attention, because this one *ALWAYS* happens. Here’s how it’s done.
The client contacts you with a project proposal. The project is “pretty straightforward” or “simple.” All you need to do is maintain a list of ___________ that you retrieve from a server they already have. Or maybe they “have a guy” who can do it in no time. The user does a few “basic” things and there ya go, the app is done. They might need a “couple of extra features” but “for the most part” that’s “about it”.
Sound familiar? Of course it does.
False Representation is the client’s tactic of delegitimizing the project’s complexity. You’ll be led to believe that the work is simple and if you don’t think it’s simple then you’re probably not cut out for the job. The macho pride that is the hallmark of every quality developer is a strength that is manipulated into a weakness in such a way that would make Karl Rove proud. (From his rotting, underground lair.) To be honest, clients may not even realize they’re doing this. All they want is get you to quote a cheap price. You can’t blame them, really. It’s their job.
One of the worst cases of this I’ve ever seen happened when a Network Diagnostics company came to us about re-implementing their Java-based application in Flex. The pitch was classic False Representation:
What we need is a simple port of our application from Java to Flex. We understand that Flex applications can be built much quicker and, since the application already exists, we won’t even need requirements. Nothing complicated. We’ll arrange for each of you to have a copy of the application and the source and we’ll have a small team available for consulting. It should be a piece of cake for you guys.
The sign that you’re getting hit with this tactic is the soothing language. Everything will be simple. The app is very straightforward. These guys even went the Full Monty on us and presented one of the most misleading tours of their product imaginable: they showcased the two main screens of the applications, discussed the behavior, and called it a day.
I wasn’t part of that presentation, but the initial SWAG was made based on it. After I joined the team, another presentation was made before kicking off development. Screen after screen after screen after screen…it was endless. Where developers were previously convinced that the other screens were very much the same, the client had not let on that the data and behavior were completely different — and there was a LOT of data, and it all required more custom behavior. After the meeting I was like, “You guys think this is two months?” and they explained how they hadn’t seen 85% of the stuff they just saw.
What was initially SWAG’d as a two-month effort took us a full year. The lesson here is that when discussing requirements with the client, either at introduction or in a formal analysis session, *IGNORE* their vocabulary. If the client thinks a feature will be easy to implement, ignore them. Evaluate it on your own. And if they’re demo’ing an application, keep a keen eye out for every menu item, every view, every corner and crevice of that application. And get a copy to play with yourself before you SWAG anything.
It’s a Bug, Not a Feature!
A favorite joke amongst developers is to be presented with some of the strangest, buggiest behavior in our code to which we reply, “That’s a feature!” While it’s just a joke for us, the opposite phrase will be a favorite of your clients’ — and it ain’t gonna be a joke to them.
The basis of It’s a Bug, Not a Feature! comes in the root philosophy of flat-rate contracts. The idea is that you are guaranteeing a set of functionality in exchange for a sum of money. The expectation is always that this functionality is only considered complete when there are no significant bugs included in it. The problem is that I have never, ever seen any language that defined exactly what constitutes a “significant bug” included in an SOW (Statement of Work).
Have I seen some language on it? Sure. Not always, but on occasion, yes. But it’s certainly not the kind that a lawyer has gone through. The difficulty is that bugs come in so many shapes and sizes, it’s simply impossible to classify them well. On top of that, as a developer, you will be inclined to win some equity from the client by fixing some bugs you wouldn’t otherwise need to. (Yeah, the easy ones, but still, they don’t know that, and you’re doing it for free anyway so you should get credit, right?)
What occurs is a tango between client and developer. The Tango Cod-ing. (Any Rent fans in the house?) Once the client starts receiving builds, the dance music begins. These buttons should be a darker shade of blue. You didn’t specify they should be skinned. Yes, but I can’t see them. Skinning them wasn’t in the contract, and I can’t draw. But, if they don’t stick out to the user, the app is broken. It’s a bug. Fix it or you don’t get paid!
It’s my belief that it’s the developer’s experience that determines the effect this has. The experienced developer is adept at identifying where a client has misunderstood what they themselves say they want. These developers have gained a feel for where the problems will be later and either (A) address it during the requirements gathering phase or (B) forsee it and code it the right way anyway. They know that they have gone against the will of the client, but they’re also confident they know it’s what they’ll want.
Experience can’t be bought. The less-experienced developers will have to fight clients on these issues for a while before that intuition builds up. If you find this is happening to you, you can combat it somewhat by being more proactive with the client. Be pushy on their desires if you feel they will dislike their own idea later. Trust yourself. It’s what they’ve come to you for. Tell them why. Don’t be afraid, the client wants someone who can guide them. It will boost your credibility and ease your workload!
Deadline Shoveling
This is the one that sometimes makes me want to simply leave the industry entirely. :-) Tell me if this sounds familiar…and you don’t even need to be on a contract to have it happen…
You’re working on a 3-month project and there’s a week left. You’re excited! All the hard work is about to pay off in a released product. It’s going pretty well, but you have a little more work than hours available so you’re going to have to put in some 10 hour-days (at least). Monday, Tuesday go by and you’ve worked 21 hours. Wednesday you put in some serious crunch time and work until 2 AM. Thursday you still manage to push out a 9 hour day before heading to sleep early, but things look good for Friday! Friday comes and at about 10 AM you are pulled into a project meeting:
Jim just got off the phone with Bob and he said he wants to add a new screen that allows you to rotate the interface in 3D space. They can push the deadline a few days, but they really need to have it by Wednesday because there’s a tradeshow on Thursday and they really want to show this feature off to the industry drivers.
I really don’t know if these tradeshows exist, but they come up quite often, eh? It’s a great way to specify a deadline and not have to negotiate it. The client says they’d loooooove to give you more time, but the tradeshow can’t be pushed back. And now your manager has no room for negotiation. They want to keep the client happy and there doesn’t seem to be room for compromise. The killer feature the client decided 5 days in a advance simply had to be completed has to be shown off at the immovable tradeshow. And if the client were to become unhappy, at the last minute, your manager’s manager may not be too please come promotion time.
So, you have to kiss that weekend plus a comp’d Monday goodbye (no more Vegas!) and you put in 15 hours on Saturday and Sunday and a massive 26 hours Monday and Tuesday and you’re tired. But the code is in place — though it ain’t pretty. But, you’re done.
Wednesday comes, hold the phone. The design isn’t gonna fly. They’ve decided not to show it off at the tradeshow, but now they want to do a presentation for the CEO first-thing Monday morning. And guess who has to fix the design?
Don’t laugh, and don’t point fingers! This happens all the time! It transcends development, this is about business. Keep the client happy and future work will come. It’s justified by the fact that the project is almost over. It always seems to happen (to varying degrees) and it’s brutal. I was once on a project that had done this for months, sans the huge hours. After 4 months of having a deadline pushed at the last minute, I simply didn’t care anymore about the product. I hoped it would succeed, but I really didn’t care anymore. It’s massively demotivating. Development is about setting a goal and getting it done and celebrating the accomplishment. If you pull out the accomplishment, it’s just work. Never-ending work.
The only way to fight this is with good management. In many cases, this isn’t going to be on you. Your representation has to fight for you, and this may or may not happen depending on who it is doing it. Be sure to communicate the time you’re putting in and the de-motivation. Make it known that you want clearer milestones, that you are willing to do more work in a proper timeframe, but you need a realistic goal, predictibility and more trust in the client if you are going to create a great product.
Now Let’s Get Back to that Good Code, Shall We?
So how does this all relate to good code? Well, my gosh, it has everything to do with it! Look, you’re a developer capable of writing good code. How do I know? You wouldn’t even be reading this if you weren’t! How many happy-to-be-a-lacky developers will read an article about “good code?” None, that’s what. But *YOU* want to write good code.
Can you? Not if the client is pulling these shenanigans!
Get familiar with these tactics, learn how to prevent them, and you’re going to open yourself to a freer world of time and expectations. In that environment, you can take the principles your favorite authors have taught you and fulfill the implementation of a world of good design. With good project planning, minimal surprises, and creating a good pace with your team you can hit all of your milestones coding the way *YOU* want to be.
Good luck out there!
Are We Really Mobile Developers Anymore?
As developers, we tend to be categorized by our specialties:
There are backend developers, those who work with databases and scalable architectures with systems like Java EE or .NET.
There are Web developers, those who either specialize in PHP, Rails, and Django or perhaps HTML, CSS, and JavaScript.
There are frontend developers, specialists in the UI. Flex, Silverlight, Swin–*cough*–Swing…and we even sometimes refer to Web developers this way as well.
Then there’s the Mobile developer. We work with iPhone, BlackBerry, Symbian, Android, Java ME, and whatever Windows phones remain on the planet.
Five years ago, I could give you a long list of reasons why I’d be more qualified to take on a new mobile project, even if it was a new phone technology I was unfamiliar with. When the iPhone was released in 2007, I knew I was more qualified than any other non-mobile developer to take a stab at writing an app. It wasn’t that I knew iPhone (or Objective-C, or even Mac!), it was that I knew mobile. I was a mobile guy.
Here’s a long list of qualifications that I believe defines the classic mobile developer:
- Writes code in a low-memory environment, handling more common out-of-memory errors and creating low-memory algorithms.
- Writes highly optimized code that runs efficiently on low-performance devices.
- Writes applications that can target a diverse set of devices that may include black & white vs. color screens, tiny to moderate amounts of RAM, differing platforms such as MIDP1 vs. MIDP2 or CLDC1 vs. CLDC1.2, etc.
- Writes software for a platform other than the machine they’re developing code on.
- Has the knowledge to install applications in a variety of ways depending on individual platform requirements. (USB, Over-the-Air, serial cable, etc.)
- Writes software on obscure platforms like Java ME, Windows CE, or the hybrid BlackBerry API.
- Able to code to multiple API’s at once, for example when GPS was still being standardized and you had both JSR 179 and private API’s for varying phones that produced varying results. (Good luck with device coverage back then!)
- Able to design an application that can be built by multiple SDK’s simultaneously.
There’s more, but let’s stop here. Hopefully we can agree that these qualities are what allowed us to identify a mobile developer as such.
Something’s changed, though. It happened subtly. Back in the “old days,” phones came and went quickly, all with their own private API’s, and the technology was improving rapidly. We saw Java phones, BlackBerry’s, Windows, tons of manufacturers like Symbian and Samsung and all the PAYGO phones.
Nowadays, things have slowed down.
The New Mobile Developer
In the last three years, the mobile landscape has been dominated by just three platforms: iPhone, Android, and BlackBerry. I exclude Palm from this because, well, no one has a Palm. (BURN!) And I’m eager to drop BlackBerry as well because RIM has always been awful at cultivating a development community. There are plenty of other phones, and some, like Symbian, still control major portions of the market, but we all know that’s going away soon.
Over these three years, we’ve seen iterations of the iPhone along with iterations of their SDK. Even when the iPad was introduced, the SDK was almost exactly the same, and you could build for both iPhone and iPad easily. When the iPhone 4 was released with a higher-res screen, they made sure is was exactly twice the size. Not only was it simple, you retained all your skills and didn’t have to deal with a new, custom SDK.
Android phones have come out in large droves as well. While I predict that Android-powered phones are breaking the market up into so many pieces that developers will soon flock in droves away from the platform, it’s still an important one today. (Java ME developers know what I’m talking about — that feeling of wanting stab yourself with something very sharp come deployment time.)
The iPhone benefits from modern software modules. Remember the past when you needed an XML processor and you were forced to choose from libraries that might be called MiniXML or TinyXML? Not anymore. I remember spending DAYS trying to find a SOAP library for Java ME. I ended up having to roll my own. :-( Today, most of the Mac libraries used for desktop development now work for the iPhone untouched.
The same goes for Android. The limitations of Java ME made using modern Java libraries impossible, and there simply wasn’t significant demand to have them all re-written. Android has more power, and with it, most Java frameworks can be installed on the phone without issue…and if there is a problem, there is significant motivation to make it so. And it’s easy to do compared to doing it for Java ME.
Also, thanks to these new phone lines, low-memory and low-performance considerations are fading away. Play with an iPhone 4 for just a minute and tell me that you’ll need a mobile developer to be able to write software for it. HA! It runs faster than my laptop did just 5 years ago. (Not fair, that was a Windows machine.) Any serious developer can take their turn at it. Finally, quality software and competition is at the forefront, not fringe software availability.
You see this difference every time you look for an application for a favorite website of yours, and are literally outraged if it’s not there. “How could they not have an iPhone app??” You had zero expectations when you had your free Java phone.
I’m a Mini-Frontend Developer
For the sake of marketing, I do consider myself a mobile developer. I advertise as such and I regard Rapture In Venice as a mobile solutions provider. But, is the work I’m doing similar to what it was a few years ago when I was pumping out Java ME and BlackBerry apps for my clients? Certainly not. The only difference between me and a Mac programmer is a resizable window bar.
Is Good Code Impossible?
This blog seems to have sparked a little bit of backlash towards me as if I were an irresponsible developer making things worse on my peers. I assure you, it’s not true. Sometimes, in business, we have to be willing to accept a little more work than we’d like or a little more hardship in general to gain something back. What was gained from the client was (A) good notoriety for having worked with them and (B) the promise of a longer and more lucrative Phase II. In all things, there is give and take. We gave as much as took.
—
When you hit your teenage years you decide you want to be a software developer. During your high school years, you learn how to write software using object-oriented principles. When you graduate to college, you apply all the principles you’ve learned to areas such as Artificial Intelligence or 3D graphics.
And when you hit the professional circuit, you begin your never-ending quest to write commercial-quality, maintainable, and “perfect” code that will stand the test of time.
Commercial-quality. Huh. That’s pretty funny.
I consider myself lucky, I *love* design patterns. I like studying the theory of coding perfection. I have no problem starting up an hour-long discussion about why my XP partner’s choice of inheritance hierarchy is wrong — that HAS-A is better than IS-A in so many cases. But something has been bugging me lately and I am wondering something…
…is good code impossible in modern software development?
The Typical Project Proposal
As a full-time contract developer (and part-time), I spend my days (and nights) developing mobile applications for clients. And what I’ve learned over the many years I’ve been doing this is that the demands of client work preclude me from writing the real quality apps that I’d like to be.
Before I begin, let me just say it’s not for a lack of trying. I love the topic of clean code. I don’t know anyone who pursues that perfect software design like I do. It’s the execution that I find more elusive, and not for the reason you think.
Here, let me tell you a story.
Towards the end of last year, a pretty well-known company put out an RFP (Request for Proposol) to have an app built for them. They’re a huge retailer, but for the sake of anonymity let’s call them Gorilla Mart. They say they need to create an iPhone presence and would like an app produced for them by Black Friday. The catch? It’s already November 1st. That leaves just under 4 weeks to create the app. Oh, and at this time Apple is still taking two weeks to approve apps. (Ah, the good old days.) So, wait, this app has to be written in…TWO WEEKS?!?!
Yes. We have two weeks to write this app. And unfortunately, we’ve won the bid. (In business, client importance matters.) This is going to happen.
“But it’s OK,” Gorilla Mart Executive #1 says. “The app is simple. It just needs to show users a few products from our catalog and let them search for store locations. We already do it on our site. We’ll give you the graphics, too. You can probably — what’s the word — yeah, hardcode it!”
Gorilla Mart Executive #2 chimes in, “And we just need a couple coupons the user can show at the cash register. The app will be a throwaway. Let’s get it out the door, and then for Phase II we’ll do something bigger and better from scratch.”
And then it’s happening. Despite years of constant reminders that every feature a client asks for will always be more complex to write than it is to explain, you go for it. You really believe that this time, it really can be done in two weeks. Yes. Yes! We can do this! This time it’s different! It’s just a few graphics and a service call to get a store location. XML! No sweat. We can do this…I’m pumped! Let’s go!!!
It takes just a day for you and reality to once again make acquaintance.
Me: So, can you give me the info I need to call your store location Web Service?
The Client: What’s a Web Service?
Me: ………..
And that’s exactly how it happened. Their store location service, found right where it’s supposed to be on the top-right corner of their website, is not a web service. It’s generated by Java code. Ixnay with the API-ay. And to boot, it’s hosted by a Gorilla Mart strategic partner.
Enter the nefarious “3rd party.”
In client terms, a “3rd party” is akin to Angelina Jolie. Despite the promise that you’ll be able to have an enlightening conversation over a nice meal and hopefully hook up afterwards…sorry, it ain’t happenin’. You’re just gonna have to fantasize about it while you take care of business yourself.
In my case, the only thing I was able to wrestle out of Gorilla Mart was a current snapshot of their current store listings in an Excel file. I had to write the store location search code from scratch.
The double-whammy came later that day — they wanted the product and coupon data online so it could be changed weekly. There goes hardcoding! Two weeks to write an iPhone app have now become two weeks to write an iPhone app, a PHP backend, and integrate them togeth–what? They want me to handle QA, too??
To make up for the extra work, the coding will have to go a little faster. Forget that abstract factory, use a big fat for loop instead of the composite, there’s no time!!!!
Good code has become impossible.
Two Weeks To Completion
Let me tell you, that two weeks was pretty miserable. First, two of the days were eliminated due to all-day meetings for my next project. (That amplifies how short a timeframe this was going to be.) Ultimately, I really had eight days to get things done. The first week I worked 74 hours and the next week…god…I don’t even recall it’s been eradicated from my synapses. Probably a good thing.
I spent those eight days writing code in a fury. I used all the tools available to me to get it done: copy-and-paste (AKA re-usable code), magic numbers (avoiding the duplication of defining constants and then, gasp!, retyping them), and absolutely NO unit tests! (Who needs red bars at a time like this, it’d just demotivate me!)
It was pretty bad code and I never had time to refactor. Considering the timeframe, however, it was actually pretty stellar, and it was “throwaway” code after all, right? Does any of this sound familiar? Well just wait, it gets better.
As I was putting the final touches on the app (the final touches being writing the entirety of the server code), I started to look at the codebase and wondered if maybe it was worth it. The app was done after all. I survived. I SURVI-
“Hey, we just hired Bob, and he’s very busy and he couldn’t make the call, but he says we should be requiring users to provide their email addresses to get the coupons. He hasn’t seen the app, but he thinks this would be a great idea! We also want a reporting system to get those emails from the server. One that’s nice and not too expensive. (Wait, that last part was Monty Python.) Speaking of coupons, they need to be able to expire after a number of days we specify. Oh, and…”
Let’s step back. What do we know about what good code is? Good code should be extendable. Maintainable. It should lend itself to modification. It should read like prose. Well, this wasn’t good code.
Another thing. If you want to be a better developer, you must always keep this inevitably in mind: The client will always extend the deadline. They will always want more features. They will always want change — LATE. And here’s the formula for what to expect:
(# of Executives)2 + 2 * # of New Executives + Bob’s Kids = DAYS ADDED AT LAST MINUTE
Now, Executives are decent people. I think. They provide for their family (assuming Satan has approved of their having one.) They want the app to succeed (promotion time!). The problem is that they all want a direct claim to the project’s success. When all is said and done, they all want to point at some feature or design decision they can each call their very own.
So, back to the story, we added a couple more days to the project and got the email feature done. And then I collapsed from exhaustion.
The Clients Never Care As Much As You Do
The clients, despite their protestations, despite their apparent urgency, never care as much as you do about the app being on time. The afternoon that I dubbed the app completed, I sent an email with the final build to all the stakeholders, Executives (hiss!), managers and so on. “IT IS DONE! I BRING YOU V1.0!!! PRAISE THY NAME.” I hit Send, lay back in my chair and with a smug grin began to fantasize how the company would run me up onto their shoulders and lead a procession down 42nd street while I was crowned “Greatest Developer Ev-ar.” At the very least, my face would be on all their advertising, right?
Funny, they didn’t seem to agree. In fact, I wasn’t sure what they thought. I heard nothing. Not a peep. Turns out the folks at Gorilla Mart were eager to and had already moved on to the next thing.
You think I lie? Check this out. I pushed to the Apple Store without filling in an app description. I had requested one from Gorilla Mart and they hadn’t gotten back to me and there was no time to wait. (See previous paragraph.) I wrote them again. And again. I got some of our own management on it. Twice I heard back and twice I was told, “What did you need again?” I NEED THE APP DESCRIPTION!
One week later, Apple started testing the app. This is usually a time of joyousness but it was instead a time for mortal dread. As expected, later in the day the app was rejected. It was about the saddest, poorest excuse to allow a rejection I can imagine: “App is missing an app description.” Functionally perfect; no app description. And for this reason Gorilla Mart didn’t have their app ready for Black Friday. I was pretty upset.
I’d sacrificed my family for a 2-week super sprint, and no one at Gorilla Mart could be bothered to create an app description given a week of time. They gave it to us an hour after the rejection — apparently that was the signal to get down to business.
If I was upset before, I would become livid a week and a half after that. You see, they still hadn’t gotten us real data. The products and coupons on the server were fake. Imaginary. The coupon code was 1234567890. You know, phoney baloney. (Balogna is spelled baloney when used in that context, BTW.)
And it was that fateful morning, I checked the Portal and THE APP WAS AVAILABLE! Fake data and all! I cried out in abject horror and called up whoever I could and screamed, “I NEED THE DATA!!!!” and the woman on the other end asked me if I needed fire or police and so I hung up on 911. But then I called Gorilla Mart and was like, “I NEED DATA!!!!” and I’ll never forget the response:
Oh, hey there John. We have a new VP and we’ve decided not to release. Pull it off the App Store, would you?
In the end, it turned out that at least 11 people registered their email addresses in the database, which meant there were 11 people that could potentially walk into a Gorilla Mart with a fake iPhone coupon in tow. Boy, that might get ugly.
When it was all said and done, the client had said one thing correctly all along: the code was a throwaway. The only problem is it was never released in the first place.
Rush To Complete, Slow To Market
The lesson here is that your stakeholders, whether an external client or internal management, have figured out how to get developers to write code quickly. Effectively? No. Quickly? Yes. Here’s how it works:
- Tell the developer the app is simple. This serves to pressure the development team into a false frame of mind. It also gets the developers to start working earlier, whereby they…
- Add features by faulting the team for not recognizing their necessity. In this case, the hardcoded content was going to require app updates to change. How could I not realize that? I did, but I’d been handed a false promise earlier, that’s why. Or a client will hire “a new guy” who’s recognized there is some obvious omission. One day a client will say they just hired Steve Jobs and can we add alchemy to the app? Then they’ll…
- Push the deadline. Over and over. Developers work their fastest and hardest (and BTW are at their most error-prone, but who cares about that, right?) with a couple days to go on a deadline. Why tell them you can push the date out further while they’re being so productive? Take advantage of it! And so it goes, a few days are added, a week is added, just when you had worked a 20-hour shift to get everything just right. It’s like a donkey and carrot, except you’re not treated as well as the donkey.
It’s a brilliant playbook. Can you blame them for thinking it works? But they don’t see the god-awful code. And so it happens time and again despite the results.
Code Impossible
In a globalized economy, where corporations are held to the almighty dollar and raising the stock price involves layoffs, overworked staffs, and offshoring, this strategy I’ve shown you of cutting developer costs is making good code obsolete. As developers, we’re going to be asked told conned into writing twice the code in half the time if we’re not careful.
What can we do about it? Check out Is Good Code Impossible Part 2: Project Manipulation Patterns next.
The Three20 Framework: Should You Use It?
I was tuned in to the Three20 framework about 4 months ago just before we were to start work on an app for a pretty well-known sports retailing client. I was impressed with all the “goodies” it provided, specifically the photo browser, dashboard, and persistence system so that I could write an app that continued from where it left off when closed. I planned to have all of this in our new app, so I decided we’d base it on Three20.
There’s not a huge amount of material out there on the framework, so before you start wading through the Three20 documentation, separating the outdated material from the newer stuff, I hope to quickly review my experiences with the framework so you can decide if it’s right for you.
The Good
To start with, there’s plenty of GOOD in Three20. Actually, some of the best benefit is just going through some of the code. It’s pretty well-written and really flexes the iPhone SDK. But apart from that, there’s plenty of great stuff to use right out of the box.
URL Navigation
When you write your own iPhone apps, you may tend to have several areas of your code creating a UIViewController and pushing it on to the navigation stack. If you’re smart, you centralize this code so you can create settings pickers or photo albums in one place, even if you can navigate to them from more than one screen.
Three20 allows you to configure navigation maps that let you navigate easily via special URL’s which take care of displaying the appropriate screen. For example, you can set up tt://profile/photos to open and display a MyPhotoBrowser view controller.
It’s real handy. However, there are some complexities that may ding you later, especially in regards to providing arguments and sequencing several in a row. (All doable but have fun finding out how to do it.)
Useful Helper Methods
Three20 includes a large set of preprocessors, inline methods, and categories that really address the core of what you need to do often with the SDK. I wish a lot of these were in the iPhone SDK actually. Even when I decide not to use Three20, I’ve borrowed a lot of these for my own code (and added quite a few more!) My favorites include TTRectInset, calls that allow you to specify hex colors and, well, a ton more! You’ll just have to check em all out. ;-)
Overall, you’ll be inspired and become completely dependent on what’s in Three20. If you don’t use the library, it’s a great lesson to build your own!
Button Styles
Three20 comes equipped with a set of sample projects. One of those is TTCatalog, a great demo of everything in the library. When you go through it, you’ll find it impossible not to be endeared with the button skinning portion that lets you create buttons that look like they were iPhone native, all with variable sizing, arrow buttons, and more. It’s great work done by the team and easily the most useful part of the system.
TTImageView
Internally, Three20 has a module called TTURLRequest which leverages an even lower-level system to cache data that’s been downloaded. The combination of these two allows for the excellent TTImageView control to exist.
In short. TTImageView lets you to add an image to your interface that is loaded from the web. This is the simple kind of thing that almost every one of us needs at some point and it’s devilishly tricky to write correctly. TTImageView allows you to write this:
_logo.urlPath = @"http://www.raptureinvenice.com/images/logo-text-with-tag.png";
Why write your own? This one works and works wonders.
Views, Views, Views!
Three20 provides you with some pre-built screens that many of us require quite a bit:
- A Photo Browser — Very similar to what’s on the iPhone.
- A Photo Album — Displays multiple images in a grid space. Think: Photos app.
- A Dashboard — A re-implemented iPhone Springboard.
The Bad
Despite all the good stuff, there’s some stuff Three20 just didn’t get quite right. It’s not much, but even if you use Three20 you may want to avoid it.
Stylesheets
This is hard for me to put here because it’s supposed to be one of the sweet spots of Three20. Imagine! CSS! On iPhone! Well, I just don’t feel it’s done right.
For one thing, you can’t specify all of your properties in one place. Say you have a UITextField and you want to specify the text color, font, background color and some other properties. In CSS, all of this is included in one stanza, and it’s kept together. It’s easy to update, too. With Three20, though, you have to specify all of these values in separate places. The code gets bulky and it can get lost, especially because you’re not going to want to write 120 different methods that return a Helvetica Font.
I’ll set some standard colors such as the standard nav bar tint color or standard text color, but I find I really don’t use stylesheets otherwise. You’ll also find CSS simply isn’t as valuable on iPhone because there’s very little repetition going on anyway. It’s too bad, it should be one of the big wins in the framework.
Status Bar Color
This drives me crazy. Three20 decided it would be nice to take over how you set the status bar color for the app. Where once before it was simple, Three20 has made it complex. You have to specify it for every screen, and the default always seems to be gray. Ultimately, until you get it perfectly right, you get the joy of seeing your status bar change from gray to black or translucent as you go between screens. Lame.
To top it off, they don’t document what you need to do real well, so beginners will spend a good chunk of time trying to figure out why their UIStatusBarColor property isn’t working. I only accidentally stumbled on the fact that Three20 has hijacked this system and I’m so glad I did or I’d have spent hours tracking down my problems. ERRGGG!
Lack of Good Documentation
And that speaks to Three20’s biggest problem — the documentation is very poor. You will be completely dependent on the sample apps. And when there *is* documentation, you’ll find it’s often out of date. The forums aren’t exactly bustling, etiher.
Bottom line, if you choose to use Three20, be sure to give yourself enough time to pour through some code and search for the docs you need. And, hey, if you can, contribute some documentation back! :-)
The Ugly
Aside from the bad, some stuff is downright ugly and deserves a callout.
New Project Structure
Three20 recently changed their project structure so that instead of a single Three20 XCode project to include with your app, you now get 7. Now, presumably they separated it this way to remove some dependencies and make builds easier. The problem is that you often need to look through the Three20 code to figure out what’s going on and, well, you never quite know where to look. So you have to open project after project looking for what you need. It was so much easier before.
I hate it.
Table View Controllers
Three20 changes how you use tables, too. They’ve adopted a style where you define your rows in advance, and then the table just uses what you gave it. At first, I found this much simpler. However, there are simply WAY TOO MANY things that become more complex or downright annoying when you do it the Three20 way:
- Customizing individual rows – Forget it, it’s a nightmare.
- Caching/Optimization – You lose the optimized way UITableViewDataSource re-uses rows. It’s gone. So, don’t be using this system if you have hundreds of rows to display.
- Creating new row styles – Brutally obnoxious. The table framework has been over architected. You’ll find that you need to change the framework itself to add new types of rows. Really?
After my team finished work on our maiden Three20 app, we all agreed we wouldn’t use Three20’s table framework anymore. And we’ve been much happier since. U-g-l-y.
UI Persistence
It’s probably unfair for me to put this here. UI persistence is one of the great draws to Three20. Imagine, you get built-in persistence so that when a user closes the app, they start right back where they were later.
Unfortunately, it’s not the easiest thing to use in the world. However, put in some elbow grease and you’ll have it licked. No, the problem is that we don’t really need it anymore with iOS 4. Well, that’s not totally true, with Three20 you can always guarantee you will start where the user left off, regardless of how iPhone manages the lifecycle. But, really, it’s not worth injecting this much architecture into the task anymore.
So, use iOS 4 for your UI persistence, and leave Three20 behind.
My Overall Recommendation
Whether you use Three20 or not depends on what kind of app you need to create. Overall, however, I’d say skip it. You get a lot of useful stuff, but it’s so easy to cull a few ideas out of it and go it on your own that it’s not worth the added risk of running into a Three20 behavior that leaves you stuck to find a workaround. On top of this, the table architecture, UI persistence, and stylesheets are too bulky and too unusable to be polluting your code with.
The two pieces of Three20 I’d create for yourself are the preprocessors and the URL navigation. I’ve created my own preprocessors that go far and beyond what Three20 put in, and they are tailored to the things I want the most. So I no longer need Three20 for it. I recommend you do the same. (One day I’ll post mine perhaps.)
The one condition for which I’d recommend using Three20 is if you have a need for the several views they provide. Instead of writing your own springboard, use Three20’s. The photo browsing views are very well done, too. But, if you only have a need for one or two of these screens, or none at all, it’s more worth it to write your own. Taking a couple days to do it (or find another 3rd party version) is going to be worth the extra time you’ll need with Three20 later.
Conclusion
I hope this review has been helpful to you. If you haven’t used Three20, I recommend you at least check it out for a day or two. Every developer has their own preference. Mine certainly was with Three20 initially, but it just quickly fell out of favor.
And if I’ve misrepresented the framework here, please comment and let me know.
10 Things Apple Could Do to Make iPhone Development Perfect
I admit, I love developing for iPhone. I’ve been doing it non-stop for over a year, for various clients, full-time and part-time, and most of the annoyances many developers complain about I don’t even notice myself anymore. I don’t desire garbage collection — I can speak retain and release like I do English. I enjoy Objective-C despite its quirks. Etc., etc.
That being said, Apple, if you’re listening, if you just did the following 10 things, I would be in programmer heaven. So, here we go, the Top 10 things Apple could do to make iPhone development perfect!
Implement Frameworks
This is obvious. Everyone wants this. I am a big believer in using little-f frameworks and libraries, but it’s hampered by the excruciating processes required to bring them in. Three20 is great, but what a pain to bring it into a project. Many require upwards of 10 steps! Starting a project is painful due to this. And there is always one little check box or one little include path that you forget to do that takes too much time to figure out. Why should developers be punished for using libraries that greatly increase the utility and reliability of their apps?!
You already support it for Mac. Apple, stop dorking around with gyroscopes and allow Frameworks for iPhone!
Simulate GPS
Come on, even the Java ME simulators allowed this! You could open up a popup that allowed you to change latitude and longitude. The GPS would detect the change (you didn’t even have to hit OK!) and would place you where you specified. Somewhere in XCode Apple has hardcoded Cupertino, California. Is it so hard to just allow a user to change this for testing purposes?
It’s frustrating in how easy it is to do and how annoying it is for developers. ARGGG!
Automatically Add #import Statements
As a former Java and Flex developer, it was a pleasure to be able to hit a simple key sequence in Eclipse and have imports added automatically. Actually, for Flex, it’s slightly more tricky, you have to hit Control-Space right after the class name to do it, but it’s still a guilty pleasure.
While not trivial, I’d love to see XCode have this feature! If it can syntax color the class names, it can add the imports automatically. I can’t explain how much time this would save! Please, please!
Allow Multiple Simulators for Bluetooth Testing
Apps that support interaction with nearby phones are great fun! While I’ve never had to write one (thankfully), I’ve seen the pain it causes when testing. You can’t run two simulators at once to do so. It’s silly! With simulator support, more apps would support these cool features! Encourage it by allowing a developer to run two separate iPhone Simulators at once and allowing them to connect.
How cool would that be?
Replace The Crappy Unit Testing Framework
The native unit testing framework is an abomination. There is no positive feedback that your tests ran, unless you enjoy reading reams of compilation logs. Anybody who does unit testing knows how many times they’ve hit the situation where all the tests run fine until they realize, OMG, the tests were never actually running!
Also, there is no UI. I want to see a green bar. I want to see how many tests ran. I want to know how long it took. TDD developers expect these things as a baseline! I’ve written a new framework, WiteBox, to replace it and there is also the wonderful GHUnit. I’d love to see one of these be the new native standard someday.
Allow Synthesized Override
This one is subtle. Say, for example, you create some ivars and properties and then you use the @synthesize command to create the setters and getters for you. As is often the case, you may want to write your own setter so that when a value is set you can change some other data or UI to reflect that. So, you write your own setWhatever() method and…
Problem is, you have to then write your own memory management code. If you’ve done iPhone coding for a while, you can write it without thinking. But why should I think? What if we could call “super.setWhatever = ” as if the synthesized method still exists? Or what if I had a syntax like “synthesized.whatever = ” I could call? That would be nice. Then I could focus on the new functionality and not on the setter code that Apple is already capable of auto-generating for me.
As it stands now, specifying copy or retain in your property is completely useless if you write your own setter. That seems wrong.
Pretty please? I’d be so happy.
Prevent Project File Merges #$&^!
OMG, why isn’t this #1? If you’ve ever worked on an iPhone project with even ONE other developer, you likely find yourself doing a manual merge of the project file at least twice a day. It gets scarier with 3 developers, or 4 developers, and so on. Many of you out there go it alone and don’t run into this, but I assure you — it’s a NIGHTMARE. Praying you never have to work with someone else is not a solution.
Apple, change your project file format and do something about this nuisance! Steve, you hearing me??
Native Private Methods
Yes, I know how to use Categories to fake it. No, it isn’t pretty. It’s 2010, Objective-C should allow for *true* private methods. Enough of this “Don’t use the Private API” stuff. PRIVATE METHODS! NOW!
Add Ability to Create Groups as Folders
When you add groups, they don’t create folder structure. This often leads to directories full of inter-mixed content in the project folder. It looks nice in XCode, but it would be nice to have a little more order in the source. The only way to map a group to a folder is to manually create the folder yourself and then drag it into XCode. How about allowing us to create a group and then have a checkbox to create a folder as well?
Add a super Call to loadView Already!
Minor, but obnoxious enough to make this list. loadView() is the recommended place to add UI elements to a UIViewController derived class. Yet, the default template has failed to provide the [super loadView] call for the last year. Add it in. :-)
I can’t count how many times I had the infamous recursive call error occur because I forgot to add [super loadView] myself. Uggg!