This is a rather vague question, but it's something I've never felt has been answered in a satisfactory way when reading about proper design.
Generally, when learning about Object Oriented programming, abstraction, factoring out, etc, the holy grail of design - and the reason they always claim you're using the development techniques in question - is that it will make your program "easy to change", "maintainable", "flexible", or any of the synonyms used to express such a productive-sounding concept. By marking ivars private, splitting code up into many small, self-contained methods, keeping interfaces general, you supposedly gain the ability to modify your program with total ease and grace.
For relatively small changes, this has worked well for me. Changes to internal data structures used by a class to increase performance has never been a major difficulty, and neither have changes to the user-interface end, independent of the API, such as redesigning a text entry system or overhauling the graphics for a gameplay element.
All of these changes seem inherently self-contained. None of them involve any changes to the behavior or design of the component of your program being modified, as far as outside code it concerned. Whether or not you're writing procedurally or in an OO style, with large functions or small, these are easy changes to make even if you have only a moderately good design.
However, whenever the changes become big and hairy - that is, changes to the API - none of my precious "patterns" ever come to the rescue. The big change remains big, the affected code remains affected, and many hours of bug-spawning work lie ahead of me.
So, my question is this. How big a change does proper design claim to be able to facilitate? Is there some further design technique, either unknown to me or that I have failed to implement, that truly does make sticky-sounding modification simple, or is that promise (which I have heard made by so many different paradigms) merely a nice idea, completely disconnected from the immutable truths of software development? Is there a "change tool" I can add to my toolbelt?
Specifically, the problem I am facing that's led me to the forums is this: I've been working on implementing an interpreted programming language (implemented in D, but that's not relevant), and I've decided that my closures' arguments should be keyword-based, rather than positional as they currently are. This requires modifying all existing code that calls anonymous functions, which, luckily, is rather small because I am early on in the development of my language (< 2000 lines), but would be enormous if I had made this decision at a later stage. In such a situation, is there any way that by proper foresight in design I could have made this modification easier, or are certain (most) changes intrinsically far-reaching? I'm curious if this is in any way a failure of my own design skills - if it is, I'd be very eager to improve them with the necessary reading material if there is a way to ameliorate the severity of the problem.
To be clear, I am in no way skeptical of OOP or any of the other patterns commonly in use. For me, however, their virtues are in the original writing, rather than the maintaining, of code bases. Inheritance allows you to abstract repetitive patterns out well, polymorphism allows you to separate code by human-understood function (which class) rather than by machine-understood effect (which branch of the
switch statement), and small, self-contained functions allow you to write in a very pleasant "bottom-up" style. However, I'm skeptical of their claims of flexibility.