views:

104

answers:

5

I'm adapting Image Downloader from Google Android blog. I want ImageDownloader to be singleton since I'll be using it in multiple places in my application. I want also to be able to manipulate Bitmaps using different Strategies (eg. produce transparent bitmaps).

Context:

I want to be able to use ImageDownloader in one activity and set transparent bitmaps, and in another use the same ImageDownloader but get black&white bitmaps using different strategy object.

+3  A: 

You think you do, but you don't want ImageDownloader to be a Singleton. Singleton is very much overused, and not appropriate in your case. Think about it: how can you manipulate Bitmaps using different strategies if there is only one instance of the class doing the manipulating?

What you want is the ability to create instances of ImageDownloader via static methods, which you can do without making it a Singleton. These methods are called Factory methods, and there are many good web pages describing them.

You probably want something like:

class ImageDownloader {
  static ImageDownloader createImageDownloader(Strategy s) {...}
   //...
}

Each call to the method with the same argument could return the same instance of ImageDownloader, provided the instances don't store state. Some versions of this approach are referred to as "Multiton". Google will tell you more.

DJClayworth
While I agree that he doesn't *actually* want a Singleton, a combination of dependency injection and factories for the classes that need the `ImageDownloader` would be better than static factories.
kyoryu
That may be true. I decided to keep it simple. Feel free to write a more complex answer.
DJClayworth
@DJClayworth Yes indeed - instances don't store state. I've ended with Strategy passed in constructor, but converting it into static factory would fit my purpose.
pixel
A: 

You could pass a strategy as parameter to the methods responsible for the image downloading/manipulation.

Then the strategy passed will handle the manipulation. It's a fairly ugly hack though. See DJClayworth's answer for the more clean code ideas.

Jes
A: 

I'm more inclined to agree with DJClayworth answer, but to answer your question, the best way to implement the singleton pattern is to use an enum:

public enum ImageDownloaderWrapper
{
    INSTANCE;

    public static final ImageDownloader IMAGE_DOWNLOADER;

    private ImageDownloaderWrapper()
    {
        IMAGE_DOWNLOADER = new ImageDownloader();//this is where you would initialize it... looks like it has a default constructor
    }
}

To get a hold of the instance:

ImageDownloaderWrapper.INSTANCE.IMAGE_DOWNLOADER.download(...

You can also take advantage of static imports:

import static some.package.structure.ImageDownloaderWrapper.INSTANCE;

Then it's a bit simpler:

INSTANCE.IMAGE_DOWNLOADER.download(...

To account for different strategies I guess you'd have to extend ImageDownloader and add the appropriate logic for dealing with strategies in that subclass (the type of IMAGE_DOWNLOADER should also correspond to the subclass you created).

Andrey
+1  A: 

I recommend a implementing a factory pattern as follows:

public class ImageDownLoaderFactory {
    private static ImageDownLoaderFactory _instance;

    public static ImageDownLoaderFactory getInstance() {
        //...
        return _instance;       
    }

    public ImageDownLoader make(Stategy strategy) {
        ImageDownLoader downloader;
        //else if logic here to return the correct ImageDownLoader
        return downloader;      
    }
}

public interface ImageDownLoader {
    Object makeBitmap();
}
johnnieb
A: 

If you want to have compelte idea of Singleton pattern and how it can be implement, refer this article

http://www.codinguide.com/2010/04/singleton-pattern.html

Regards,

Interperator