“Elements of Reusable Object-Oriented Software” is a book that I am sure all self respecting software developers have read. The infamous Gang of Four book seems to shape everything we do in modern object oriented software development and by applying the principles contained within generally results in a quality software product.
One common (but slightly controversial) view on design patterns is that generally they only exist to patch up any shortcomings of the language. If a language can solve a problem in a trivial way then it may well have no need for a design pattern at all. This can be demonstrated by developments within the .NET Framework, for example the “Iterator” design pattern is embedded within the language through the IEnumerable interface, reducing the need to implement the pattern yourself.
Microsoft F#, due to ship with Visual Studio 2010, is primarily a functional programming language and supports all the features you would expect, such as functions as first-class values, currying and immutable values. As F# is fully integrated into the .NET framework it can also be used in an imperative or object oriented way.
So in a multi-paradigm language is there a need for software design patterns? Do we need to worry about design patterns in F#, and if so how do we apply them.
Some articles I have read recently have gone so far as to suggest that the design of functional languages eliminates the need for design patterns completely. This is however only partially correct.
There are some design patterns that are rendered obsolete by functional languages, take the Command pattern as an example. The Command pattern as documented by the Gang of Four enables you to:
“encapsulate a request as an object, letting you parameterize clients with different requests”.
This is simply an approximation of a first-class function. In F# you would simply pass a function as the argument to another function.
In an object oriented language, you have to wrap up the function in a class, which you then instantiate and pass the resulting object to the other function. The effect is the same, but in the object oriented world it's called a design pattern.
The same can be said about the Abstract Factory pattern. The Abstract Factory enables you to:
“Provide an interface for creating families of related or dependent objects without specifying their concrete classes”.
In F# this is known as currying. Currying is the process of transforming a function that takes multiple arguments into a function that takes just a single argument and returns another function if any arguments are still needed.
It is clear therefore that several design patterns are rendered redundant in F# because the language provides more powerful, succinct alternatives. There are however still design problems that are not solved within F#. There is no F# equivalent for the Singleton pattern for instance.
Interestingly it works the other way too. Functional languages have their own design patterns; you just tend not to think of them that way. You may have come across “Monads”, which are a kind of abstract data type and often used for handling global state within functional languages. This is a problem that is so simple to solve in object oriented languages that there is no equivalent design pattern.
So while it is true that some object oriented design patterns become redundant in functional code, many, such as MVC do not.
So if you’re working with F#, don’t forget about design patterns, you never know you may even come across some new ones.
4 comments:
Every once in a while I think to myself that I should revisit design patterns, but when I do start reading up on them, it just smacks of common sense (and reading the GoF book is like wading through treacle!).
I'm an accomplished "expert level" programmer/developer of 20+ years (10 of which in an OO environment - Delphi & C#). I've never consciously thought about design patterns; good OO design just comes naturally and falls out of the analysis & design process.
My personal opinion is that "design patterns" is an academic buzzword, and not something you should get too hung up on. With a couple of years' experience good OO design will become second nature.
Hi Andy, Thanks for your comment.
I think you make a valid point in some respects. Quite often the use of design patterns can over complicate and confuse the architecture of an application, just take a look at the Java.io package which makes far too much use of the decorator pattern!
A common mistake made by many new developers is to “design by pattern” and I think we would all agree that this is a very poor approach. However design patterns do exists and they do have a very real place within software development. I’m certain that you use them on an almost daily basis without even realising it. If you’re working with Silverlight or Windows Presentation Foundation for example you must certainly be working with the Model View View Model pattern.
At the end of the day, a design pattern is just a “solution to a common problem”. The source of the solution, be it good OO design or the GoF book, does not really matter. The important thing is that your code is as well designed as possible.
I've often used design patterns as a target to refactor towards; I'll write the code, then identify whatever patterns I can find, perhaps emphasising them in the refactoring.
Then the patterns given me a vocabulary for discussion, eg. "a composite containing flyweight singletons, iterated over with the given visitor".
All commenters have missed the main point of this article.
Design patterns exist in OO languages to overcome the inherent flaws and deficiencies in the paradigm.
Functional programming (have you looked at Clojure?) will free you from the chains of slavery of OO and design patterns. Free your mind - become functional!
Post a Comment