Many approaches are possible of course. Fundamental knowledge is the
starting point IMO: read the pattern books and such, study existing systems
and software from a high level (rather than doing something like loading GCC
source code in your IDE), use Doxygen to analyze source code at a high
level, pay attention to how things interact (the "interfaces") rather than
the things themselves, avoid large team development roles if you can (you'll
get buried in the details rather than gain high-level perspective), create
entire application programs but do start with the pen and paper and circles
and arrows and such, way before writing any code. Do not write a whole book
of documentation before doing some iteration and feasibility studies, but do
write important things down in additon to your "circles, boxes and arrows"
or you will forget your decision-making path come implementation time.
"Jumping in with both feet" is OK, but some amount of study and THINKING
(design is more thinking than annotating) is prudent. Don't OVER-study the
commonly tauted "principles" either: you'll get to know the trade-offs and
when they apply by doing (designing and architecting, that is). Most of the
"principles" are not documented or available to read about, realize, as
experienced designers/architects draw from the larger wealth of knowledge
and experience rather than the much smaller scope that is Information
Technology.
(This is the most key point IMO: designers/architects are born, not made or
taught.
Very good. Not far from being right on the money.
If you are asking how to be one, maybe that is a sign).
People think that sw design is like a skill you aquire in some school,
like a plumber or machist.
Yes, you CAN aquire plenty of knowle, but the whole art of it
will be missing.
Know
yourself: designers find it natural to design.
Yep. In fact it is not a "job" to them. It is something they get the
kicks out of. It is some necessity to them, like an oxygen.
They create the patterns
rather than go out and look for them.
Correct. When someone talks to me about "design patterns".
I tell them: I CREATE them and I created plenty. So far, did not
see an area where I would not feel comfortable with.
Sure, you can read the patterns from some book and blindly apply
them anywhere you can find a place to stick them on. But all of
it is artificial. It won't necessary be that, which is truly
requiered by your situation.
There are ALL sorts if issues with patterns, down to issues of
debugging. Some time ago, I needed the web crawler. So I found
some nice piece of code that looked promising. It did do most
of what I wanted. But it did have some pretty bad shortcomings.
It was using the visitor pattern.
The code was totally undocumented and I spend WEEKS trying
to understand all the intricacies. When I was debugging it,
it was a nightmare. You are totally event driven and the
environment is totally async. You don't even know where
to set the breakpoints, and even if you single step through
the whole thing, it is such a major headache, that it takes
you at least 10 times more time and effort.
And THAT is the reason I suspect that powerful and beautiful
piece of code was eventually abandoned and author stopped
maintaining and improving it. Becaues we got overloaded with
the complexities of it to the point that it was ubearable.
So, the visitor patern in the async, event driven state machine
is a disaster. And so I saw with other patterns.
People think that patterns is some kind of paradise.
Nowadays, about the fist question you are asked on the
interview is: do you know design patterns?
And if you don't, you are some kind of clueless idiot to them.
You won't have a chance in most places.
What a joke.
Are you "a picture person"? Or do you
prefer to read/listen? Some people, perhaps most, are better at filling in
the details of a good design/architecture. Then again, some people are so
high level that their designs are not practical (cannot be implemented).
Practicality vs. extremism seems to be a big problem in SW engineering (I
think STL is the latter, for example).
Yep, plenty of new "technologies" in the sw business could be classified
as extremism. The overkill and overload with complexities probably not
helps anything at the end, but creates more problems than it solves.
To me, your code should be readable like a news article.
You should be able to understand ANY piece of code within seconds,
and not sit there for hours, trying to comprehend all the nasty
details, going as far as spending minutes if not hours just to
understand the parameters of some method. I saw some code that is
basically unreadable, unless you are willing to spend HOURS,
and even there it is not clear you will see all the intricacies
of it.
People do not have that time nowadays.
On the top of it, those complications essentially do not buy
you anything. The bang for the buck is as low as it gets, and
the costs of code maintenace and expanstion is immense.
Quite often, people create overly complicated things just to
show others how "great" they are, which is basically the result
of complex of inferiority.
Distinguish between "high-level" design and "low-level" design. The former
should be pretty much devoid of programming language peculiarities.
One of the things I remember from my early days of programming
was this recepie:
Top down design and bottom up implementation.
That is probably the most valuable overall rule for sw development.
I intuitively use it more often than not.
Once you have your low level stuff worked out and working,
it makes it a breaze to hang higher level stuff on the top of it.
Build small systems and application programs first. Large systems have
specialized skill requirements but they are IN ADDITION to the stuff you
learn from building complete small systems/programs thoroughly. Taking
programs that you have already developed and "rearchitecting" or
"refactoring" them is a good starting point, for you are already have a lot
of useful information about the domains (plural).
Basically, I consider it the issue of modelling.
By creating a model, you will be able to test it and see all sorts
of things that you could not even expect before you started.
And I mean MOST of it, no matter who says what.
Then you can SCULPT your project. I do not program, I SCULPT it
like a sculpture.
From the first days on a project, this thing becomes alive.
So, you never end with doing ALL sorts of things without even
knowing if your entire concept is correct and your house does
not end up "being built on sand", and quite literallly at that.
From the first days, your creation should be alive.
So you can see its freakingess, its weakenesses, its beauty.
It should sing or hum as Rolls Royce, every step of the way.
I do agree with this one.
and stick with pen and paper (or an appropriate
graphics program). The programming-specific tools and methods are for
low-level design the ill-fated attempts at creating the proverbial "software
factory"
Correct. Those "factories" are some of the biggest pain on the
neck that do not necessarily buy you anything, but give you ALL sorts
of headaches and make it more difficult even for you to understand
your code.
on-the-fly (read, project work/"general SW dev").
Designing/architecting is a creative process and as such it is not conducive
to highly-structured "methods" or management (those things stifle
creativity).
Correct. They simply eat MOST of your energy on constanly worrying
about things, that you never have to worry about.
I can produce immence improvements in my projects in a matter
of days. In few days, I sometimes add some much new functionality,
that it becomes a problem to even verify it all, even thogh it
all works pretty much out of the box.
And debugging and making it more robust becomes more or less
an idle excersize because it flows by itself. No headaches.
That is when you can take a break and take it easy.
Debugging mostly becomes a verification procedure to make sure
ALL the error conditions have been handled without being lazy
or sloppy about something that "can not happen in 'REALITY'".
Your rate and patterns of creativity are just that: highly
personal:
Correct.
you probably can't turn it on and off like a light switch all the
time. Some days you will be highly motivated and creative and other days you
will plod along drudgerously.
Well, for me, for MAJOR architectural decistions and design
"patterns", it is a process of MATURING.
This process sometimes takes MONTHS untill it all finally
falls into place. I never try to write a piece of code that I can
put a final dot on it. So, no need to overstress yourself perfecting
something, that is not totally clear from the standpoint of
system as such and ALL sorts of most subtle interactions,
the issues of efficiency, compactness, robustness and you name it.
Architecting the system doesn't qualify one to manage the project, realize.
Realize too that it doesn't preclude that: "ownership is nine-tenths of the
law". I've never seen a project run by someone from a business background
devoid of technical background be nearly as successful as it could have been
if someone with an engineering background was running the show (requisite
management skill are still required of course). Business rule implementation
sits on top of architectural technical foundation, NOT the other way around.
Finally, don't do it my way, do you your way! Good luck.
--
Programmer's Goldmine collections:
http://preciseinfo.org
Tens of thousands of code examples and expert discussions on
C++, MFC, VC, ATL, STL, templates, Java, Python, Javascript,
organized by major topics of language, tools, methods, techniques.