Software Evolution
Software is a thing that has its own kind of life: it is conceived, developed, reaches maturity, is sent into the world, continues to develop, and eventually grows tired and old and is retired.
"Growing software" metaphor
Bug fixing isn't growth; it is tending to diseased parts of the code. Code grows slowly by the progressive accretion of small extra parts, similar to how an oyster makes a pearl.
"Evolving software" metaphor
Software might seem to evolve like a single-celled organism into a large, complex beast. It is an incremental process and develops through a number of stages. Some differences are that the changes are deliberate and do not happen through natural selection. We can use experience gained from previous release to adapt the code to its habitat and ensure its long term survival.
Software Rot
 Bad things happen to good code. No matter how well you start, no matter how honorable your intentions, no matter how pure your design and how clean the first release’s implementation, time will warp and twist your masterpiece. Never underestimate the ability of code to acquire warts and blemishes during its life.
The longest phase of software development is always maintenance. It is where most of the overall effort goes. B.W. Boehm observed that 40-80 precent of total development time is spent in maintenance.
 Software is never expected to stand still after a release. There will always be odd faults to fix, no matter how much testing went on. Customers demand new features. Requirements change under the development team’s feet. Assumptions that were made during development prove to be incorrect in the Real World and require adjustments. The upshot: More code is written after the project is considered complete.Â
After software has been released, you become more restricted with what you can do. Users are dependent on published APIs and are familiar with the current UI. There are also psychological restrictions such as not being able to see a different version than how the code has always worked or not believing the product will be around for long enough to make the effort to modify it properly.'
Software rot happens whether you modify the code or not. Fixing one fault may cause the addition of other faults. Brooks found that as many as 40 percent of fixes introduced new faults. Quick-and-dirty fixes pile atop one another and act as nails in the original design's coffin. Be aware of how easily code degrades as it is modified. Do not be satisfied with changes that leave the system in a worse state.
There are many forms of rot that are easy to notice. Large classes, large functions, cryptic names, surprising side effects, lack of structure, duplication, high coupling, blurry APIs, implementation details leaking, work-arounds, functions with long parameter lists, code that you can't even consider trying to improve, out of date documentation, warnings, comments saying "Don't touch this."
There are also many more subtle and invisible degradations that manifest at a higher level than that syntactic gunk. Modifications that fudge the original code architecture or subtly circumvent program conventions are much harder to spot until you are deeply immersed in the system.
Why do we make such a big mess of code? The answer is simple: complexity. There is a lot to understand and there isn't enough time with the deadlines we are given.
How does code grow?
By luck: this is code that never had any design, it was modified without thought, its structure is down to happenstance. Maintenance modifications to well designed code can follow this approach.
Accretion: Get something working quickly rather than do it properly which there is not time for.
Rewrite: This takes courage and vision. It gets riskier as you do more at the same time. Good modularity and separation of concerns will make this easier.
Refactor: Make small changes in order to improve the internal structure without changing the external behavior. It is design enhancement.
Design for growth: Careful design allows room for growth. Do not try to guess the future and do not over-design. Over-design is especially likely when design occurs by committee. There is a school of thought exemplified in Extreme Programming that insists on using the absolute simplest design that can possibly work in any given situation.
Believe the impossible
Perhaps the problem is the mistaken belief that it takes longer to do the job properly. This is a false assumption when you factor in the time spent debugging and the ease of making later modifications.
What can we do about this?
First, recognize the problem. Before we think about how to work with existing code, consider the interconnection of modules, and reduce coupling as much as possible. Remember that modularity and information hiding are the cornerstones of modern software engineering. Think carefully about your system interfaces as you create them. Write neat, clear code that can be easily understood. Do not overcomplicate things. Simplicity is nearly always more desirable than performance.
Maintenance of existing code
Maintaining good code requires a different battle plan that maintaining bad code. With good code, you must carefully preserve the integrity of the design and do not introduce anything out of place. Only change what is necessary. Do not make many modifications at the same time (yourself). Do one thing at a time carefully.
Before making a change, you must be informed about the code you are working on. Understand where it sits within the whole system, which components will be affected by the change, what assumptions are present, and the history of modifications already made. Inspect the code's quality. Adopt the correct attitude. Be prepared to do some redesign work. Try not to introduce extra dependencies. Retain the programming style of the source files you are working with. Maintain any comments. Carefully test any modification you make.
 It’s important to maintain software well and expand it correctly, preserving the code design and making sympathetic modifications. Don’t expect maintenance to be easy. You may need to invest a lot of time to rewrite, redesign, or refactor.Â
Article notes
Thinking of software as similar to how an oyster makes a pearl or bug fixing as tending to diseased parts of the code is what metaphor?
The growing metaphor
If you were using "growing" as a metaphor for how software changes, what would be an example of something from nature that is similar to how software grows (a progressive accretion of small parts)?
How an oyster makes a pearl
Thinking of software as starting as a single-celled organism and incrementally changing into a large, complex beast is what metaphor?
The evolution metaphor
Using experiences of previous software releases to adapt the code to ensure its long term survival is thinking consistent with what metaphor?
The evolution metaphor
What is the longest phase of software development?
Maintenance
What phase does most of the overall effort in software development go to?
Maintenance
B.W. Boehm observed what percentage of total software development time is spent in maintenance?
40-80 percent
Brooks found what percentage of code changes fixing faults also introduced new faults?
40 percent
What unfortunately happens to code whether you modify it or not?
Code rot
What is the simple answer given by Code Craft as to why we make such a big mess of code?
Complexity
In software development, what commonly pile atop one another and act as nails in the original design's coffin?
Quick-and-dirty fixes
Large classes, large functions, cryptic names, surprising side effects, lack of structure, duplication, high coupling, blurry APIs, implementation details leaking, work-arounds, functions with long parameter lists, code that you can't even consider trying to improve, out of date documentation, warnings, comments saying "Don't touch this" are all forms of code rot that together might be considered?
Syntactic gunk
What form of what Code Craft calls "syntactic gunk" could taking its elimination too far lead to what APoSD calls "classitis"?
Large classes
What two forms of higher-level code rot are harder to see than typical syntactic gunk (that you may only notice once you are deeply immersed in the system)?
Modifications that fudge the original code architecture or subtly circumvent program conventions
To dispel the belief that doing software development properly always takes more time, what must you factor in?
Time saved later
What does Code Craft say are the cornerstones of modern software engineering?
Modularity and information hiding
Code Craft says that simplicity or performance is almost always more desirable?
Simplicity
In software design according to Code Craft, you should not be satisfied with any changes that do what?
Leave the system in a worse state