Извлечение и обобщение «повторяющихся» методов с аналогичной функциональностью

Предположим, у нас есть класс со многими методами, которые делают что-то другое, но могут быть сгруппированы вместе как одна «разновидность функциональности». Например, добавление правил настройки o.

Давайте рассмотрим пример правил. Скажем, у нас есть класс, который моделирует настольную игру, и мы добавляем разные правила, поэтому, когда игра воспроизводится, гарантируются правила:

public class Game {
    private RuleManager ruleManager;
    // etc...

    public Game() {
        ruleManager = new RuleManager(this);
        setupGameRules();
        // etc...
    }

    private setupGameRules() {
        if (players.size() == 1)
            setupSinglePlayerRule();
        else
            setupMultiplePlayerRule();

        setupNumberOfTurnsRule();

        setupScoreRule();
    }

    private void setupSinglePlayerRule() { /*...*/ }
    private void setupMultiplePlayerRule() { /*...*/ }
    private void setupNumberOfTurnsRule() { /*...*/ }
    private void setupScoreRule() { /*...*/ }
}

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

Я хотел бы извлечь все эти методы setupXRule() как-то в единицу, с точки зрения дизайна. Причины:

  • Делает код более понятным
  • Правила игры не фиксированы и «жестко закодированы» в игровом классе
  • Дополнительные правила могут быть добавлены. Вот что я имел в виду с обобщением. Я хотел бы, чтобы любой другой программист использовал этот класс, чтобы определить свои собственные правила и установить их в игре.

Каким будет лучший подход?

Обновление: Я думал об этом дизайне:

public abstract class GameRule {
    protected Game game;
    protected RulesManager rulesManager;
    protected Rule[] rules;

    public GameRule(Game g) {
        game = g;
        rulesManager = g.getRulesManager();
    }

    // Sets up the rule
    protected abstract void build();

    // Posts the rule to the game, so when it's played the rule is enforced
    public void post() {
        if (rules == null)
            throw new IllegalStateException("The rules have not beein initialized yet.");

        rulesManager.post(rules);
    }
}

И тогда у нас есть разные правила:

public class SinglePlayerRule extends GameRule {

    public SinglePlayerRule(Game g) {
        super(g);
        build();
    }

    protected void build() {
        // sets up the rule using the rule manager internal operation to handle and manage rules
    }
}
7 голосов | спросил dabadaba 21 PMpThu, 21 Apr 2016 17:31:34 +030031Thursday 2016, 17:31:34

1 ответ


0

Вам нужна коллекция, которая представляет все известные правила настройки. Например, главный массив или список интерфейсов (как предлагает @StevieV).

Я бы включил каждую возможность установки в свой собственный класс, чтобы я мог назвать все методы просто setup(). Каждый класс будет либо наследовать от общего базового класса, либо реализовать интерфейс (или оба). Базовый класс и /или интерфейс будут иметь метод setup().

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

Затем вам нужно использовать применимые правила для любой конкретной ситуации. Итак, я бы превратил ситуацию в объект первого класса.

Таким образом, интерфейс правила может включать метод boolean isApplicable(Situation situation), который вы использовали для составления соответствующего набора для данной ситуации.

Каждое правило будет иметь свой собственный способ определить, применимо ли оно, например, если один игрок, если многопроцессор и т. д. Таким образом, интерфейс будет иметь два метода: isApplicable(situation) и setup(). (Альтернативно, вы могли бы просто setup(situation), который просто ничего не делал, когда это не применимо.)

Предположительно, setup() сделает то, что необходимо, однако вы также можете создать дополнительный список для любой ситуации, если хотите .

Как поясняет @RobertHarey, это можно сделать, используя лямбда, а главная коллекция - список лямбда или лямбда-пар для двух методов.

ответил Erik Eidt 21 PMpThu, 21 Apr 2016 20:16:14 +030016Thursday 2016, 20:16:14

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132