Шаблонный шаблон для статических классов

У меня есть класс утилит, которые выполняют некоторую работу. Очевидно, что он закрыт для расширения и все методы являются статическими. Для простоты класс выглядит так:

public final class Util {
    private Util() { }

    public static void doWork() {
        // some work
        int variable = help();
        // some work uses variable
    }

    private static int help() {
        // some helper functionality
    }
}

У класса есть метод doWork который выполняет много расчетов. Кстати, метод вызывает вспомогательный метод help чтобы получить некоторый результат, а остальную часть кода используйте результат, возвращаемый help метод.

Теперь в клиентском коде я хочу повторно использовать функциональность метода doWorkно вместо звонка help Я хочу позвонить help2 метод. Самое простое решение - просто создать метод doWork2 с заменой help в help2,

Это очень плохой подход, потому что каждое изменение в doWork должен быть воспроизведен в doWork2 или. Это очень похоже на Template Method шаблон, но из-за того, что у нас нет здесь расширения, мы не можем его применить.

Лучшее решение, которое я придумал, чтобы добавить параметр к этому методу, но сохранить всех существующих пользователей doWork:

public static void doWork() {
    doWorkWithParameter(true);
}

public static void doWorkWithParameter(boolean helpOrHelp2) {
    // some work
    int variable = helpOrHelp2 ? help() : help2();
    // some work uses variable
}

Какие лучшие дизайнерские решения могут быть применены для решения этой проблемы? Есть ли способ добиться гибкости, как Template Pattern имеет, но в приложении к утилитам классов.

Заранее спасибо.

3 ответа

Решение

Мое предложение вдохновлено шаблоном Command, где класс Util является Invoker, а каждая пара doWork-help инкапсулирована с использованием интерфейса Worker.

Рабочий интерфейс может быть чем-то вроде

public interface Worker {
    public void doWork();
    public int help();
}

Утиль Класс

public final class Util {
    private Util() { }

    public static void toWork(Worker worker){
        worker.doWork();
    }

}

Бетонщик (реализации справки и doWork)

public class ConcreteWorker implements Worker{

    @Override
    public void doWork() {
        // TODO Auto-generated method stub
            int variable = help();

    }

    @Override
    public int help() {
        // TODO Auto-generated method stub
        return 0;
    }

}

Другой работник

public class ConcreteWorker2 implements Worker{

    @Override
    public void doWork() {
        // TODO Auto-generated method stub
            int variable = help();

    }

    @Override
    public int help() {
        // TODO Auto-generated method stub
        return 1;
    }

}

И казнь

Util.toWork(new ConcreteWorker());
Util.toWork(new ConcreteWorker2());

Не так давно я сделал это:

public static enum Helper{
    OLD(){
        public int help(){
            return 0;
        }
    },

    NEW(){
        public int help(){
            return 1;
        }
    };

    public abstract int help();

    public void doWork() {
        int variable = help();
    }
}

public static Helper HELPER = Helper.NEW;

тогда мы можем позвонить:

Constants.HELPER.doWork()

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

Helper.OLD.doWork();
Helper.NEW.doWork();

Вы можете создать 2 статических объекта Help1 & Help2 реализации Help интерфейс, который имеет метод help() и измените ваш метод doWorkWithParameter следующим образом:

public static void doWorkWithParameter(Help h) {
    int variable = h.help();
}

Это тесно связано с вашим текущим решением. Но я думаю, что это немного более "объектно-ориентированный".

Другие вопросы по тегам