Click here to Skip to main content
Licence CPOL
First Posted 9 Dec 2011
Views 2,628
Bookmarked 11 times

Proxy pattern extending Open/Closed principle to avoid declaring singleton

By | 12 Dec 2011 | Article
Proxy pattern extending Open/Closed principle to avoid declaring singleton.

Introduction

One of the disadvantage of using the Singleton pattern is the consumer class gets knowledge of its existence. There is no harm in having this knowledge, but it simultaneously brings the issue of tight coupling. This article will help you get independent of the singleton syntax, maintaining behavior.

Background

This article is based on industry wide used Design Patterns like Singleton, Proxy and assumes that the reader is quite comfortable with them. The approach mentioned in this article will work in scenarios where a singleton class has public methods without any public properties.

It might work as a remedy to the problem discussed in this StackOverflow thread.

If you have a Singleton with public properties, you can give a miss to this approach.

Using the code

We all are comfortable with declaring a singleton in the following way (or something similar to this):

public class ServiceProvider
{
   private static ServiceProvider instance = new ServiceProvider();

   private ServiceProvider()
   {
   }
    
   public static Instance
   {
     get
     {
       return instance;
     }
   }
   
   public int Foo()
   {
     // Do operation.
   }   
}

public class Consumer1
{
   public void DoAction1()
   {
     int i1 = serviceProvider.Instance.Foo();
   }
}

This code will work fine in all seasons provided the system will not require to change the singleton behavior of ServiceProvider. But there will always be a change which would make us scrap the singleton behavior. Naturally we will then remove the singleton specific code from ServiceProvider and subsequently update the client side code.

This will need a lot of code change in the consumer side, violating the Open/Closed programming principle. E.g., declaring a local variable in the consumer if multiple methods are using the singleton functionality.

Replacing Singleton with Proxy

I have tried to solve this problem by bringing the Proxy pattern as a medium of communication between the consumer and the supposed to be Singleton service provider.

public interface ISystemService
{
   int Foo();
}

internal class InternalServiceProvider : ISystemService
{
   public int Foo()
   {
     // Do some operation.
     return 1;
   }
}
public class ServiceProvider : ISystemService
{
   private static ISystemService proxy = new InternalServiceProvider();
   public int Foo()
   {
      return proxy.Foo();
   }
}

public class Consumer1
{
   public void DoAction1()
   {
     ISystemService serviceProvider = new ServiceProvider();
     int i1 = serviceProvider.Foo();
   }
}

public class Consumer2
{
   public void DoAction2()
   {
     ISystemService serviceProvider = new ServiceProvider();
     int i1 = serviceProvider.Foo();
   }
}

If you check the code carefully, you will find the client side is oblivious to the singleton behavior of ServiceProvider. The client side will always be required to instantiate the object before using it. Thus for the client, it will always work like a normal class.

Tomorrow if we have to scrap the singleton behavior of ServiceProvider, we can easily achieve that by changing the code as:

  1. Converting the private static proxy property to private.
  2. Instantiating proxy in a non-static instance specific constructor.

Note that this change does not require any modification in the client side, allowing the client code to continue working the same way.

public class ServiceProvider : ISystemService
{
   private ISystemService proxy;

   public ServiceProvider()
   {
     proxy = new InternalServiceProvider();
   } 

   public int Foo()
   {
     return proxy.Foo();
   }   
}

How does it adhere to the Open/Closed principle?

Till now we have seen how we can switch on/off singleton behavior with minimal changes in code, but we haven't seen anything that makes it adhere to the Open/Closed principle, or does it already satisfy the Open/Closed principle requirements?

The answer is yes. We can change the behavior anytime by instantiating a different derived class of ISystemService in ServiceProvider, keeping the user oblivious to the change. Thus we also extend the advantages of the Open/Closed principle.

Points of interest

This article provides a way to become independent of Singleton syntax, continuing to use its behavior. This solution may not fit all scenarios, but will be helpful in scenarios where no static data perseverance is required.

We can, by merging the Proxy pattern with the Open/Closed principle, make the system independent of Singleton syntax.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

RakeshGunijan

Software Developer

India India

Member

Hi,
I am Bachelor of Engg(Computer) from Mumbai University.
I am right now working in Singapore.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralMy vote of 3 Pinmemberstooboo2:40 9 Dec '11  
GeneralRe: My vote of 3 [modified] PinmemberRakeshGunijan2:49 9 Dec '11  
GeneralRe: My vote of 3 Pinmemberstooboo3:02 9 Dec '11  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web02 | 2.5.120517.1 | Last Updated 13 Dec 2011
Article Copyright 2011 by RakeshGunijan
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid