Architecture emerges from the code.
Efficient design solutions come from listening to the code. If you choose to work in the present by opening your ears to what the code is saying you will quickly have the answer. If you work from your ego out of fear and try to predict the future, you will create mistakes and slow things down. Trust the code.
Actually, this is a law only for the ExtremeProgramming camp, so it is presumptuous to call it a "law of programming". It stands in contradiction most notably with the teachings of EwDijkstra, and many other GrandMasterProgrammers.
The purpose of code is to implement the design, the architecture. If, while trying to implement a given design, the code is awkward, then maybe that's a sign that the design can be improved. But trite phrases like "listen to the code" sound to me like excuses for hackers to get away with NO design...
Also, even if there were some merit to the premise of this page, it would hardly be a LAW. See ThereAreNoLawsOfProgramming.
Code IS the design. I have been programming for 25 years, and the 1st paragraph is the best advice that I have ever received. But, you do have to have something bigger, some kind of metaphor of what the whole system should be doing. This is the architecture, not the class diagrams, flow charts or anything else. -- NissimHadar
If that's the best "advice" you've ever received, perhaps you need to seek better advice. I've been building software (not just programming) for 25 years, and I'll take a strong design over clever code any day. I can reimplement a solid design using a variety of languages, libraries, and platforms; I can grow a good design to handle new requirements. But all I can do with code, even good code, is maintain it, tweak it, patch it, maybe stretch it. I could try to extract the design it represents, and in limited cases I might even try that, but for the most part I'd rather start with a new design, salvage what code I can, and move on. I'll never understand CodeWorship.
Building software is just programming.
Sticks and stones... The problem is that you have attempted (following various cults) to excise an integral aspect of programming (the design aspect) as distinct. Design is not distinct, though many try to characterize it as so for a variety of misguided reasons. All but the dimmest folk know programming is not just keyboarding, but programming is also not just tricky encoding of a design using arcane symbols. Programming is the entire effort of building software. This definition of programming is extremely important because it discourages the misguided notion that non-programmers can design software.
We'll have to agree to disagree, because I don't share you're interpretations of programming and design. By the way, it doesn't help when you use phrases like "cults" and "all but the dimmest folk".
I frequently use pictures and prose to concisely describe elements of my designs to other people - never in complete detail, mind you. Drawing those pictures and writing that prose is not designing but mere commenting or digesting or describing. Designing is mentally synthesizing a solution, and that happens inside the head. If you need to draw pictures to work out your ideas, knock yourself out. But you’re fooling yourself if you think that everyone needs that intermediate form.
Again, your view of designing appears to be different from mine. I wish you well in pursuing your approach; please allow me to pursue my own. By the way, neither I nor anyone else I've read here has claimed that "everyone needs that intermediate form."
Above, you speak of implementing a solid design using a variety of languages. You cannot be using those languages skillfully if you would fulfill the same requirements with an identical design in two different languages. Yes, to some degree, very high-level structure is usually quite language neutral. But programming languages are extremely idiomatic, and at a detailed level, skillful use of a language strongly influences design. Programmers skilled in one language who try to use the same approaches in another language have perpetrated some of the crummiest designs I’ve ever seen. For example, some of the worst Java code comes from C++ programmers who merely learn the syntax differences rather than the design approach of Java. (The superficial similarity lulls them into a false sense of comfort.)
Once again, we have fundamental differences in what's important. I would never say anything against the "skillful use of a language," but to me that is primarily important for the implementation of a design. Yes, the design will be influenced by the language in which it will eventually be realized, if for no other reason than knowing what capabilities will be available (e.g. if I know we're going to implement with Java, I won't think in terms of multiple inheritance). But a good, solid design can, and often should, be crafted without too much focus on implementation details. I think premature focus on implementation can compromise the design; I've seen it happen quite often.
If you (the writer in italics) yourself don't understand CodeWorship, it's unlikely anyone can help you to, since it appears to be your own invention.
I'd suggest that you'll find that the kind of people that subscribe to the principles above will also take strong design over clever code any day. They've chosen to use code as their primary medium for recording design decisions. That's likely because they've learned how strong, solid and capable of growth code can be if you'll only let it. If all you allow yourself to do to your code is is maintain it, tweak it, patch it, maybe stretch it, then no wonder you're hung up on this separate "design" thing, whatever that is.
I'd further suggest that the kind of people that subscribe to the principles above don't "worship" code; instead they have (or strive to have) the kind of intimacy with, understanding of and attachment to their medium, code, as a sculptor might have with, for instance, clay. Or a carpenter with wood. Or a writer with words. Or a painter with oils. And so on. -- KeithBraithwaite
Absolutely!That you choose an analogy with artists and mediums is interesting. Most artists have a design "in mind" before they commit to their particular medium. Some will put that design down on paper as notes or sketches, or build preliminary models first; others will just iterate through multiple attempts until they're happy with the result.
But software engineering isn't art. (Yeah, I know some would disagree. And in fact, I tend to the resist any attempt to squeeze any trace of art or creativity out of software. But fundamentally, we're building software systems, not art.) Some people may choose to "record design decisions" in code. Of course, some people choose not to do unit testing or documentation, either. If they work for a company that builds non-trivial software products that need to be delivered on-time and (relatively) bug-free, then many of them will be expected to document their design before storming ahead into coding, and if they should serve up a design review with nothing but code, they'll be out on the street.
On one hand, it is ironic that I'm even arguing this side of this argument, because when I get to work on a project small enough for me to do it all myself (my favorite kind!), I rarely do any formal design diagrams at all. I sketch out some quirky diagrams that don't correspond to any UML at all, and then I dive in and cobble up a skeletal set of stubbed-out classes. I put some effort into choosing classes and methods and naming them well, and I think of this as a sort of proto-design. Then I start hanging functionality on this skeleton, wherever it seems interesting to start. I inevitably end up revising this design on the fly as I'm implementing it, refactoring and so on. In other words, I think I'm doing something very similar in spirit to the "code is the design" folks.
But at some point (hopefully when I have some minimally functioning prototype), I stop and model this design, preferably using UML. And if I'm part of a team doing a moderate to large software project, I wouldn't dream of trying to build software without a guiding architecture up front. (Which is not necessarily the same as BigDesignUpFront; I think moderate to large projects can benefit from iterative, incremental development, perhaps even more than small projects.)
I don't deny that you CAN "capture" a design in code, but I think it is a poor way to represent software design. Software source code is primarily meant as a tool for humans to communicate detailed instructions to stupid machines. People reading source code CAN, with some effort, extract the underlying design and form a mental model. Why not do so more explicitly, using various graphical tools and metaphors to make it easier?
As long as one considers source code as only a tool to communicate with a computer, that's all his source code will ever be. For truly skilled programmers, source code is a very important tool for communicating with other programmers, and even with our future self.
I don't accept this argument. In my experience many "truly skilled programmers" are below average on communicating design concepts to their teammates. They expect other people to just analyze their code and the perfection of their "design" will be self-evident. When other people point out design alternatives, they get impatient and cranky, because they've become emotionally attached to their beautiful code. These are not the TrulySkilledProgrammers we are talking about.
I think this whole argument stems from the poor implementation of the graphical metaphor (namely, bad CASE tools). The only thing which can be truly and fully representative of the system and its design is the part which contains all the information about the operation of the system, no? Therefore, the source code is king. You can generate a complete UML diagram from the source code (so long as it was constructed sensibly), but there is no way to generate complete source code (of any useful complexity) from a UML diagram. So the UML "design" is a product, not source. The only alternative viewpoint that makes sense is that the graphical views are just that - alternate views of the source code. So if you move a method in the source, it moves in the diagram. If you move it in the diagram, it moves in the source. They are simply two different views for the same thing. I've noticed very recently that there are now a couple of programming tools out there that use this concept. It works a lot better than the ridiculous UML-diagrams-generating-code paradigm. -- GavinLambert
The statement "architecture emerges from the code" seems to suggest that you write the code first then the architecture crawls out of the rubble. In the ConstructionMetaphor, this would be like saying that first you build the building/house/skyscraper and then you work out what the architecture is. This sounds rather too much like hacking.
Yes, exactly. This is the source of much of my dissatisfaction with the premise of this page; it seems to lead to a kind of mysticism. I don't accept that software is wholly an art, and that it doesn't lend itself to any discipline or clearly expressed principles and techniques.
That's the obvious interpretation to me. However KeithBraithwaite seems to be interpreting this page's principles as saying that the code should be the ultimate documentation of the design/architecture. It's hard to disagree with that. So I won't. -- AdewaleOshineye
The ConstructionMetaphor is weak to begin with, so I wouldn't put too much weight in any conclusions drawn from it.
The first time I bought plants for my apartment they all died within weeks much to my distress. I bought plants a second time and doubled the watering schedule. Instead of once a week I now watered them twice. The plants still died. I bought plants a third time and added plant food to the water. Aagh! They still died! I then replaced all the light bulbs in my apartment with full spectrum bulbs so the plants would receive proper light. I purchased plants a fourth time. After a few weeks they died.
I was confounded - why did the plants die when I watered them twice a week, used plant food and had full spectrum light bulbs?
After some thinking, I went to a plant store and told my tale of woe and asked what I had been doing wrong. The plant person asked "Do you water the plants before the soil is dry to the touch?" I said "I water them twice a week". The plant person said "Water them only when the soil is dry to the touch".
I started to then water the plants only when the soil was dry to the touch. The plants have been healthy and happy for almost a year now.
So the answer to the question of "why did the plants die when I watered them twice a week, used plant food and had full spectrum light bulbs?" is in the question itself. The plants died because I did not look to the plants for when they needed to be watered. but instead to my own ego of thinking I knew when they needed to be watered.
Now I water them when they have a slightly droopy look and the soil is dry to the touch. In other words, I water them when they ask me to. I look to the plant when to water it and by doing so I always water it exactly when it needs to be watered.
Try taking care of 500 orchids, all different. No, you don't listen. You water twice a week and throw out the ones that die from root-rot or mites or whatever. Some plants are monsters. You put them outside in the fall and they won't die, they spring out new spikes from broken old spikes. Brings those back inside and keep them. Eventually you end up with a decent collection.
This is what I meant when I wrote "efficient design solutions come from listening to the code" and what I think the italicized writer ironically demonstrated by saying "I can grow a good design to handle new requirements" - fulfilling the present requirements is what creates good design, not fulfilling what you think the future requirements will be. Just as a plant should be watered when it asks to be watered (by taking on a "thirsty" appearance) and not according to some imposed schedule, source code should be refactored when it asks for it by taking on a duplicitous, bloated or chaotic appearance, and not according to someone's ego or belief that they can predict the structure of the source code before the source code exhibits the tension that demands new structure.
Why give code structure it isn't asking for?
-- RodneyRyan?
Is code somehow sentient? More mysticism. Consider the case where a man hits a woman for some perceived slight and says, "She was asking for it." In this case, the woman is indeed sentient but the meaning of the phrase is really "given who I am and who she is, I had to hit her." No decision need be made by the woman or by the code; the decision lies entirely with the person doing the refactoring or the hitting.
Now that I think about it, maybe I shouldn't make analogies between refactoring and domestic abuse...
Code is a tool that we use and control. It doesn't do anything by itself, any more than bricks have a say in the architecture of a building. The people here talking about "listening to the code" are really evaluating the code using their own brain! This is just a process of feedback; try something with your medium, stand back and look at it, decide what looks "right" and what looks "wrong," and reach in and adjust it, rinse and repeat...
When the bricks in a building start to crack, there is something wrong and it doesn't matter what the architectural plans say. Building inspectors look at the state of the building and do not care whether it was built according to plan, they only care about what the building actually exhibits. Building standards and architecture itself came out of examining what went right and what went wrong with actual designs. Also, remember pleasing architecture is not decided by the architect nor the bricklayers; it is decided by those who view the building after it is built. Likewise, the quality of software is not decided by a software architect nor the developer; it is decided by the users of the software.
Maybe the creator of this page should have called it SoAndSosSecondLawOfProgramming?. The title implies that this is widely considered the second most important insight in our field.
Someone says above that " this would be like saying that first you build the building/house/skyscraper and then you work out what the architecture is." Developing software is *not* like constructing a building. Software is soft - malleable in a way very different from a building, which is hard. If you've built a piece of software test-first, you can refactor it towards a very different design, step by step, with all tests running and the software fully functional at each incremental commit. Try doing that with a bridge or a skyscraper.
This softness or malleability of software (together with modern computing environments with an extremely fast build-run-test cycle) that makes architecture growing naturally from the code possible and desirable. Also, "listening to the code" isn't mystical - it is a common linguistic device known as a "metaphor." (Thinking like a machine is often useful for a programmer, but it doesn't help when reading text for humans only!) Look at MartinFowler's RefactoringBook for examples. If a method is mostly method invocations on an object of a different class, perhaps it "wants'" to be on that class instead, and you should apply a Move Method refactoring. This is a metaphor - I think we're all aware that methods aren't sentient. -- ApoorvaMuralidhara [P.S. Even these comments were developed incrementally through writing and revision, letting the paragraph/sentence structure develop naturally by "listening to the prose." (Prose doesn't actually have a brain - agreed?) Perhaps, then, one should compare programming to writing rather than to bridge-building. Programming actually seems unique to me, sort of half (technical) writing and half constructing a machine that works.]
Looking back, months after writing the above, I wonder. The tone-deafness for metaphor, the "thinking like a machine" I criticize - is it wilful (are there people who believe metaphor is wrong?), or is it an inability to understand? If the former, I strongly disagree - metaphor is essential to how human beings communicate and think, and DesignPatterns and ExtremeProgramming and many other things we discuss here depend on it. (As do common words in the world of computers - including "file," "stream," "desktop," "framework," etc. Or does the writer object specifically to analogies between objects and sentient beings, because they might encourage teleological or mystical thinking? This would make sense only if someone somewhere believed code thought or felt or talked.) If the latter, this ultra-literalism might stem from many "geeks" or "nerds" actually having AspergersSyndrome, as a current theory holds. I wouldn't want to mock someone who had a genuine disability, but there's no way to tell from an unsigned contribution. -- ApoorvaMuralidhara