A few basic concepts I’ve found essential in getting great work done fast.
Get Better Requirements Up Front
As the tough questions. Focus on driving out uncertainty, and testing assumptions.
The more effective you are at doing this, the less trouble you will have down the road.
Start recording and organizing requirements as they come in, and maintain your project documents in as orderly a fashion as possible.
This may mean using a lot of paper in a binder, keeping journals, or using project management software.
Yes, it’s extra work, but it’s necessary to avoid miscommunications and prevent missed commitments (among other things).
Keep the organizational work from bogging down your project by picking a method that’s easy for you to get into.
Then focus on getting really, really good at it.
I like to draw diagrams in LibreOffice, keep prose in ReStructuredText, and organize my work in SCM like git or a CMS like Plone. It doesn’t matter, as long as it’s something you can do with minimal effort.
Get Sign Off
Take the requirements you get from your stakeholders, reformat them, reinterpret them, and present them for approval.
Typically, this will start a dialog that will lead to better requirements, and solidify the relationship you have with your stakeholders.
Worst case, they sign off without reading it, and you have ‘rear-end coverage’ in the event expectations aren’t met.
Break Down The Walls
Resist the comfort of ‘buffers’ between you and your stakeholders and/or users.
Dealing as directly as you can with the people who your work will affect the most:
- avoids unrealistic expectations
- prevents false starts
- limits rework
Overall, it means a shorter time to ‘done’, and happier stakeholders.
Prototype, refine, re-refine, prototype some more, refine, re-refine, ad infinitum.
Build just enough to meet the requirements, and then build more. Refactor liberally.
Further, don’t focus too much on polishing your work too early in the project. Start with quick proof of concept prototypes – move code from prototypes into modules as it matures, and add unit tests along the way.
It’s important to vet your engineering and design decisions early on to keep refactoring ‘cheap’.
As the project comes into focus, your APIs begin to settle, your namespaces take shape – then concentrate on kick-ass test coverage, modularization, code organization, DRY, packaging, and other refinements. The end result will be highly refined, well vetted units of code that can more effectively be replaced or reworked.
Lather, rinse, repeat.
Utilize Design Patterns
I sleep with the GoF book under my pillow at night.
Seriously, design patterns are not a magic bullet, but remember why they exist – because software is repetitive.
I’ve found the hardest part of any project is not writing the code. The real challenge is engineering the solution.
Design patterns lay out a foundation of practical approaches that have been tested both intellectually and practically, over time. They help us articulate a software problem – they act as a sort of solution vocabulary.
Building up a solution out of a series of design patterns means less engineering work, less communication parity between developers, and fewer engineering ‘near misses’.
Also, don’t forget there are design patterns in other areas besides OOP work – and sometimes, they’re not called ‘design patterns’. For example, check out this repository of Enterprise Data Models.
Absolute transparency coupled with free-flowing communication is essential to a healthy project… assuming that your stakeholders actually understand what you’re doing :)
It’s important to channel information in constructive ways, and tailor it to your audience.
You can avoid unnecessary re-work, bad requirements, and slow downs because of misunderstandings if you find ways to communicate completely, but effectively.
I like to send out periodic status reports, and keep in mind who will be reading them. But remember, this isn’t about spin – it’s about simple communication. Find ways to do it effectively, regardless of the underlying message, and you will get things done faster.
Find Your Community
Some of the biggest road blocks to getting a project completed are purely mental.
We paint ourselves into a corner, we become unsure about engineering decisions we’ve made previously, we get stuck on a problem we just can’t seem to work out.
Building a human infrastructure of cultural and engineering support can be one of the biggest efficiencies you can gain as a programmer.
Find a community of similar individuals. This may mean other developers at your organization, local user groups, IRC channels – be creative. The similarities might be surprising – usually that means similar languages, industries, domains, platforms, but that’s not the case all of the time. Don’t be afraid to seek out non-technical connections.
But never forget to return the favor. Keep a blog and update it frequently. Answer other people’s questions on IRC. Building a reputation for being helpful will help you get help more… um… helpfully. The more help you can get, the less time you’ll spend in mental quagmires, and the more efficient you can become.