I am still getting mature as a software engineering/designer/architect, as you may want to call. At this point in time, I am getting small projects, private projects and so on. What I noticed is that even though I think about the SW structure, design some diagrams, have they really clear in my mind when I start coding, at the end, my software is not flexible and clear as I would like to.

I would like to ask you what kind of approaches, mechanisms or even tricks do you use, to get your software (and SW design) flexible, robust and clear (easy to understand and use). So.... Any ideas to give to a beginner?



You can almost never make it right the first time. And even if you do, requirements change and new ones come along, so over time you need to extend and modify your code in unanticipated ways. So whenever you notice it is awkward or difficult to change the code the way you want to, refactor it first to make it open for change. A recommended reading for this is Refactoring to Patterns.

Good design rarely comes out of the box - rather it emerges through a series of transformations and refinements over the lifetime of an app. Of course, the more experience one has, the easier it is to see dead ends: decisions which look appealing now but would cost dearly in the long run. Practice makes the master.

  • +1 - Rafactor, refactor, refactor. /Ballmer. Always refactor your code and it will start to shine. – Sergio Mar 3 '11 at 14:51
  • Hey, that answer was very nice! I always think "this part is done, I shouldn't touch it anymore", but it may be the other way around. :) – JSBach Mar 3 '11 at 19:37

It's just a question of craftmanship - and having the available time to spend on the pursuit of craftmanship (in the event that you are producing the work for a paying client).

What does craftmanship entail? At a basic level:

  • Clean and consistent writing style
  • Adequate documentation
  • (IMO) descriptive names for methods, variables and classes

At a higher level you encounter common design principles

using Test Driven Design methodologies can help keep your methods clean and focussed.

Once you start making well designed classes, you start thinking about making well designed applications- where you may begin to think about concepts like Design Patterns and Dependency Injection.

Having dropped a few buzzwords, acronyms and wiki links, however, it still comes down to the same things as any form of craftmanship:

Patience, perseverance and attention to detail.

Your interest in a piece of code may well tail off before it is "finished", or you may be too impatient to engage in TDD or writing adequate documentation.

A Craftsman will overcome these obstacles and ensure that all the i's are dotted and t's crossed.

in response to OP's comment:

If you are working in a commercial environment. you may find you are not given adequate time to apply your craft to it's full extent. IME this is a very common cause for poor quality code - it's hard to sell Unit tests and documentation as a ROI to the customer/MD.

  • Yes, that is true. But the effort to keep everything good will increase with the time of the project, correct? You may get to a time where all you do is "maintain" the code, you will not have time to add anything anymore. Don't you think there is this risk? – JSBach Mar 3 '11 at 19:39
  • yup - that's why I mentioned "having the available time" when working in a commercial environment. I'll update my post – sunwukung Mar 3 '11 at 21:03
  • Yes, you are right. I have never had direct contact with the client, specially regarding to "selling things" to him. I hope I get this opportunity soon :) Thanks again! – JSBach Mar 3 '11 at 23:16

Depends on what you call the end. You just have to go back and fix it and apply what you learned to future projects where applicable. Bad code usually sticks out after it has been written or you knew it ahead of time, but just wanted to get the thing to run. Eventually, you can account for some of it at design time; just make sure you don't over-engineer the thing.

Bad code is relative. We can all look at a line of code and recommend not doing it that way, but we also stress consistency. The best way to ruin a perfect line of code is to copy and paste it all over the place.

You may never get back and actually get former projects to the level of robustness, flexibility and clarity you desire. There's always the next one. Software ain't easy.

  • Yes, over-engineering is always a problem, specially to the beginners, which are still very excited about all the techniques and patterns :) – JSBach Mar 3 '11 at 19:42

Robustness - Know the requirements of your project ahead of time. You can't anticipate every modification to the project, but every information is less work you'll have to do making your solution fit to the new requirements. It helps clearness in the long run.

Flexibility - Learn how to think using the Model-Controller-Interface pattern. When you build your project, define the structure before you proceed with the details. It'd be like building the frame of the house and the walls before you begin laying down carpet. It allows you to easily extend or grow as you require. Good starting place to start doing detail work lies in the sections of the project which aren't going to be modified.

Clearness - Add comments explaining why you inserted the code, not what it does. If you have to pick between writing shorthand tertiary logic and writing out a full if statement, write out the full if statement. If you have to ask why, know that I will hunt you down if I debug your code one day and find out you didn't do that.


One technique works for me: TDD.

  • it helps getting clear interface and behaviour quickly
  • it provides a regression test suite for future refactoring
  • it is a great communication aid when needing clarifications on requirements

For robustness, have the attitude that the rest of the system is unreliable and will fail every chance it gets. This gets you in the habit of always checking return codes, always catching exceptions, and always thinking about "how am I going to recover from this?"

For flexibility, always program to interfaces and try to delegate responsibility. DI is helpful, but can become cumbersome on large projects.

For clarity, always write the simplest, most straightforward code possible. Save the tricky techniques for places where you've identified a problem. This also plays into flexibility. I've been on lots of projects where someone (not always me... ;) spends a lot of time implementing an "elegant" solution that ultimately doesn't work out (due to a spec or requirements change). The result is that then you either spend a lot of time adapting the elegant solution to the new requirements, or just scrapping it and writing something new.

Not the answer you're looking for? Browse other questions tagged or ask your own question.