Friday, February 7, 2014

Software Design Patterns...there are a lot!

So, I knew that there were quite a few software design patterns, but I'd never really looked at any of them in great detail. The basic concept behind a software design pattern is that it provides a template that can be followed in order to solve a certain problem in a given situation. In essence, they are best practices that are implemented by the developer. Apparently there are software design patterns for everything from algorithms to structural design. As mentioned in class, these patterns are to developers what blueprints are to builders. They guide the developer in creating a program that will hopefully be better because it is based on a pattern that has been tested, used, and has been proven to improve the software structure and help prevent certain problems and issues from arising.

Obviously, a developer can't just choose any software design pattern since each is best suited for specific purposes (for instance, you probably wouldn't want to use a Monad design for an object-oriented project). Thus, it is up to the developer to choose the design that best fits their program and inappropriately choosing a design could harm the final project by introducing confusion and complications.

A problem with using a software design pattern also comes from the generalization of the design. The design cannot be too specific or else it will not work for majority of applications. Thus, the design has to contain some abstraction (or indirection as Wikipedia mentions) in order to remain flexible. This can introduce complications into the resulting software because of misunderstandings about how to implement the abstractions and can cause performance issues with the application.

I picked out a few of the patterns mentioned in the article to discuss here.  The Interpreter pattern was especially interesting to me because I had to create an interpreter and parser for a calculator in a previous class. The Interpreter pattern basically provides a framework for interpreting a computer language (or something as simple as interpreting reverse polish notation). Each symbol in the language is given its own class (and it does not matter whether the symbol is terminal or not) and this class defines how to interpret that symbol. For instance, a Number class's interpreter function would return a number while a Plus class's interpreter would return the sum of it's left and right operands. I essentially used this method when I created my calculator, but I did not know that it was an actual design pattern. The pattern is helpful in that it provides a basic structure for creating the interpreter for a language, which can then be combined with a parser.

Another pattern that I looked at was the Decorator pattern. This is essentially a way of standardizing wrapper creation for a class. For instance, you have a class that has almost all the functionality you need except for one or two operations or components. In order to add this functionality, you create a decorator class which would extend the original class (or interface) and take the original class as an argument to the constructor. The additional functionality is added to this object once it is passed into the decorator class. As the example in the Wikipedia article shows, you could have a Window interface, subclass it into a WindowDecorator interface, which takes a Window as the constructor's parameter, and then further subclass the WindowDecorator to provide extra functionality such as scrollbars. This makes it extremely easy to add or remove features from a specific object without having to create ridiculous subclasses such as MyHorizonatalVerticalScrollBarBorderedWindow. 


I also looked at the Wikipedia article "Software Design Patterns" in order to find a more complete list of such patterns. Browsing through them, I recognized some templates that are used in the coding languages that I use. For instance the "Hollywood Principle" is used in the Enterprise JavaBeans framework. The idea behind the Hollywood Principle is "Instead of your program running the system, the system runs your program." Basically this method allows the programmer to focus on creating the application without having to worry about all the system calls that happen behind the scenes. In essence, approaches that use this technique will provide a framework that the developer must follow and build on. This is helpful in that it allows the developer to focus on the specifics of the application being built, but it could also be restrictive or time-consuming if you have to create functionality that is not necessarily supported by the framework.

No comments:

Post a Comment