Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

new class instance vs Singleton class vs static method

I am struggling to choose the perfect design pattern for this scenario :

When I click on the Browse button on my swing UI, a specified URL must be opened up on the web browser. This functionality is achieved inside this utility class which looks like this :

//inside action Listener of the browse button I call the openURL method of the below class

class webBrowserUtility(){
    void openURL(String url){
    ........
    }
}

Design Pattern Methods

Approach 1) I can go ahead and create new instance of the above class and invoke openURL().

Approach 2) Singleton : Make the WebbrowserUtility class a singleton and retain a static instance of that class in memory to be able to call the method whenever needed.

Approach 3) static method : Make the openURL() method static and call WebbrowserUtility.openURL(url) as needed.

In my first approach, I am worried that it might be inefficient as, every click on the browse button will create a new instance of the WebBrowserUtility class. I am confused between which approach to adapt between choice 2) and 3). Can you please help me choose the best among these three design patterns for this scenario? Or is there a better design pattern that can be adapted for the same?

like image 300
Vamsi Emani Avatar asked Dec 16 '22 10:12

Vamsi Emani


2 Answers

There's no ultimately right answer to your question. And no need to look for the one. Actually what one should understand while designing architecture for some piece of software is: when you don't know what's right -- just use an abstraction. Then if you will eventually understand that your initial implementation wasn't right, you will just replace it with another one and don't have to change public interface.

I mean in your case it is not obvious: from one side you should go with a singleton instance so no need to instantiate many instances, consume more memory and introduce additional overhead on object creation. However from the other side you can't be sure your project requirements won't change -- maybe you will have to add some state to your WebBrowserUtility service and make a number of calls in parallel keeping different states for different consumers, or you might even want to implement instance pooling for your class. You can't predict the future, that's why you should use abstraction.

The simplest way to abstract your object instantiation is to use a static factory method and call it like getInstance() -- just like if you're about to implement a singleton, though don't think about it only in terms of singleton implementation -- this is rather just an abstraction of how to instantiate it. For now you can stick with singleton, so this method will always return the only instance of the service, though in the future, if you would need to alter the way of class creation you will just change getInstance() implementation without need to change any code that actually uses your service. So you won't have to decide right now which way is better until you have enough information to choose.

So instantiating your services with factory methods gives you more flexibility, however there are even better ways. If you continue developing this idea about instantiation abstraction you will understand that usually you'd like to move the creation code out from the actual service into a dedicated factory class because sometimes you want to instantiate the same service in different ways for different means. Further development of this idea ends up using Inversion of Control pattern which is the ultimate answer on how to create instances of your services and manage dependencies among them.

If you're using Java, take a look at the very popular Spring framework that allows you to define the rules of services creation in a configuration file, so if you need a prototype instead of singleton it's only a matter of changing that config file.

I would also discourage of implementing your service class as just a number of static methods with required logic. The reason behind that -- it could be simple and fast to implement it right now, however in the future you're hands will be tied up with the interface that defines static methods. So if you would eventually need to use multiple instances, you will have to change the consumers code that uses your static methods as well, because the static signatures are in your interface rather than just in your implementation. In contrast deciding between prototype/singleton is hidden into the instantiation code, so consumers don't care how the instance is created -- they just ask for an instance and get it.

like image 149
coffeesnake Avatar answered Jan 20 '23 02:01

coffeesnake


Firstly, I recommend that you not overly worry about the possibility of a performance/efficiency issue at this stage unless you have some concrete reason to believe it will be a problem. Wait and see if it actually is a problem, and then address it accordingly. But you might well find that there's nothing to worry about.

So, the question is, does your WebBrowserUtility use any non-static member variables (i.e. instance data) of your class?

  • If it does, then you've got to go with approach 1. and create a new instance every time.

  • If it does not, then I'd be inclined to go with a static method and make the WebBrowserUtility a static class rather than implement a singleton. You don't really need there to be only one instance, which is what the singleton pattern is for. And the static method on a static class solution gives you the easy accessibility you need. The downside is that if you're writing unit tests for this, properly unit testing a static method is problematic.

like image 27
razlebe Avatar answered Jan 20 '23 01:01

razlebe