Использование фабрики для создания стратегии - PullRequest
2 голосов
/ 25 марта 2012

У меня реализован следующий шаблон стратегии:

public abstract class RetrievalStrategy {
    public abstract List<MyObject> retrieve();
}

public class LimitRetrievalStrategy extends RetrievalStrategy {
    public int limit;
    public LimitRetrievalStrategy(int limit) {
        this.limit = limit;
    }
    public List<MyObject> retrieve() {
        // fill up the list and return it, limiting to 'limit' results
        return new ArrayList<MyObject>(limit);
    }
}

public class SpeedRetrievalStrategy extends RetrievalStrategy {
    public int speed;
    public SpeedRetrievalStrategy(int speed) {
        this.speed = speed;
    }
    public List<MyObject> retrieve() {
        // do something with the speed and return list again
        return new ArrayList<MyObject>();
    }
}

Мое клиентское приложение получает от пользователя либо скорость, либо ограничение (и, возможно, другие параметры).Я хочу создать фабричный класс, который будет возвращать правильную стратегию на основе параметров, которые имеют значение, и параметров, которые не имеют.Я не хочу, чтобы клиент решал, какую стратегию следует вернуть.Должен ли фабричный метод createStrategy(params) иметь операторы if для каждого параметра и в зависимости от различных комбинаций (представьте, что есть другие классы Стратегии) ​​возвращать класс Конкретной Стратегии?Как правильно это сделать?

Ответы [ 3 ]

4 голосов
/ 25 марта 2012

О, RetrievalStrategyFactory, с чего начать?Это звучит как переобучение для YAGNI .Один из подходов - создать перечисление для указания поля «set», предполагая, что для каждого параметра есть одна стратегия поиска, и использовать его в качестве фабрики.

public enum FieldParameter {
    LIMIT {
        RetrievalStrategy getRetrivalStrategy(int value) {
            return new LimitRetrievalStrategy(value);
        }
    },
    SPEED {
        RetrievalStrategy getRetrivalStrategy(int value) {
            return new SpeedRetrievalStrategy(value);
        }
    };

    abstract RetrievalStrategy getRetrivalStrategy(int value);
}

Тогда клиентский код явно не задает стратегию поиска,но это неявно дается, когда код клиента сообщает вашему коду, какое поле предоставил пользователь.

1 голос
/ 25 марта 2012

Если вам нужна возможность расширить фабрику, вам нужна абстрактная фабрика. Это фабрика фабрик. Абстрактная фабрика может иметь много фабрик плагинов, которые могут следовать стратегии, чтобы определить, какая фабрика используется.

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

1 голос
/ 25 марта 2012

Нет, возвращаемое значение в сигнатуре метода должно быть общим интерфейсом или базовым классом.

У фабрики должны быть тесты if, чтобы выбрать конкретный тип для возврата, но это неизбежно, если только вы не можете создать Map, которая возвращает конкретный экземпляр на основе класса составного ключа, который инкапсулирует комбинации параметров.

...