One of the most basic questions of design is: What is abstraction? Abstraction is one of the key tools of software design; it is necessary for managing the immense and ever-growing complexity of computer systems. The common answer to this question usually has something to do with objects, thereby reflecting the large body of literature and tools that have emerged over the past decade or two to support object-oriented techniques. But this response ignores useful design structures that are not object-oriented: templates, families of overloaded functions, modules,generic functions, and others. Such use is particularly common in the C++ community, though it is by no means unique to that community. And the perspectives both of experience and practical application substantiate the need to go beyond any single approach (such as object orientation) even if there were compelling arguments for the superiority of any single technique (which there probably are not).
Jim Coplien's PhD Thesis presents a broad design method called multi-paradigm design. The broad goal of multi-paradigm design is to understand how to build systems that capture the structure of their domains in ways that support intentionality, software comprehension at the system level, and greater ease of evolution. These are not just academic concerns, but practical concerns for the everyday programmer.