Click here to Skip to main content
Click here to Skip to main content

Proxy pattern extending Open/Closed principle to avoid declaring singleton

, 12 Dec 2011 CPOL
Rate this:
Please Sign up or sign in to vote.
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)

Share

About the Author

User-Rock
Software Developer
India India
No Biography provided

Comments and Discussions

 
GeneralMy vote of 3 Pinmemberstooboo9-Dec-11 3:40 
GeneralRe: My vote of 3 [modified] PinmemberRakeshGunijan9-Dec-11 3:49 
GeneralRe: My vote of 3 Pinmemberstooboo9-Dec-11 4:02 

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.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.141220.1 | Last Updated 13 Dec 2011
Article Copyright 2011 by User-Rock
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid