The world of software development is now nearing a century. Over these years, software industry has seen drastic changes in the technologies and domains. Starting from mechanically operated binary switches to serverless computing on the cloud, it has been a long journey. But some of the core principles have and will remain untouched and unchanged. One of the most important (and also most neglected) one is the importance of a good Design & Architecture.
Its importance can never be exaggerated. Unfortunately, that is where projects squeeze their time and end up in disaster. Here, we will look into several core principles of design.
These years have seen some fundamental changes in software development. The complexity of software applications has grown exponentially. The trade-offs between memory, network and processing have changed their base. There was a drastically but asymmetric growth in each of them. Naturally, there were changes in the principles and patterns of design. But not in its importance.
Before proceeding, we must note and understand an important point. Using Design Patterns does not imply a good design. Just because we have used several patterns does not mean that we can develop highly maintable and reusable code. Certainly not. These patterns can at best, provide a good, tested way of going around a design component. But it is important to understand which pattern is meaningful in a given design. Without this understanding, they are meaningless.
Each phase of software development brought forth a new set of design principles that replaced the older ones. These were not any better or worse. Just that some are more relevant in the given constraints of the application development. Let us have a brief look at some of the important ones.
Functional desigh patterns can be classified into Data Structures and Algorithms.
Object Oriented Design Patterns can be classified into three main types:
The list can never be exhaustive. Many more patterns will evolve as the constraints and requirements change. But the fundamental concepts of design and the importance of a good architecture will never vary.
Long long ago, we started with assembly code on microprocessors. Here, everything was restricted. The code size was limited by the ROM size. The processing power was limited by the clock speed and the RAM size. And there was barely any concept of connectivity. The design in those days was focused on reducing the code size and resources - not on reuse. That was possible because the applications were never so complex and redevelopment of modules was hardly a problem.
Over the years, as the processing power increased, it was possible to increase the complexity of the software. That brought in programming languages. It brought in the concept of reuse of software. Now, it was important to create software modules that could be reused. This changed the requirements of a good design. Another criteria was added to the concept of a good design - reuse. The others like performance were relaxed a bit.
Over the years, as the processing power and complexity increased further, we had to do more. Just reuse was not enough. It had to be maintainable. What one person developed was maintained and enhanced by another. So we had to develop code that was readable and maintainable and reusable. All this came at a price of performance and that was tolerable.
This trend followed, and today, most of the applications work on micro-services on the cloud. One barely knows how a functionality is implemented. The code just invokes an API and expects that the job is done. Most of this works over the network. This is a terribly inefficient use of network bandwidth and processing power. But we can afford it because of the amount of complexity, reusability, maintainability we can pack into our application.