As you have perhaps read in my last blog post, I once worked on a project where when I started its very old codebase was more or less one giant mess. It got me thinking heavily about structured code and how I’d love to just refactor all of that but sadly can’t. What I can do however is offer up some advice based on my own experiences as to how one might go about doing their job in an organized manner, so that the things you deliver will also be.
First, every project needs an Architect. Imagine what would happen if your immigrant paid-under-the-table construction workers were tasked with the job of designing the house as they build it. Not the best plan. Everything you want to do, software design-wise, deserves a discussion with the project’s architect, as this person is most likely the most experienced person with conceptual design, and through discussing it you can show him how you think and approach problems (good for future work, as he will remember this bright young mind!), and most importantly, you will be keeping him in the loop.
That said, YOU might be the architect, and forget experience, you’ve got a job to get done. Let’s go then.
I am assuming it’s an iOS project, which is very much going to be for the mostpart a Model-View-Controller paradigm. Here’s generally how to ensure you can adhere to this pattern:
Make a Click-Dummy
You should be able to navigate the interface without requiring any data initially (or at least you can use mock data), so that you are properly ensuring that View objects remain dumb (that is, the Controller tells them how they should appear, and the View tells the controller what has just happened to it, say when the user interacts with it.) A view should rarely, if ever, retain a pointer to a data model. If so, this ‘smells bad’ and you should probably be doing something differently.
Ensure View-to-Model Separation
If you couple a view to a model, this view can never be reused in any other project, ever again. This is why you should keep your views as dumb as possible. They should inform someone (a controller) about anything that happens to it, if they need to populate themselves with content (like a table view, for example), it should be delegating this job away to someone else (like a controller! who asks the model!) A view is vapid and vain; it only cares about itself and how it looks, and if anything happens to it that might disrupt his appearance, he goes and cries to someone else about it and gets them to figure out what to do.
Encapsulation, Encapsulation, Encapsulation!
It can’t be stressed enough how important it is to encapsulate the functionality of your objects as much as possible. Always write code considering that someone else may use your code later. The public header is your way of saying “these are all the things you should need to know about, the rest is not required knowledge for you to make this thing do it’s job” Matt Gemmell put it best in his famous article (which you should read as well!):
APIs are UX for developers… your API is part of the first impression that a developer will have with your code, and will have a huge impact on whether they use it or throw it away.
Of course, with any craft, practice makes perfect, and one doesn’t simply learn this stuff overnight. The important thing is that you strive for excellence, don’t just be happy with “It works! On to the next feature…”
Time after time I’ve heard the lazy excuse of “well, I shouldn’t need comments because the code speaks for itself”. Well then, young padawan, your code is saying “help me, I’m retarded” or at a very minimum “I’m culturally very different than you.” Which in any case leads to misunderstanding and confusion. Especially when you haven’t adhered to design patterns, comments are most essential for another programmer to make sense of the mess that’s been made. It never hurts to give a person some indication of what was going through your head at the time. That person could also be you, reading your own code months later once your skills have progressed and you find yourself wondering “What idiot would write such a thing…. written by… oh. Erm, carry on, nothing to see here…”
I hope this might be of some help to you, which of course will then be of some help to whatever person you end up working with in the future. I had another article I like to call “Stephen’s Manifesto” on writing clean code, but it’s a bit long, lots of images, and a bit outdated. It’s meant for relative rookies. I’ll summarize as follows:
- Avoid “Cowboy Programming”: Don’t “code first, ask questions later”.
- Write headers first. It gives you an overview of what you want to accomplish
- Write method stubs, filled in with comments that explain in plain english what your algorithm is.
- Organize your implementation files with pragma marks
To Nib Or Not To Nib
(UPDATE) There are some good arguments on the Internet about this, whether using NIB files is good, or whether you should just skip it and do it all in code. Ultimately there are times where either would be appropriate, but personally I am a fan of Interface Builder. If it were really a cumbrance, why would it exist? Why would they have taken it further to create Storyboards? That said, there are times where maybe it’s not the tool for the job. (I will add my rebuttal to one of these posts in a future post).
The key reason I would say in an article called “Writing Structured Code’ is that Interface Builder (IB) is actually an excellent way of ensuring a coder works to the Model-View-Controller paradigm. Because when you are coding up your view controller’s view in IB, the NIB file has an owner; in most cases the View Controller. So, right there you are forcing your views to inform the controller of anything happening to them, and the controller (via IBOutlets) is able to set properties on the views. Without that, you see coders writing controller code in their views, views are referring to objects, and all sorts of other wacky behaviour that just wouldn’t be easily possible if the person had to set up a view in IB and then set all sorts of other pointers in viewDidLoad.
Having ‘grown up’ with Interface Builder, I think it inherently trained me to adhere to a MVC pattern and I feel I’m better off having done so. Whether I need IB now, no, not really, but as it’s been mentioned in one of the above 2 posts, one writes less (boring) code.