In preparing for this post, I have spent a good deal of time trying to make sense of the history of software design patterns and how they could actually relate to the physical world. While recovering from a highly pollenated day out in Athens, I found much of the information interesting but at times like an acronym soup filled with a new language to further confuse the reader. This blog post is an attempt to bring some simplicity to this process and explain to the novice.
When discussing the development of any great project one need only to look at history to see when things are planned well and executed with flawless perfection, that it will stand the test of time. Take the ancient Egyptians with the pyramids, or the Romans with the aqueducts. Both were engineered thousands of years ago and still there today. In fact, some aqueducts are still used on a daily basis. What does this have to do with software development you may ask? Simple, when something works in the physical world such as architecture, it will get reused and refined. As structures become more stable, the design becomes more fluid - the same follows in programming. Look at the simple arch as an example. Early arches were simplistic and modern arches can now have vast spans. When an architect decides to build a home, he or she will create the formal drawings and plans. Even if they know something about building the home it is unlikely that they would be the ones installing the electrical wiring, the plumbing or doing the sheetrock. The same is true for software. First, you need to have a solid plan which acts as the blueprint for the project. As with a home, blueprints usually have to be revised numerous times before their final completion and it is also possible that changes have to be made after the project is already underway. This is often the case in software development where there are those who are working on the project, the project manager and the customer. Translating the customer’s need into the programming necessary to complete the task can be an often difficult and cumbersome undertaking.
Software creation has been in an evolution since its inception in the 1940s. Early programming languages were not focused on finding portions of code that worked that could be reused in the future. Modern programming takes the object oriented approach which uses and reuses proven code repeated times making the programs less prone to error and providing consistency for the end user. This brings us to patterns – which in carpet or wallpaper is simply an image or shape repeated over and over. Could this have a place in the computer world???? Of course! Loops repeat commands over and over until they are told to stop and in the object oriented world, we would reuse those patterns which would successfully generate the desired outcome in the software.
Enter Christopher Alexander, noted Architecture expert, Professor, Author and Mathematician. What could he contribute to the software design world? Plenty! In the 1977 book, A Pattern Language (by: Alexander et al), he explains that “a pattern language is about patterns being like words. They stay the same but can be combined in different ways like words in a sentence. They can be used as in a network where one will call upon another. When you build something you can put patterns together to form a language.” (Source: patternlanguage.com) Sounds simple enough. It is a close parallel to how we would want to construct well organized programs.
There are several main works which use Alexander’s ideas and apply them to programming. Beginning first with works by Kent Beck and Ward Cunningham at the OOPSLA Conference in 1984, Coplein & Schmidt’s Pattern Languages of Program Design Gamma, Helm, Johnson & Vlissides (the so-called Gang of Four) Design Patterns: Elements of Reusable Object Oriented Software and Gabriel’s Patterns of Software.
Design patterns can help speed the process along in programming by using proven templates to solve problems. Typically the programming design pattern falls into one of the following categories: Creational Patterns, Structural Patterns, Behavioral Patterns or Concurrency Patterns. Additionally, there are Anti-Patterns – that go against the ‘pattern’ – there are many anti-patterns which can affect software development.
From a software design perspective, a design pattern is a reusable solution to a recurring problem. It is not the finished programming code but instead a template which will guide you to the proper solution for the problem at hand. This is reminiscent of Alexander’s work. If you are building a house or building a city, there are specific templates which offer a proper solution for the best use. As a guide, it is best for light to enter a room from two directions by simultaneously maintaining as much of a complete wall as possible. That way, the builder or architect has the flexibility to decide where the windows are best suited but is not specifically told exactly where to place the windows on the blueprints. It is much the same in programming, if you know that you need to put a particular component into the program, there is some flexibility to how it is done which is where the design pattern comes in to play.
One example of a Concurrency Pattern is using the idea of a Lock. It prevents more than one person or process having access to the data at one time.
In the above example, using a personal bank account, accessing online would lock out the ATM access and vice versa so that only one would have access to the bank account data at one time. This is often used in a database to prevent multiple people accessing and potentially causing errors.
Anti-Patterns can be just as helpful to ensure that you are following good design principles. It can help you find ways to remedy poor coding and provide a better alternative. When an anti-pattern is detected, it is generally because the code created is ineffective or wrong. Anti-Patterns differ from a bad idea or poor coding in that the action initially seems to be beneficial but instead produces more bad results and a refactored alternative to the anti-pattern exists and is proven effective. Refactoring is a process where code is altered but the functional parts are still the same, the non-functional parts are adjusted to make a better solution. The names for many anti-patterns are similar to familiar terms that come from the boardrooms across the world.
Anti-Patterns are typically classified in one of the following categories: Organizational, Project Management, Analysis, Software Design, Object Oriented Design, Programming, Methodological or Configuration Management. As part of the humor, the following are some of the types of Anti-Patterns: Death March, Big Ball of Mud, Analysis Paralysis, Mushroom Management, Lava Flow, Spaghetti Code, Reinventing the Square Wheel and Dependency Hell. All of these are readily known to programmers although it is possible to be so deep into a project to not realize that the problems are all around.
Much wisdom can be acquired by diving deeper into the subject and I recommend taking some time to read further on both Design Patterns and Anti-Patterns as doing so will help the novice programmer begin to avoid some of the pitfalls that colleagues found before.
More Later,
CH
No comments:
Post a Comment