Сочетание фабричного метода и шаблонов синглтона - PullRequest
0 голосов
/ 16 мая 2018

Я сейчас реализую игру, в которой есть разные типы карт. Будучи всеми картами, они, естественно, имеют общие атрибуты и методы, поэтому был создан абстрактный класс Map, который затем был разделен на подклассы такими картами, как SafeMap, HazardousMap, WeirdMap и т. Д.

Чтобы упростить добавление новых карт в будущем, использовался шаблон проектирования заводских методов. Таким образом, программа содержит класс MapCreator, код которого выглядит примерно так:

public class MapCreator{
    public Map createMap(char mapType){
        switch(mapType){
            case 'S':
                return new SafeMap();
            case 'H':
                return new HazardousMap();
            case 'W':
                return new WeirdMap();
            default:
                return null;
        }
    }
}

Теперь я также хотел бы убедиться, что существует только один экземпляр Map (независимо от выбранного подкласса). Я читал, что лучший способ сделать это - развернуть шаблон проектирования синглтона, где статический экземпляр объявляется конфиденциально внутри класса, а конструктор также становится закрытым. Но я не знаю, как это можно сделать в сочетании с шаблоном разработки метода фабрики, поскольку у нас есть несколько подклассов, и getInstance() должен находиться в конкретном классе.

Я ценю любую помощь.


Примечание: я посмотрел на несколько похожих вопросов , но я не думаю, что ответы на них имеют отношение к моему делу.

Ответы [ 2 ]

0 голосов
/ 16 мая 2018

Шаблон ServiceLocator - это то, что вы ищете.

Вообще говоря, чтобы избежать необходимости использовать Singletons повсеместно, вы склонны использовать этот шаблон, который затем можно при необходимости смоделировать для юнит-тестов.

Он состоит из карты, в которой в качестве ключа используется класс интерфейса, а в качестве значения - объект (он может содержать много классов / интерфейсов Singleton).

Таким образом, вы можете получить ServiceLocator сhashmap, имеющий запись с Map.class в качестве ключа и желаемый экземпляр в качестве значения.

Вы получите значение (например):

ServiceLocator.get(Map.class);

Где get - универсальный метод получения, которыйоборачивает yourHashMap.get (Map.class);

0 голосов
/ 16 мая 2018

Самый простой способ сделать это - использовать одно статическое поле и вернуть это значение, если карта уже создана.

Код не проверен, но я думаю, что концепция достаточно проста:

public class MapCreator{
    private static Map theOnlyMap;
    public synchronized Map createMap(char mapType){
        if( theOnlyMap != null ) return theOnlyMap;
        switch(mapType){
            case 'S':
                theOnlyMap = new SafeMap();
            case 'H':
                theOnlyMap =  new HazardousMap();
            case 'W':
                theOnlyMap = new WeirdMap();
        }
        return theOnlyMap;
    }
}
...