"Doing engineering is practicing the art of the organized forcing of technological change." (George Spencer-Brown, Electronics, Vol. 32 (47), 1959)
"A clean design is more easily modified as requirements change or as more is learned about what parts of the code consume significant amounts of execution time. A 'clever' design that fails to work or to run fast enough can often be salvaged only at great cost. Efficiency does not have to be sacrificed in the interest of writing readable code - rather, writing readable code is often the only way to ensure efficient programs that are also easy to maintain and modify." (Brian W Kernighan & Phillip J Plauger, "The Elements of Programming Style", 1974)
"Instrument your programs. Measure before making 'efficiency' changes." (Brian W Kernighan & Phillip J Plauger, "The Elements of Programming Style", 1974)
"Programs are not used once and discarded, nor are they run forever without change. They evolve. The new version of the integration program has a greater likelihood of surviving changes later without acquiring bugs. It assists instead of intimidating those who must maintain it." (Brian W Kernighan & Phillip J Plauger, "The Elements of Programming Style", 1974)
"When the operation to be done is more complex, write a separate subroutine or function. The ease of later comprehending, debugging, and changing the program will more than compensate for any overhead caused by adding the extra modules." (Brian W Kernighan & Phillip J Plauger, "The Elements of Programming Style", 1974)
"Far be it from me to suggest that all changes in customer objectives and requirements must, can, or should be incorporated in the design. Clearly a threshold has to be established, and it must get higher and higher as development proceeds, or no product ever appears." (Fred P Brooks, "The Mythical Man-Month: Essays", 1975)
"Different levels of documentation are required for the casual user of a program, for the user who must depend upon a program, and for the user who must adapt a program for changes in circumstance or purpose." (Fred P Brooks, "The Mythical Man-Month: Essays", 1975)
"Nevertheless, some changes in objectives are inevitable, and it is better to be prepared for them than to assume that they won't come. Not only are changes in objective inevitable, changes in development strategy and technique are also inevitable. The throw-one-away concept is itself just an acceptance of the fact that as one learns, he changes the design." (Fred P Brooks, "The Mythical Man-Month: Essays", 1975)
"Program maintenance involves no cleaning, lubrication, or repair of deterioration. It consists chiefly of changes that repair design defects. Much more often than with hardware, these changes include added functions. Usually they are visible to the user." (Fred P Brooks, "The Mythical Man-Month: Essays", 1975)
"Structuring an organization for change is much harder than designing a system for change. Each man must be assigned to jobs that broaden him, so that the whole force is technically flexible. [...] Management structures also need to be changed as the system changes." (Fred P Brooks, "The Mythical Man-Month: Essays", 1975)
"The beginning of wisdom for a programmer is to recognize the difference between getting his program to work and getting it right. A program which does not work is undoubtedly wrong; but a program which does work is not necessarily right. It may still be wrong because it is hard to understand; or because it is hard to maintain as the problem requirements change; or because its structure is different from the structure of the problem; or because we cannot be sure that it does indeed work." (Michael A Jackson, "Principles of Program Design", 1975)
"Cohesion can be put into effective practice with the introduction of the idea of an associative principle. In deciding to put certain processing elements into a module, the designer, in effect, invokes a principle that certain properties or characteristics relate the elements possessing it. […] Ironically, this important design concept had to be developed after the fact when it was too late, politically or pragmatically, to change designs - by asking the designer/programmer why a certain processing element was combined with others into a module. It must be kept in mind that cohesion applies over the whole module - that is, to all pairs of processing elements." (Edward Yourdon & Larry L Constantine, "Structured Design: Fundamentals of a discipline of computer program and systems design", 1978)
"Economic principles underlie the overall structure of the software lifecycle, and its primary refinements of prototyping, incremental development, and advancemanship. The primary economic driver of the life-cycle structure is the significantly increasing cost of making a software change or fixing a software problem, as a function of the phase in which the change or fix is made." (Barry Boehm, "Software Engineering Economics", 1981)
"One should not start full-scale implementation efforts based on early user interface designs. Instead, early usability evaluation can be based on prototypes of the final systems that can be developed much faster and much more cheaply, and which can thus be changed many times until a better understanding of the user interface design has been achieved."
"Our experience with designing and analyzing large and complex software-intensive systems has led us to recognize the role of business and organization in the design of the system and in its ultimate success or failure. Systems are built to satisfy an organization's requirements (or assumed requirements in the case of shrink-wrapped products). These requirements dictate the system's performance, availability, security, compatibility with other systems, and the ability to accommodate change over its lifetime. The desire to satisfy these goals with software that has the requisite properties influences the design choices made by a software architect." (Len Bass et al, "Software Architecture in Practice", 1998)
"Unit tests can be tedious to write, but they save you time in the future (by catching bugs after changes). Less obviously, but just as important, is that they can save you time now: tests focus your design and implementation on simplicity, they support refactoring, and they validate features as you develop." (Ron Jeffries, "Extreme Programming Installed, 2001)
"One problem area for refactoring is databases. Most business applications are tightly coupled to the database schema that supports them. That's one reason that the database is difficult to change. Another reason is data migration. Even if you have carefully layered your system to minimize the dependencies between the database schema and the object model, changing the database schema forces you to migrate the data, which can be a long and fraught task." (Martin Fowler et al, "Refactoring: Improving the Design of Existing Code", 2002)
"Refactoring is risky. It requires changes to working code that can introduce subtle bugs. Refactoring, if not done properly, can set you back days, even weeks. And refactoring becomes riskier when practiced informally or ad hoc." (Erich Gamma, 2002)
"Refactoring changes the programs in small steps. If you make a mistake, it is easy to find the bug." (Martin Fowler et al, "Refactoring: Improving the Design of Existing Code", 2002)
"Without refactoring, the design of the program will decay. As people change code - changes to realize short-term goals or changes made without a full comprehension of the design of the code - the code loses its structure. It becomes harder to see the design by reading the code. Refactoring is rather like tidying up the code. Work is done to remove bits that aren't really in the right place. Loss of the structure of code has a cumulative effect. The harder it is to see the design in the code, the harder it is to preserve it, and the more rapidly it decays. Regular refactoring helps code retain its shape." (Martin Fowler et al, "Refactoring: Improving the Design of Existing Code", 2002)
"As a noun, design is the named (although sometimes unnamable) structure or behavior of a system whose presence resolves or contributes to the resolution of a force or forces on that system. A design thus represents one point in a potential decision space. A design may be singular (representing a leaf decision) or it may be collective (representing a set of other decisions). As a verb, design is the activity of making such decisions. Given a large set of forces, a relatively malleable set of materials, and a large landscape upon which to play, the resulting decision space may be large and complex. As such, there is a science associated with design (empirical analysis can point us to optimal regions or exact points in this design space) as well as an art (within the degrees of freedom that range beyond an empirical decision; there are opportunities for elegance, beauty, simplicity, novelty, and cleverness). All architecture is design but not all design is architecture. Architecture represents the significant design decisions that shape a system, where significant is measured by cost of change." (Grady Booch, "On design", 2006)
"Pick the right ones [abstractions], and programming will flow naturally from design; modules will have small and simple interfaces; and new functionality will more likely fit in without extensive reorganization […] Pick the wrong ones, and programming will be a series of nasty surprises: interfaces will become baroque and clumsy as they are forced to accommodate unanticipated interactions, and even the simplest of changes will be hard to make." (Daniel Jackson, "Software Abstractions", 2006)
"Good software designs accommodate change without huge investments and rework. When we use code that is out of our control, special care must be taken to protect our investment and make sure future change is not too costly."
"Software is usually expected to be modified over the course of its productive life. The process of converting one correct program into a different correct program is extremely challenging." (Douglas Crockford, "JavaScript: The Good Parts", 2008)
"The majority of the cost of a software project is in long-term maintenance. In order to minimize the potential for defects as we introduce change, it’s critical for us to be able to understand what a system does. As systems become more complex, they take more and more time for a developer to understand, and there is an ever greater opportunity for a misunderstanding. Therefore, code should clearly express the intent of its author. The clearer the author can make the code, the less time others will have to spend understanding it. This will reduce defects and shrink the cost of maintenance."
"Agile methods universally rely on an incremental approach to software specification, development, and delivery. They are best suited to application development where the system requirements usually change rapidly during the development process. They are intended to deliver working software quickly to customers, who can then propose new and changed requirements to be included in later iterations of the system. They aim to cut down on process bureaucracy by avoiding work that has dubious long-term value and eliminating documentation that will probably never be used." (Ian Sommerville, "Software Engineering" 9th Ed., 2011)
"But the history of large systems demonstrates that, once the hurdle of stability has been cleared, a more subtle challenge appears. It is the challenge of remaining stable when the rules change. Machines, like organizations or organisms, that fail to meet this challenge find that their previous stability is no longer of any use. The responses that once were life-saving now just make things worse. What is needed now is the capacity to re-write the procedure manual on short notice, or even (most radical change of all) to change goals." (John Gall, "The Systems Bible: The Beginner's Guide to Systems Large and Small"[Systematics 3rd Ed.], 2011)
"Agile teams often do not distinguish between bugs, enhancements, or change requests. They use a general unit called change to track progress. Change seems to be a valid unit for both development and operations because operations teams primarily think in terms of changes to the production system. Using changes as a shared term for both development and operations makes it easier to stream production issues back to a work backlog (that is ideally shared by both groups)." (Michael Hüttermann et al, "DevOps for Developers", 2013)
"Good architecture provides good interfaces that separate the shear layers of its implementation: a necessity for evolution and maintenance. Class-oriented programming puts both data evolution and method evolution in the same shear layer: the class. Data tend to remain fairly stable over time, while methods change regularly to support new services and system operations. The tension in these rates of change stresses the design." (James O Coplien & Trygve Reenskaug, "The DCI Paradigm: Taking Object Orientation into the Architecture World", 2014)
"When you write a computer program you've got to not just list things out and sort of take an algorithm and translate it into a set of instructions. But when there's a bug - and all programs have bugs - you've got to debug it. You've got to go in, change it, and then re-execute … and you iterate. And that iteration is really a very, very good approximation of learning." (Nicholas Negroponte, "A 30-year history of the future", [Ted Talk] 2014)
"The fact that software engineering is not like other forms of engineering should really come as no surprise. Medicine is not like the law. Carpentry is not like baking. Software development is like one thing, and one thing only: software development. We need practices that make what we do more efficient, more verifiable, and easier to change. If we can do this, we can slash the short-term cost of building software, and all but eliminate the crippling long-term cost of maintaining it." (David S Bernstein, "Beyond Legacy Code", 2015)
"This is what the Agile Manifesto means when it says responding to change over following a plan. To maximize adaptability, it is essential to have good, fast feedback loops. This is why there is so much emphasis on iterative development." (Sriram Narayan, "Agile IT Organization Design: For Digital Transformation and Continuous Delivery", 2015)
"Why is continuous deployment such a powerful tool? Fundamentally, it allows engineers to make and deploy small, incremental changes rather than the larger, batched changes typical at other companies. That shift in approach eliminates a significant amount of overhead associated with traditional release processes, making it easier to reason about changes and enabling engineers to iterate much more quickly." (Edmond Lau, "The Effective Engineer: How to Leverage Your Efforts In Software Engineering to Make a Disproportionate and Meaningful Impact", 2015)
"Given enough time and enough users, even the most innocuous change will break something; your analysis of the value of that change must incorporate the difficulty in investigating, identifying, and resolving those breakages." (Titus Winters, "Software Engineering at Google: Lessons Learned from Programming Over Time", 2020)