When designing and writing code, after "make it work" what are your top design considerations?
Make it flexible and extensible.
Requirements change very quickly, and I've bitten myself far too often by writing spaghetti in the first iteration and twirling it tightly around my fork with each subsequent change.
My motto is "make it work, make it fast - in that order". It's basically to guard against premature optimization. Don't worry too much about making it robust initially - you may find you've spent too much time making something a jewel of software reuse only to never use it again because requirements have changed.
Lastly, take some advice from The Mythical Man-Month: "plan to throw one away". Once you have something working you can begin to redesign its structure and make it what you should have written the first time around.
Maintainability
Performance
Extensibility
Code Quality (how much reuse of old code etc)
also, I've learned that when you decouple as many parts of your code as possible (separate different pieces into components not knowing about their users, for example), you can much more easy make modifications to accommodate the changes Brian was writing about.
One submodule doesn't do what you would have wanted it to? Easy. Just extend it. As it implements a defined interface, no other part of your project would break.
Once you have clean interfaces, you may even find out that component C also needs a certain functionality of component A which you didn't think of in the initial design phase when you designed B as an user of A.
But now that A knows nothing about B, C is free to use A aswell without you having to go around an fix up A to work with C aswell.
This proves to be very helpful over and over and is certainly something I'm after whenever I'm designing something fresh.
Even before "make it work", I want code that is readable. Rather than hacking until something appears to work, prefer code that obviously has no bugs than has no obvious bugs.
Trying to be flexible and extensible often leads to speculative generalisation. Writting code that "you might need", but never do in that form. Causes lots of upfront work and additional maintenance.
For my day job, making security is the top consideration (closely followed by not breaking anybody else).
This is my design philosophy.
Readability - Write Code that is readable. You or someone else will appreciate it when you have to come back to it at a later point in time.
Simplicity - Keep it simple. Only build in complexity where required and only to the degree required. You can always refactor it later.
Say Less - Less code is more. If you can leverage something that exists, do so.
As Michael Feathers says in Working Effectively With Legacy Code, legacy (bad) code is code with no tests. I find that by designing and writing test-first code or even code with an eye for tests it WILL turn out to be loosely coupled, it WILL be more readable and it will certainly be more maintainable. So in a word, primary design concern: Testability.
Seriously, I went from not knowing how to design a durn thing to feeling fairly comfortable in my designs simply by considering tests. At some point, it all just clicks.
Readability Simplicity
Unfortunatly it seems that Simplicity is not very high up that list. I've the impression that learning to click somewhere which then generates (barely readable) code is very popular. And there a configuration file and there another probably best in XML. There another makefile, there another manifest and well there another thing is not that unpopular....
Everything other users are saying (on which I agree) + I shape everything as library.
It's just enough if you make static library (.a) of any big enough set of functionality inside your project. When you think that the functionality is grown up and could be useful somewhere else, all you need is just modifying the compilation system and keep the everything as it is.
Obviously I do this only for worthy modules. :-)