Параметризованный паттерн стратегии - PullRequest
6 голосов
/ 18 апреля 2010

У меня есть несколько классов Java, которые реализуют шаблон стратегии. Каждый класс имеет переменные номера параметров разных типов:

interface Strategy {
     public data execute(data);
}

class StrategyA implements Strategy {
     public data execute(data);
}

class StrategyB implements Strategy {
      public StrategyB(int paramA, int paramB);
      public data execute(data);
}

class StrategyC implements Strategy {
      public StrategyC(int paramA, String paramB, double paramC);
      public data execute(data);
}

Теперь я хочу, чтобы пользователь мог вводить параметры в какой-то интерфейс. Пользовательский интерфейс должен быть выбран во время выполнения, то есть стратегии должны быть независимыми от него. Диалог параметров не должен быть монолитным, и должна быть возможность заставить его вести себя и выглядеть по-разному для каждой стратегии и пользовательского интерфейса (например, консоли или Swing).

Как бы вы решили эту проблему?

Ответы [ 4 ]

4 голосов
/ 18 апреля 2010

Одна из возможностей сделать это с чем-то похожим на шаблон проектирования Builder:

Для каждого типа стратегии у вас должен быть соответствующий строитель (один или несколько). Конструктор не работает как обычный конструктор, получая все параметры init в качестве аргументов метода; Вместо этого он должен блокировать , пока не будет получен соответствующий ввод. Некоторые сборщики отображают диалоговое окно Swing и ждут, другие выводят на консоль и ждут ввода, другие могут читать из файла и т. Д. После того, как сборщик получит все входные данные, он может создать экземпляр стратегии и вернуть его.

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

1 голос
/ 18 апреля 2010

Решение этой проблемы зависит главным образом от того, какая стратегия является текущей. Для простоты я предполагаю, что пользовательский интерфейс одинаков для всех стратегий.

Практически вы будете создавать класс конструктора или метод фабрики. Что-то вроде этого:

interface StrategyPicker {
    public Strategy getStrategy();
}

// Most likely used in the JFrame it is added to
class StrategyPickerUI extends JPanel implements StrategyPicker {
    // initialize the panel with all the widgets
    // and implement the getStrategy method. the getStrategy
    // method should be called after the input is done in this
    // panel (such as clicking an Ok or Apply button)
}

// You can also make one for the console app
class StrategyPickerSimple implements StrategyPicker {
    // ...
}

Если вы хотите быть по-настоящему модным, вы создаете простой фабричный класс, чтобы удалить акт создания в своем собственном классе:

public class StrategyFactory() {
    public static Strategy createStrategyFromParameters(StrategyParams sp) {
        // creates the Strategy object... doesn't need to be public static
        // and if it isn't, it will help making unit tests easier
    }

    // This nested class could be split up to StrategyAParams, 
    // StrategyBParams, StrategyCParams
    public class StrategyParams {
        data paramA; 
        int paramB_A;
        int paramB_B;
        int paramC_A;
        String paramC_B;
        float paramC_C;
    }
}

// in StrategyPickerUI class
    public getStrategy() {
        StrategyParams sp = new StrategyParams();
        sp.paramB_A = myJTextFieldParamB_A.getText();
           // and so on...
        return StrategyFactory.createStrategyFromParameters(sp);
    }

Если вы хотите, чтобы пользовательский интерфейс был не монолитным, то разделите обязанности на свои собственные объекты. Надеюсь, это поможет.

0 голосов
/ 16 апреля 2012

Я бы предложил сначала поискать «Параметризованный шаблон стратегии». Есть статья может быть именно то, что вы ищете http://www.hillside.net/plop/2010/papers/sobajic.pdf

0 голосов
/ 05 мая 2010

Если ваши классы параметров содержат простой объект (Numbers, Boolean, Date, String), вы можете попытаться сгенерировать ваш интерфейс во время выполнения.

Будет сложнее создать пользовательский интерфейс для составных объектов и набора параметров

Посмотрите на Метавиджет это мощный генератор пользовательского интерфейса.

...