Blogs About Technology, GTD and Life
8 Nov
I have always admired the cleverness of the name Hollywood Principle. I love its name! The essence of this principle is “don’t call us, we’ll call you”. As you know, this is a response you might hear after auditioning for a role in a Hollywood movie. And this is the same concept for the software Hollywood Principle too. The intent is to take care to structure and implement your dependencies wisely.
At its most basic level, the principle is about reducing the coupling in a software system. It gets back to the well known phrase in software development: loose coupling and high cohesion. You can keep classes loosely coupled by ensuring that you don’t have unnecessary references and you are referencing classes and other subsystems properly. Although the Hollywood Principle does not dictate anything about cohesion, it is an important aspect too. Cohesion is about keeping your classes true to their intent and not allowing their behavior to expand beyond its core purpose. Like high coupling, low cohesion doesn’t tend to cause systems to be unstable or not work properly, but will likely lead to difficulty in maintaining the software.
One of the most popular ways to implement, or obey, the Hollywood principle is to use events or callbacks. A well known pattern that follows the Hollywood principle is the observer pattern. This pattern allows one to observe the state of an object in a well defined and non obtrusive manner. It is typically implemented by injecting a callback object (observer) into the class to be observed (subject). The subject simply raises an event in all observers when its state changes. How the observer reacts to the event is outside the scope or care of the subject.
Dependency Injection (DI), which is a form of Inversion of Control (IoC) is another example of the use of the Hollywood principle. Take for example a shopping cart class that requires a reference to a currency conversion service. Traditionally, the shopping cart class would be designed with a reference to the currency convesion service or use a factory to get a reference to the appropriate service implementation. By contrast, using DI, an external mechamism (e.g. Spring or Spring.net) automatically provides a reference to the required currency conversion service at the time the shopping cart class is instantiated.
25 Jan
Software design patterns have been around for many years. And as most who follow design patterns know, they gained tremendous traction after Gamma, Helm, Johnson, Vlissides (these gentlemen are fondly known as the Gang of Four (GoF)) released their book Object-Oriented Design Patterns book.
What many don’t know is that design patterns have their roots in architectural patterns. Not architecture as in computer software or computer network architecture design, but architecture as in buildings and towns. Christopher Alexander coined the term “pattern” in the late 1970s in his writings. If you want to get into the heart of the origins of patterns, you can check out his original book The Timeless Way of Building. And his second edition (with additional authors) A Pattern Language: towns, buildings, construction. Although Alexander’s books are interesting from a historical perspective, they will provide little value in your pursuit of software design patterns while taking a large divot from your wallet.
So what are software design patterns? They are solutions to common problems that developers and architects face. Many software design patterns address common situations that developers need to implement in every application they build (e.g. object initialization). Take just about any programming problem and there are only a few good implementation approaches, but many bad approaches. Software design patterns capture the experience of experts in a form that others can reuse.
In the early 1990s, the best source for information on software design patterns was definitely the GoF Object-Oriented Design Patterns book. At my previous employer, we issued the GoF book to all new developers because the book defined a set of well thought through patterns but more importantly defined a new lexicon. The introduction and popularization of the software design pattern lexicon provided a common language for developers to express design options in a very concise manner.
The GoF book was revolutionary because it defined many core pattern names and provided details regarding the intent of the patterns and also included some code snippets to clarify the suggested implementation approach. Unfortunately, the code samples for the patterns are written in C++. Today, with a large portion of business applications being developed in Java, PHP and .NET, you may find the GoF book harder to consume than some more recent pattern books such as Head First Design Patterns for Java and Design Patterns for C# for .NET.
In addition, Martin Fowler’s book Patterns of Enterprise Application Architecture has been very influential. In his book, Fowler identifies new enterprise patterns and provides clarification and enrichment to other lesser-known patterns.
GoF defined four essential elements that are required for any software design pattern:
GoF felt that a problem to be solved by a software design pattern must be seen repeatedly in practice to prove the pattern is applicable beyond the system in which it is first identified.
Patterns are typically divided into 3 categories:
Most patterns cannot be read once and completely understood. If you want to be able to use a pattern, you must approach pattern literature with the attitude that you will study the patterns rather than just read them. Some patterns have slight variations between different authors and sometimes slight differences in their sample implementation approaches. Sometimes these differences are a result of different technology platforms and languages. For example, patterns in .NET tend to leverage .NET platform-specific capabilities such as generics and delegates.
However, when learning a new pattern, the single more important take-away is to understand its intent. Otherwise, some patterns start to look alike and many patterns are implemented in a similar fashion by introducing an interface, abstract base class, level of indirection, aggregate object, etc. For example, in .NET the Role Object Pattern (ROP) and State Pattern are similar in their implementation. Both patterns start with a primary class that needs to either have a role or have a state. At first glance, especially by scanning their UML, they appear to be almost the same.
However, after studying their UML more carefully, their implementations are very different - primarily because ROP aggregates one or more roles that are reference by their Role interface and the State Pattern is associated with one state, which is referenced through an abstract base class. But the biggest difference is the intent behind the two patterns - ROP gladly exposes the role(s) from the class and embraces the concept of a role. To the contrary, the State Pattern hides the concept of a state class and just provides a simplified state value to its consumer.
Although patterns are meant to be implementation independent, most texts provide sample implementations. If you do most of your work in one programming language, you will greatly benefit by finding a resource on patterns that has accompanying examples written with your primary language. Even though you might be able to translate say from Java to C# you may miss some platform-specific features in C# during your implementation. For example, some .NET patterns are written to leverage .NET delegate (which are essentially function pointers to simplify threading) and the Observer pattern will leverage the .NET events/event handlers.
In future blogs I will address many GoF software design patterns and provide working samples in C#.