Как реализовать синглтон со стратегиями?

1

Я адаптирую Image Downloader из блога Google Android. Я хочу, чтобы ImageDownloader был singleton, так как я буду использовать его в нескольких местах в своем приложении. Я также хочу иметь возможность манипулировать Bitmaps с помощью разных Strategies (например, создавать прозрачные растровые изображения).

Context:

Я хочу иметь возможность использовать ImageDownloader в одном действии и устанавливать прозрачные растровые изображения, а в другом использовать тот же ImageDownloader, но получать черно-белые растровые изображения с использованием другого объекта стратегии.

Теги:
design-patterns
singleton
strategy-pattern

4 ответа

3
Лучший ответ

Вы думаете, что делаете, но вы не хотите, чтобы ImageDownloader был Singleton. Синглтон очень сильно злоупотребляют и не подходят в вашем случае. Подумайте об этом: как вы можете манипулировать растровыми изображениями с использованием разных стратегий, если есть только один экземпляр класса, выполняющего манипуляции?

То, что вы хотите, это возможность создавать экземпляры ImageDownloader с помощью статических методов, которые вы можете сделать, не делая его Singleton. Эти методы называются Factory методами, и есть много хороших веб-страниц, описывающих их.

Вероятно, вы хотите что-то вроде:

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

Каждый вызов метода с тем же аргументом может возвращать тот же экземпляр ImageDownloader, если экземпляры не сохраняют состояние. Некоторые версии этого подхода называются "Multiton". Google расскажет вам больше.

  • 1
    Хотя я согласен, что он на самом деле не хочет Singleton, комбинация внедрения зависимостей и фабрик для классов, которым нужен ImageDownloader была бы лучше, чем статические фабрик.
  • 0
    Это может быть правдой. Я решил сделать это простым. Не стесняйтесь писать более сложный ответ.
Показать ещё 1 комментарий
1

Я больше склонен согласиться с ответом DJClayworth, но чтобы ответить на ваш вопрос, лучший способ реализовать одноэлементный шаблон - использовать перечисление:

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
    }
}

Чтобы удержать экземпляр:

ImageDownloaderWrapper.INSTANCE.IMAGE_DOWNLOADER.download(...

Вы также можете воспользоваться статическим импортом:

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

Тогда это немного проще:

INSTANCE.IMAGE_DOWNLOADER.download(...

Чтобы учесть разные стратегии, я думаю, вам придется расширить ImageDownloader и добавить соответствующую логику для решения стратегий в этом подклассе (тип IMAGE_DOWNLOADER также должен соответствовать создаваемому подклассу).

0

Если вы хотите иметь сложное представление о шаблоне Singleton и как оно может быть реализовано, обратитесь к этой статье

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

Привет,

0

Вы можете передать стратегию как параметр методам, ответственным за загрузку/манипулирование изображениями.

Затем пройденная стратегия будет обрабатывать манипуляции. Это довольно уродливый хак. См. Ответ DJClayworth для более простых идей кода.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню