2010-08-17 5 views
1

J'adapte Image Downloader à partir du blog de Google Android. Je veux ImageDownloader être singleton puisque je l'utiliserai à plusieurs endroits dans mon application. Je veux également être en mesure de manipuler Bitmaps en utilisant différents Strategies (par exemple produire des bitmaps transparents).Comment mettre en œuvre singleton avec des stratégies?

Contexte:

Je veux être en mesure d'utiliser ImageDownloader dans une activité et mettre en bitmaps transparentes, et dans une autre utilisent le même ImageDownloader mais obtenir noir & bitmaps blanc en utilisant différents objets de stratégie.

Répondre

3

Vous pensez que oui, mais vous ne voulez pas que ImageDownloader soit un singleton. Singleton est très surutilisé, et pas approprié dans votre cas. Pensez-y: comment pouvez-vous manipuler Bitmaps en utilisant différentes stratégies s'il n'y a qu'une seule instance de la classe à manipuler? Ce que vous voulez, c'est la possibilité de créer des instances de ImageDownloader via des méthodes statiques, ce que vous pouvez faire sans en faire un Singleton. Ces méthodes sont appelées méthodes Factory, et il existe de nombreuses bonnes pages Web les décrivant.

Vous voulez probablement quelque chose comme:

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

Chaque appel à la méthode avec le même argument pourrait retourner la même instance de ImageDownloader, à condition que les instances ne stockent pas d'état. Certaines versions de cette approche sont appelées "Multiton". Google vous en dira plus.

+1

Même si je suis d'accord qu'il ne * fait * veulent un Singleton, une combinaison d'injection de dépendances et d'usines pour les classes qui ont besoin du 'ImageDownloader' serait mieux que des usines statiques. – kyoryu

+0

Cela peut être vrai. J'ai décidé de rester simple. N'hésitez pas à écrire une réponse plus complexe. – DJClayworth

+0

Oui en effet - les instances ne stockent pas d'état. J'ai fini avec la stratégie passée dans le constructeur, mais la convertir en usine statique correspondrait à mon but. – pixel

0

Vous pouvez transmettre une stratégie en tant que paramètre aux méthodes responsables du téléchargement/de la manipulation d'image. Ensuite, la stratégie adoptée traitera la manipulation. C'est un hack assez moche cependant. Voir la réponse de DJClayworth pour les idées de code plus propres.

1

Je suis plus enclin à se mettre d'accord avec la réponse DJClayworth, mais pour répondre à votre question, la meilleure façon de mettre en œuvre le modèle singleton est d'utiliser un 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 
    } 
} 

Pour obtenir une prise de l'instance:

ImageDownloaderWrapper.INSTANCE.IMAGE_DOWNLOADER.download(... 

Vous pouvez également tirer profit des importations statiques:

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

Ensuite, il est un peu plus simple:

INSTANCE.IMAGE_DOWNLOADER.download(... 

Pour tenir compte des stratégies différentes, je suppose que vous auriez à étendre ImageDownloader et ajouter la logique appropriée pour traiter des stratégies dans cette sous-classe (le type de IMAGE_DOWNLOADER doit également correspondre à la sous-classe vous avez créé).

Questions connexes