88

I feel that I am good at writing code in bits and pieces, but my designs really suck. The question is, how do I improve my designs - and in turn become a better designer?

I think schools and colleges do a good job of teaching people how to become good at mathematical problem solving, but let's admit the fact that most applications created at school are generally around 1000 - 2000 lines long, which means that it is mostly an academic exercise which doesn't reflect the complexity of real world software - on the order of a few hundred thousand to millions of lines of code.

This is where I believe that even projects like topcoder / project euler also won't be of much help, they might sharpen your mathematical problem solving ability - but you might become an academic programmer; someone who is more interested in the nice, clean stuff, who is utterly un-interested in the day to day mundane and hairy stuff that most application programmers deal with.

So my question is how do I improve my design skills? That is, the ability to design small/medium scale applications that will go into a few thousand of lines of code? How can I learn design skills that will help me build a better html editor kit, or some graphics program like gimp?

gnat
  • 20,543
  • 29
  • 115
  • 306
user396089
  • 1,211

9 Answers9

90

The only way to become really good at something is to try, fail spectacularly, try again, fail again a little less than before, and over time develop the experience to recognize what causes your failures so that you can manage potential failure situations later on. This is as true of learning to play a musical instrument, drive a car, or earn some serious PWN-age in your favourite first person shooter, as it is of learning any aspect of software development.

There are no real shortcuts, but there are things you can do to avoid having problems get out of hand while you are gaining experience.

  • Identify a good mentor. There is nothing better than being able to talk about your issues with someone who has already paid their dues. Guidance is a great way to help fast-track learning.
  • Read, read some more, practice what you've been reading, and repeat for the entire lifetime of your career. I've been doing this stuff for more than 20 years, and I still get a kick out learning something new every day. Learn not just about up front design, but also emergent design, testing, best practices, processes and methodologies. All have varying degrees of impact on how your designs will emerge, take shape, and more importantly, how they last over time.
  • Find time to tinker. Either get involved with a skunkwork project through your workplace, or practice on your own time. This goes hand-in-hand with your reading, by putting your new knowledge into practice, and seeing how such things will work. This is also the stuff that makes for a good discussion with your mentor.
  • Get involved with something technical outside of your workplace. This could be a project, or a forum. Something that will allow you to test out your theories and ideas outside of your immediate circle of peers in order to maintain a fresh perspective on things.
  • Be patient. Recognize that earning experience takes time, and learn to accept that you need to back off for a while in order to learn why and where you have failed.
  • Keep a diary or a blog of your tasks, your thoughts, your failures and your successes. This isn't strictly necessary, however I have found that it can be of great benefit to you to see how you have developed over time, how your skills have grown and your thoughts have changed. I come back to my own journals every few months and look at the stuff I wrote 4-5 years ago. It's a real eye-opener discovering just how much I'd learned in that time. It's also a reminder that I got things wrong from time to time. It's a healthy reminder that helps me improve.
Phil
  • 3,680
  • 28
  • 30
S.Robins
  • 11,505
16

Well, there's no golden apple for this kind of question, and I feel perhaps this is for every coder himself to find what's right for him. Here's my take, anyway.

You could read books on the subject. Great books. Fantastic books. But I find that these books only help you once you've tried to build and design an application - and failed.

For me, it's all about experience. When I started as a rookie I read books on how to design. I didn't understand much of the content back then. When I started working and had to design applications myself, I made very messy applications. They worked, but they were a pain to maintain. Then I read those books again - and this time I better understood them.

Now, I continue making new mistakes and learning from the old ones.

12

Stop designing and learn to refactor code. Incremental development with continuous and aggressive refactoring will result in a much cleaner end product than any up-front design.

kevin cline
  • 33,798
7

Read about patterns, sure, but first and foremost read about anti-patterns. Recognizing anti-patterns is important, and it's easier to understand why something shouldn't be done in such a way than why it should.

See http://sourcemaking.com/antipatterns/software-development-antipatterns for example.

Write code so that it can be adjusted quickly if requirements changed (which is very common in production environment).

Be super-skeptical about adding "just one more little hack." One more here, one more there, and the code becomes unmaintanable.

Value the open/closed principle.

Write tests (as in TDD). They force you to think your design through even before you actually implement it.

Browse the code of open source projects (reasonably sized ones, that is). I used to be surprised at - usually - seeing so many levels of abstraction. Now I understand it's not art for art's sake, there's a reason why it's done this way.

4

One principle that I find very important for good design is decomposition: if a class is too big (more than, say, 300-400 lines of code) break it up into smaller classes; if a method is too big (say, more than 50 lines of code) decompose it; if a project contains more than 50 classes, decompose it.

The key is to estimate the size of your system and construct several abstraction layers (e.g. subsystem, application, project, module, class, method) that allow you to decompose your code into understandable units with clear relationships between them and few dependencies.

Giorgio
  • 19,764
0

It's tough, what we're really talking about is an ability to abstract rather than create better code, but two things will make you better and one thing will make you happier:

"Better"

A) Find the best designer you can and pair program / do a design together. Ask them to explain what they're thinking as they address the problem, don't settle for"it just feels right" and keep digging. That process will help the "mentoring" party too

B) Imagine everything as individual actors and conversations between them. Each of the actors should have a single role / responsibility and groups of them handle different systems. If that conversation works and each actor feels coherent and cohesive then you're on your way.

And "Happier"

C) If you've tried your best and it still isn't happening then there's nothing wrong with accepting that some people can't do some stuff. You could write tight, brilliant code, but never be able to design or architect. So what? I can't play physical sports for toffee, I'm not good looking and my car driving will never be better than average. Revel and utilise what you're good at.

gnat
  • 20,543
  • 29
  • 115
  • 306
-1

In my personal experience read others code is a good source of "inspiration". I mean try to understand other people designs and ask yourself why he/she do things in that way ?

you can find a lot of open-source projects for research.

anyway you need practice.

PCJ
  • 117
-1

Don't live in fear

Strive for simplicity

Listen to your users

Try lots of ideas

Create something, then make it better

Work on things that add value, abandon things that don't

-1

Learn to ask the right questions. More often than not you'll improve your design by looking at the problem from a different angle. In particular this will help you to move away from focusing on solving the problem at hand and look more into solutions that solve multiple related problems.