Showing posts with label Design Patterns Discussion. Show all posts
Showing posts with label Design Patterns Discussion. Show all posts

Monday, July 16, 2007

Is Inversion of Control just a fancy name for other well known patterns?

I've recently come upon a lot of content on the web in regards to the inversion of control pattern. One of the best articles in this regard is Martin Fowler's Inversion of Control Containers and the Dependency Injection pattern article. After reading the article and playing around with a couple of the frameworks (see Castle Project & Spring.Net) available that aim to ease the use of an Inversion of Control Container a thought popped into my head: Isn't Inversion of Control just a fancy name for the "abstract factory" or "strategy" pattern thoroughly explained by Gamma in his famous design pattern book? Being a pattern fanatic I had to explore a bit more and this post is basically what I have surmised on this interesting subject.

To start I want to make one thing very clear: the phrase "Inversion of Control" is being overused/misused (like so many other phrases) and Martin Fowler's distinction on what is Inversion of Control (the general definition) and what he calls Dependency Injection, which is what we would be discussing, is very clear and to clarify the issue please read the section titled "Inversion of Control" in his article.

In order for us to start comparing dependency injection with other patterns let's get a clear definition of dependency injection first. My explanation here will be brief in order to provide a general overview and the major points in relation to dependency injection for a thorough definition either read Martin Fowler's article or just do a little search on "Inversion of Control" you can't miss the vast array of detailed explanations that are out there! J

One major problem that causes coupling and headaches in software design is when a designer creates a class A and then his/her class needs to use class B in one way or the other and he/she creates an instance of class B directly. For example:

class A {
B myB = new B();
void f() {
//do something with myB
}
}
class B {
//implementation of class B
}

The problem with the above design is that class A is dependent on class B in such a way that if for any reason (testing, future expansion, etc.) we need to replace B's implementation with something else (something that supports the same interface, but has a different implementation) we need to rewrite code. Dependency injection is the simple concept of creating class A in such a way so that we can later on "inject" its dependency on the "right" class not a fixed implementation. In other words what if we could create class A that would use an instance of B but the actual implementation of that was instantiated would be left for later on. So A could use B1 or B2 or any other class that implemented the B interface. Sounds too abstract? Let's talk about concrete examples:

Suppose we are going to use ADO.net to access a SQL server database and you write this code in your DAL layer components:

SqlDataAdapter a = new SqlDataAdapter(…);
//other lines of code that use the data adapter

The problem with the above code is that we have made ourselves dependent on the Sql implementation of ADO.net and in the future when our program needs to do the same exact thing with the Oracle classes we have to rewrite code. Now some people might be jumping up and down at this point screaming "use OleDbDataAdapter or use OdbcDataAdapter since they are vendor neutral ways of accessing data." Yes we could do that but that misses the whole point of this exercise: we are trying to create a DAL component that can be injected with the right dependency to use either Sql or Oracle or some other connection mechanism, we don't want to use a general method such as OleDbDataAdapter since it is too general and we will lose some of the features of native connectivity (i.e. performance). Anyhow let's not get bogged down on the specifics of the example and just assume that in developing the above mentioned DAL layer components we want our components to be independent of any specific implementation and allow us to inject (I love using this term!) them with the right implementation.

OK first things first: we need to make sure our DAL components try to use something a little more abstract than just SqlDataAdapter. Obviously this is necessary to make sure that we can later on replace the SQL based implementation with something else. Fortunately the ADO.net designers had designed some general interfaces for the most common ADO.net classes and in this case we have the IDataAdapter interface. So my DAL layer code would look like this:

class DAL
{
public IDataAdapter Adapter;
public void Save(/* … */)
{
//use the Adapter variable to do the saving
}
//other functions with similar implementations
}

The issue here is how to initialize the Adapter member variable so that it can be used by the DAL class. Here is where dependency injection (or Inversion of Control or IoC) comes into play.

The dependency injection pattern states that an outside component sometimes known as the Inversion of Control Container will take care of making sure the Adapter field (in this example) is filled with the right object (implementation) before it's used. How it does that is based on three variations of the pattern:

Type 1 IoC (or what Martin Fowler calls interface injection): you make sure that the DAL class implements an interface that has an "inject" method for assigning the Adapter property. Then during the application configuration or a similar phase based on some configuration we would inject into the DAL class the "right" implementation of the IDataAdapter that we need. For example if the config file says SQL Server based then our configuration code would create a SqlDataAdapter and inject into the DAL using the interface:

interface IAdapterInjectable {
void InjectAdapter(IDataAdapter a);
}
class DAL : IAdapterInjectable {
public void InjectAdapter(IDataAdapter a) {
Adapter = a;
}
private IDataAdapter Adapter;
public void Save(/*…*/) {
//save using the Adapter
}
}

Type 2 IoC (or what Martin Fowler calls setter injection): your DAL class implementation has to have a property setter that the configuration code will use to "inject" (by setting the value of the property) the right adapter into the class:

class DAL {
public IDataAdapter Adapter {
get {
return _Adapter;
}
set {
_Adapter = value;
}
}
private IDataAdapter _Adapter;
public void Save(/*…*/) {
//save using the Adapter
}
}

Type 3 IoC (or what Martin Fowler calls constructor injection): I guess this would be pretty obvious. In this method the constructor of our DAL accepts an IDataAdapter and when it's created the code responsible for its creation has to pass the right adapter implementation to it.

In all three cases the dependency injection has happened by somehow assigning the right implementation to the class that is dependent of an abstract interface and it has been assumed that we can take care of this assignment in our "configuration" section very easily. The reality is that configuring these classes with the right injection can sometimes be hard and in other cases is not worth the effort so like any other design pattern IoC should only be used when it is necessary and the extensibility it provides is worthwhile. The good thing about readymade IoC frameworks such as Spring.net or Windsor class of the Castle Project is the fact that they take care of the configuration section and also provide that configuration based on an XML setting. So all you have to do is create your classes, make them dependent on an abstract interface and allow the framework to fill in the blanks (or inject the dependencies) based on some XML configuration. For a very good example of this please see this article in MSDN.


 

The Big Question:

Now let's get back to the issue of this post: Is the IoC or dependency injection pattern just another fancy name for already existent patterns? Let's see what we can compare the IoC to or better yet if we didn't know about IoC how would we go about designing to cover for the above problem?

Before being exposed to Inversion of Control, whenever I had to deal with flexibility requirements such as the above I would either design my classes using Abstract Factory or the Strategy pattern. Each situation had different details therefore I would pick between the two patterns based on the requirements but they where my main choices. So for example if a design got to the point where my code needed to create a concrete implementation that might change in the future or might not be known until later on AND was fixed for the duration of the program execution I would go with the Abstract Factory pattern combined with a polymorphic singleton (see here for an explanation).

If in other scenarios I needed to "configure" my code to use different methods and the programmer/designer who was using that class had the right information to make the decision in regards to which implementation to use I would go about using the Strategy pattern. The Strategy pattern provides enough flexibility so users of my code could configure it (or plug into it) the right implementation. And finally the above 3 different types of IoC would be different ways to assign the strategy implementation to the context (my code).

So what's the big deal? If the strategy, abstract factory and many other "old" patterns could take care of that level of flexibility why do we need another fancy name, other than the fact that "injecting dependency" into your code just sounds too cool?

Well if you look deeper into what the IoC is trying to achieve first of all you realize that IoC is not just a fancy name but a totally different point of view toward this problem. Although the Abstract Factory and Strategy pattern each try to resolve the problem that IoC tackles in different ways both of them are general patterns and techniques for different (although partially overlapping) problems therefore the reader sometimes loses his/her focus on the problem. Dependency injection (or IoC) will give you a better more focused pattern in regards to what we are trying to achieve (decoupled components that would otherwise be tightly coupled due to the type of usage that exists between them).

Plus the articles, documents and frameworks surrounding IoC cover a lot more than a flexible way of encapsulating creation logic. They also provide us with a very strong and flexible base set of classes and readymade components that take care of a lot of the detailed implementation issues in regards to setting up the environment necessary for achieving true configurable component independence. Therefore a lot more reuse and stability is achieved when these frameworks and the IoC concepts in general are used as opposed to designing using Abstract Factory or Strategy from scratch.

Finally this pattern, like so many other patterns, techniques and concepts, is built on top of pre-existing ideas and implementations and there is nothing wrong with that. And not only is it built on top of these existing ideas it also provides a very good encapsulation and focus on the problem and its solution as compared to the more general Abstract Factory or Strategy pattern.

Thursday, May 24, 2007

The much debated Singleton: Part II

As I mentioned in my previous post regarding the singleton pattern I've seen a lot of talk on different blogs/forums regarding the evils of the singleton pattern. I've tried to cover the general concepts of where this pattern should be used and where it should be avoided in the previous post I made regarding this issue (read here) and in this post I'm going to quote a couple of the stuff that I've found and post my reply to them in here. So here goes: My responses in bold.

The items that I found on http://c2.com/cgi/wiki?SingletonsAreEvil

  • Someone had mentioned that when you use the singleton pattern you suddenly have two types of objects:

    "those that can be instantiated in a standard fashion and those that cannot be created at all. I would personally rather use a container which governs the number of a given object that can exist in a system and acquire the objects from the container"

    We already have a lot of different types of objects that can be instantiated (or not instantiated) in different ways this isn't a particular problem with the singleton pattern but quite the opposite, the singleton pattern is using one of these different types of language mechanisms to obtain what its aiming for (the fact that no one should be able to instantiate the object unless they go through the single point of access). As an example we have interfaces, abstract classes, sealed classes, protected & private constructors, static classes and a whole lot of different types of classes that some you can instantiate in the regular way (using new) and some you can't (and some you are not allowed to instantiate period; e.g. the abstract class). Anyway this isn't a really good argument against the use of the singleton pattern.

  • Someone else had mentioned this:

    "Singletons usually are used to provide a single point of access to a global service. I always make the singleton separate from the class itself so the class can be used any way you want. The singleton can then use the class. The singleton also doesn't have to instantiate the object"

    One of the points of the singleton pattern is to prevent accidental or purposeful creation of the singleton object, that's why it has a private constructor so one can create it except for the singleton class itself which knows when and where to create it. In regards to the second part I have seen C++ code that uses the "friend" keyword to have a separate singleton factory than the singleton object itself but I really can't see any use for it. You need a single point of access you also need a class that can be instantiated in a controlled manner why are you making your design complex and the programmer using your design confused by making him deal with (and understand) two classes (albeit one being very small and simple). I guess you might come up with very rare cases where this would be useful but in general I think sticking with a singleton class that also provides the single point of access is the best way to go.

  • A couple of people where mentioning coupling issues with singleton class names and/or polymorphism issues with the singleton:

    "Subsystem's coupling to Singleton's Class Name" or "Singletons aren't polymorphic"

    Let's make something very clear singletons are polymorphic (please read the section regarding polymorphic singletons in this post) and let's also focus on something else the whole reason we are using a singleton as opposed to a global variable (or static member) is because it allows us to deal with the single point of access issue through an object oriented fashion. It allows us to have all the OO design techniques, design patterns etc. at our disposal when we are dealing with a singleton just as we would when dealing with other classes & objects. So all general OO design techniques and features apply to a singleton.

    Regarding the first argument: your different subsystem's are going to be dependent on some single point of access (because you've made that design decision) now it's a lot better that you implement it using the polymorphic singleton pattern just to make sure that they are only dependant on an abstract class (the singleton being that abstract class) not on the actual implementation.

  • An amusing one:

    "Doesn't a C# static class, with its static constructor, provide all the functionality you would ever need from a singleton?"

    OK I think this guy has missed the whole point of the singleton. If you use a static class that means all member variables/methods are static and then you might use the static constructor to initialize some of these member variables, BUT this isn't object oriented programming this is a feature simulating the procedural way of design & implementation. Why have the designers of the C# language decided to include it there? Well one reason being the fact that you will need utility classes (methods) that are pure static classes and you don't need a real object to respond to the calls (another design decision) but a utility (or pure static class) is just a bunch of methods but a singleton is a full blown object instantiated from a class the only difference being that only one instance (or a limited number of instances) exist of it.

    If you think this argument is correct you should try to first understand the singleton pattern and then come back and re-read what the argument is saying!


These items I've found on http://www-128.ibm.com/developerworks/webservices/library/co-single.html

  • "There is one implementation anti-pattern that flourishes in an application with too many singletons: I know where you live anti-pattern. This occurs when, among collaborating classes, one class knows where to get instances of the other."

    This will be a problem when you overuse the singleton pattern, but correct usage of the pattern especially in places where there is a strong domain reason or a legitimate technical requirement backing its existence but otherwise over-use of the pattern will cause the above mentioned problem.

  • "Where's the harm? Coupling among classes is vastly increased when classes know where to get instances of their collaborators. First, any change in how the supplier class is instantiated ripples into the client class. This violates the Liskov Substitution Principle, which states that you should allow any application the freedom to tell the client class to collaborate with any subclass of the supplier. This violation is felt by unit tests, but more importantly, it makes it difficult to enhance the supplier in a backward-compatible way. First, the unit tests cannot pass the client class a mock supplier instance for the purposes of simulating the supplier's behavior, as described above. Next, no one can enhance the supplier without changing the client code, which requires access to the supplier's source. Even when you have access to the supplier's source, do you really want to change all 178 clients of the supplier? Weren't you planning on having a nice, relaxing weekend?

    Collaborating classes should be built to allow the application to decide how to wire them together. This increases the flexibility of the application and makes unit testing simpler, faster, and generally more effective. Remember that the easier it is to test a class, the more likely a developer will test it."

    Again I think this a case of misuse of the pattern. Let's straighten one thing out the fact that a singleton is a class that by default you're not suppose to instantiate doesn't mean that it can't have sub-classes and doesn't mean that replacing it with "stub" classes for the purpose of testing would be impossible. I feel I'm repeating myself too much but a polymorphic singleton especially when it's combined with other patterns such as bridge or strategy it can give you all the flexibility in the world and doesn't affect testing or any other type of pluggable behavior. Completely loosely coupled!

  • "To decide whether a class is truly a singleton, you must ask yourself some questions: (1) Will every application use this class exactly the same way? (exactly is the key word) (2) Will every application ever need only one instance of this class? (ever and one are the key words) (3) Should the clients of this class be unaware of the application they are part of?"

    I don't agree with the rules set above although they might be very helpful in situations where there is going to be only one instance of the singleton but as Gamma mentions in his book a singleton might be polymorphic (therefore question 1 is not really the case if you need a polymorphic singleton), a singleton might be designed because we need a controlled number of objects (therefore question 2 is not true) and I don't understand question 3! J

This item is from http://www.sitepoint.com/forums/showthread.php?t=386447

  • "It's hard coupling. Singletons are essentially static functions - the difference is syntactical sugar. Whenever you reference a static symbol in your code, you make it more dependent on the context. It's really the same as with a global variable - A global variable is bad because it has a global scope. A static function is also global in scope, so it has the same problems associated. The difference between the two, which accounts for the assumption that singletons are slightly better than global variables, is that functions are more abstract than variables, and this gives you some flexibility. This flexibility can then be used to excersise some damage control. Still it can't beat narrowing the scope, which is what objects provides."

    Hard coupling!! First time I heard that (I think he meant tight coupling). Anyhow this description is very good, and especially relevant to misuse of the pattern. If you use a singleton as an excuse to be lazy and not think about your design, if you use a singleton as an excuse to make everything global then yes there is no difference between a singleton and static members BUT if you use the singleton where it's supposed to be used it will be a whole lot more than "syntactical sugar." Plus we are forgetting that part of using a pattern isn't just because it's implemented with for example a static member or it isn't, but it's the whole knowledge that comes packed up with a pattern and is transferred to the next person (read this post). The above comparison is like saying using functions & procedures is "syntactical sugar" to using a goto statement because they are eventually a jump to a piece of code and a jump back! But that's not the case, functions and procedures provide a higher level of abstraction, so do classes, interfaces etc. which provide an even higher level of abstraction. Patterns are pretty much the same thing they too provide a higher level of abstraction albeit being implemented using mundane "static" members or similar constructs of a lower level of abstraction.

Items from http://home.earthlink.net/~huston2/dp/singleton.html

  • "It's relatively easy to protect Singleton against multiple instantiations because there is good language support in this area. The most complicated problem is managing a Singleton's lifetime, especially its destruction ... There are serious threading issues surrounding the pattern."

    Who says we don't want multiple instantiation of a singleton? There are cases that we need multiple instantiation (but controlled number of instances). I totally agree that in C++ and other languages that don't have garbage collection managing the lifetime of a Singleton or a lot of other patterns could be hard but not impossible. Yes threading could also be a serious problem to consider, but with singletons there are usually two scenarios that occur: you either have a singleton instance per thread then you have a multi-instanced singleton which returns an instance based on the calling active thread or you have on instance of the singleton replying to all threads which means the class must be thread-aware.

  • "The Singleton design pattern is one of the most inappropriately used patterns. Singletons are intended to be used when a class must have exactly one instance, no more, no less ... frequently use Singletons in a misguided attempt to replace global variables ... A Singleton is, for intents and purposes, a global variable. The Singleton does not do away with the global; it merely renames it."

    One instance and no more? I don't agree and if you read Gamma's book you'll see that it's not what he intended when he created the pattern. I agree that singleton is usually misused and it is not supposed to fix global variable problems (i.e. common coupling) but the advantages it provides as opposed to using a global variable are tremendous. Read my post on this issue here & here.

    "When is Singleton unnecessary? Short answer: most of the time. Long answer: when it's simpler to pass an object resource as a reference to the objects that need it, rather than letting objects access the resource globally ... The real problem with Singletons is that they give you such a good excuse not to think carefully about the appropriate visibility of an object. Finding the right balance of exposure and protection for an object is critical for maintaining flexibility."

    I agree completely! Very well said.

  • "Our group had a bad habit of using global data, so I did a study group on Singleton. The next thing I know Singletons appeared everywhere and none of the problems related to global data went away. The answer to the global data question is not, "Make it a Singleton." The answer is, "Why in the hell are you using global data?" Changing the name doesn't change the problem. In fact, it may make it worse because it gives you the opportunity to say, "Well I'm not doing that, I'm doing this" – even though this and that are the same thing."

    Very well said.

Wednesday, May 23, 2007

The much debated Singleton

After creating my post about the Singleton pattern I noticed a lot of hype around this pattern and its use (or misuse) over the internet. I also found some very interesting and sometimes amusing posts/comments on the matter (which I've included at the end of this post). Interestingly there was a lot of negative content about this pattern and the side effects that it has on your design. Intrigued by all of this information I decided to write my version of why & when you should use the Singleton pattern and also try to answer a lot of misconceptions that I read about during the past two weeks. So here goes:

The original thought behind the conception of the singleton pattern is to provide an object oriented approach to alleviate the pain of common coupling (global data) and provide a different strategy when dealing with global data. Also the pattern was intended as a solution when you absolutely needed to limit the number of objects of a certain type (class). Note that the singleton pattern will not totally remove common coupling from your design and to solve the problem completely, in most cases, requires the designer to completely re-think their design. Let's understand common coupling and it's evils before we delve any deeper:

Common coupling is a situation where function/component/class/module A & B are dependent on one another (coupled together) through the existence of some sort of external (and shared) data area between them in which one can change the content and the other will read from it (or both will read and change). Now the two coupled entities might be calling each other or might not be using one another directly at all. It doesn't matter; they are coupled to each other due to their shared use of the common data area. The perfect example being global data shared between multiple functions/components/classes/modules etc. (just for the sake of brevity I'm going to refer to all these different sections of code that coupling might relate to as components from now on).

Why is common coupling or global data bad? Well let's start by answering this question: why do we want loose coupling between our components (as opposed to tight coupling)?

  • When multiple components are tightly coupled we lose the chance for component reuse: If we want to reuse component A we must also take component B for the ride, because component B changes the global data and if the global data doesn't contain a certain state we will not be able to get the functionality we need from component A.
  • Due to tightly coupled components we increase our cost of maintenance and tests. When something changes instead of only needing a replacement of component A's implementation (which relates to the global area), since other components are tightly coupled to it we need to change them as well. Once we change component A and test it we must also test the other components tightly coupled with it.
  • When there is too much coupling we reduce the probability of independent design, coding & testing therefore creating a tougher environment as far as technical & project management is concerned.
  • Too many tightly coupled components mean a bigger thing to understand: more complexity.

As we can see common coupling (which is a level of tight coupling) can become a major reuse hindering factor, especially in cases where future change and evolution of the system is expected. How many times have we all designed something using global data only to find out in later versions that the data that we assumed (wrongly assumed!) to only have one running instance in the system needed to actually have multiple running instances. For example suppose we were to design a word processor similar to WordPad that ships with Windows. One of the immediate design decisions that come to mind when designing this word processor is to keep the current document information in a global variable where all the different routines of our program can access it and so we don't have to pass it around (common coupling). Making this design decision will cause many problems down the road but let's just examine two:

  • Components that we design (i.e. the spell checker) all depend on the existence of a globally available document to do their work and their reuse is hindered by this fact when we need to make use of them in a different project. As an example suppose we need a spell checker to check product information before it was saved to the database. If I had had the foresight to design my spell checker as an independent component that accepts what it's supposed to check as input (a rather abstract form of input but never the less an input not a global data area) and performed the checks on the input (as opposed to a global data area), I wouldn't have had this problem when the time came for its reuse.
  • If in the future the stakeholders decide that we are going to change our SDI (single document interface) word processor into a fully fledged MDI (multiple document interface) application where the user can open and work on multiple documents simultaneously we are going to be in trouble. Again we would need to rethink our single point of access because now we have multiple documents being loaded and it no longer makes sense to have one single document in memory where everyone will access and use.

Having said all this, one can't deny the fact that using global data in some cases is absolutely essential. But the scenarios where use of global data as a design decision is correct and invaluable are rare and will only occur once or twice in a moderately sized program. So the big problem is detecting when you are to allow a global shared piece of data and when not to. Chances are that in most cases you shouldn't allow it and we'll try to figure out when to do this and when not to, but before we get into that let's get back to the singleton pattern.

Based on the discussion so far the singleton pattern is useful when their exists enough reasons to share something as global data in your program, at that point instead of sharing it as global data (or a static member variable of a class) you should expose it as a singleton. This way you have more of a control over how that piece of global data will be accessed and used and in the future you can maintain it a lot easier (since singletons are regular objects instantiated from classes) by using OO techniques and other design patterns. You can also make sure that only one instance of that global object exists and no one (on purpose or through a mistake) can create a second instance which could have dire consequences (depending on your object's role in the system).

OK now we can go back to the definition of the singleton pattern and figure out when to use it:

The singleton design pattern is used in places where you want to ensure that only a single (or a controlled number) of instances of a specific class exist. The client code using the object shouldn't be allowed to create new instances (since it doesn't make sense to create new instances) and all of the different areas of client codes should access that single object through a well defined access point.

As can be seen nowhere in the definition of the singleton pattern (in any documentation about the pattern) is there a reference to use a singleton whenever you feel like using global data! Or use a singleton whenever you're lazy and don't feel like thinking about your design so you just expose some object as a global object and let everyone in all the different layers of your software access it through the single point of access. Or any other similar excuse for singleton's (mis)use. In order to use a Singleton correctly one cannot break other design rules (such as Common Coupling) a singleton does not justify having common coupling in your design!

So where can we use a singleton? Well there are situations where hardware or some other fact from the domain or a non-functional (technical) requirement dictates the use of the singleton pattern. A perfect example is the polymorphic singleton that I've used in the Abstract Factory example so that we have one single point of access to our abstract factory and that single point is configured with one of its subclasses. The technical requirements of that design imply that throughout the execution of the software the singleton will only contain one object that never changes. Other such examples would be when you are managing one piece of hardware (i.e. a modem, printer, etc.) and even in this case it is always wise to think about the consequences of your design decisions if we end up supporting more than one of those hardware pieces (i.e. two modems at the same time). But even for places where we have a controlled number of hardware (multiple modems) we can use the multi-instance singleton (please read my post on the singleton pattern) to fix this problem.

Another perfect use of the singleton pattern is to make sure that from a specific class we only get one object per thread. An example is the Connection Manager (which in some cases we might need more than one per thread but for the time being we'll assume one per thread will do) in this case the singleton pattern is there to make sure that nobody creates an extra copy of the ConnectionManager and cause problems in the way we communicate with the DB but the singleton itself might have multiple instances (actually one for every active thread that is running) so code in each thread will get a different ConnectionManager object hence making sure that one thread wouldn't use another thread's database connection.

There are a lot of perfectly legitimate reasons to use a singleton and I've only touched on a couple of them here but to round things up I believe the following list will help make an informed decision. As with any engineering design decision you as the designer have to consider the tradeoffs and you will ultimately decide if the singleton will help you out in a specific scenario but you should also take care not to misuse it since its negative effects on your design (especially form a reuse point of view) can be disastrous:

  1. Is the candidate object a truly single object from a problem domain point of view? Will it always be that way (considering future growth of the software)? If yes by all means implement it as a singleton.
  2. Will the candidate object becoming a singleton cause the common coupling problem (as described above)? If so be very careful you might be better off not implementing this as a singleton. If it doesn't create a common coupling problem (as is the case with many technical requirements which point us to a singleton and won't create a common coupling problem) then a singleton would be a lot better than a global variable (or a static member variable).
  3. Is the data stored in the singleton object being used from multiple locations in your software and a change from one location will be picked up in another location? If this is the case go back and think really seriously about item #2 in this list, since it looks like your causing a common coupling problem. If it's not a common coupling problem but the question still holds true then ask yourself are the multiple locations that are going to be accessing this singleton located in different layers of the software possible deployed in different processes or across machine boundaries? Will they ever be deployed like that? A nice example of this is current user information. Suppose we are building a multi-layered distributed windows application. The UI layer authenticates the user and puts the current user credentials in a singleton object hoping that one of the back end layers (for example the DAL) will be able to pick it up and use it. In this case your code will work when you're testing it and everything is running in-process but will immediately break once you deploy it to the live environment where the UI resides on client machines and the DAL resides on a server. Why? Because singletons don't automatically get marshaled across process/machine boundaries. Actually that's the case for any global (static) variable and you would have to come up with some solution to get them across. In this kind of a scenario a singleton might work but you need extra effort and code to make sure the data it's holding gets marshaled across to the other process/machine.
  4. Does the problem domain consider a class to only have one instance, for simplicities sake or is that an immutable fact in the domain? For example suppose we're developing a financial accounting system and in this system we decide to create a singleton called OwnerCorporation: The OwnerCorporation is considered a singleton since the financial accounting system will be sold to one corporation and they will use it to keep a record of their financial records. But this decision (having only one OwnerCorporation object) has been made for simplicities sake it's really not true in the real world and the moment this app has to support other different scenarios in the real world this design decision will cause it to break. For example suppose down the line we decide to sell the app to an accounting firm where it will be used to track the financial accounts of multiple corporations hence needing multiple instances of the OwnerCorporation class. Or in the future we decide to sell our financial accounting services online and the same back-end routines need to be used to support multiple owner corporations each accessing the site to manipulate their specific information, again implementing the OwnerCorporation as a singleton will cause headaches in this scenario.

In general you should pay attention to the fact that some object might seem like a singleton from a certain view point but from a different viewpoint it's not a singleton at all (as in item #4 above). This is the case with many other design decisions that we have to make and the cost/time needed to design a perfect scenario that will fit all possible viewpoints is usually so prohibiting that most designers don't really bother. The same case is true for the singleton pattern BUT the issue that should be stressed time and again is that the singleton is not a valid replacement for good (or decent) design or we shouldn't use the singleton as an excuse to create global data shared by everyone and therefore creating common coupling in our system.

I know I promised to review some posts & comments that I found on the internet here but this post is very long as it is so I'll work on it in the next post.

Wednesday, May 2, 2007

Design Patterns Pros & Cons

Well I guess the Gang of Four (GoF) design patterns (or Gamma's design patterns as many like to call it) are probably the most renown set of patterns available (and used) in software engineering (if you want a good explanation of what a design pattern is please refer to http://en.wikipedia.org/wiki/Design_pattern_(computer_science), to the book Design Patterns: Elements of Reusable Object-Oriented Software by Gamma et al or do a search for 'design patterns' you can't miss it!J). We've all read many articles or heard a lot of stuff in regards to the pros & cons of using design patterns, and although anyone who knows me professionally would agree that I'm a pro-design pattern kind of person, I do believe that the issues raised against design patterns are extremely interesting and enlightening.

A lot of articles I've read that try to undermine design patterns usefulness, although they are a bit unfair, do have some valid points. One of these points that I found very interesting was the fact that many believe that design patterns are taking us back to a pre-reuse era where everything had to be re-coded. The argument looks valid when you look at design patterns from a distance: design patterns are ultimately providing you a solution and a couple of examples, you have to understand (or misunderstandJ) the solution and using the examples as help try to implement it, and solve your own problem.

On closer examination, especially if you have used design patterns in real life, you realize that design patterns are supposed to provide you with a different type of reuse. A type of reuse that I would like to call "concept reuse" or "idea reuse." Design patterns try to provide a structured way of thinking and organizing a solution so that people with less experience with that domain or problem can soak up the experience of the more adept designer/developer and hopefully save a whole lot of time, agony and trial & error in the process. That being said we can't ignore the fact that design patterns in their purest form will not give you a ".dll" or ".class" or any other similar re-usable binary code that you can plug into your program and start using it. But the point behind design patterns is that if they did provide that kind of plugable/reusable solution we would have not had the whole idea/concept type of reuse. Let's delve into this a bit further:

Software reuse has been a major driving force behind a lot of innovations in the industry. From the very early days of software development reusing a piece of code has been the "second priority" of many projects (hopefully the "main priority" has been delivering to customer requirements). So why shouldn't design patterns be a step forward in the same evolutionary process? As I mentioned above I believe design patterns are another form of reuse which is different from binary code or source code reuse. Yes we can develop a series of components, frameworks and even code generators to ease the implementation process of design patterns [see http://se.ethz.ch/~meyer/publications/computer/visitor.pdf] but that still will not fill in the function of design patterns. At a higher level than components, binary code, etc. etc. there exist concepts and ideas and solutions in which if we have a uniform way of describing them we can communicate faster and more efficiently in a team. When we use design patterns we can document & evaluate an implementation a lot easier than actually describing everything in detail. We can compare and discuss two competing designs based on the merits of each one and finally pick a good "design pattern" to shape our solution. Design Patterns are a method to encapsulate "expertise."

I would like to add that for design patterns to be really helpful as "expertise encapsulations" your team members should all be intimately familiar with them and this sometimes can be a big downside to extensively using them in a project. Obviously if some members of your team are design pattern experts and the rest of them think design patterns pertain to fashion than you basically have two groups in your team each trying to talk in completely different languages and well we all know what happens next.

I would also like to add that sometimes extensive use of design patterns is overkill. Some problems, especially if the requirements and future change is very predictable and stable, can be solved very easily without employing design patterns. It's also fair to say that once a developer/designer is fluent in the use of design patterns he/she can incorporate them into a solution as easily as using any other design construct. But this doesn't mean that the next guy who comes along and is going to maintain that project or make some changes to it has the same intimacy with design patterns as the first designer therefore we have another overkill. To sum up, design patterns should be used wisely and where needed and like any other tool that we have at our disposal if you try to fix everything using design patterns you're going to end up in a big mess.

So the next post I'll do on design patterns would be a fresh look at probably the most famous design pattern of all time (and probably the simplest): Singleton. Now I know it sounds kind of cheesy to be writing about the same thing as everyone else has already done a million times but I believe that I have some very interesting experiences and fresh ideas regarding this very simple (and useful) pattern to share with everyone. Plus it will give everyone an idea on the level of detail I'm going to get into once I start writing about the other GoF design patterns.