Как абстрагироваться от создания одинаковых методов для каждого атрибута?

Допустим, я написал следующий класс:

public class Metrics {
        private static int metric1 = 0;

        public static int countMetric1() {
                metric1 += 1;
                return 0;
        }

        public static int resetMetric1() {
                int currentCount = metric1;
                metric1 = 0;
                return currentCount;
        }
}

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

public class Metrics {
        private static int metric1 = 0;
        private static int metric2 = 0;

        public static int countMetric1() {
                metric1 += 1;
                return 0;
        }

        public static int resetMetric1() {
                int currentCount = metric1;
                metric1 = 0;
                return currentCount;
        }

        public static int countMetric2() {
                metric2 += 1;
                return 0;
        }

        public static int resetMetric2() {
                int currentCount = metric2;
                metric2 = 0;
                return currentCount;
        }
}

Хорошо, хорошо ... но точно не СУХОЙ. Если я затем захочу добавить метрика3 или метрика4, мне придется снова скопировать и вставить много, и это вонючий. Есть ли способ в Java реорганизовать это, чтобы избежать повторения и сохранить «статичность» кода? (Из-за контекста кода вещи должен быть статичны)

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

Примечание 1: Это код пример. Так что не нужно возиться с именами переменных.

Заметка 2: Любое предложение о том, как улучшить заголовок вопроса, было бы неплохо. :)

Вы знаете, что такое вонючий? Имея атрибуты metric1, metric2, metric3, ... Похоже, это XY проблема. Какую проблему вы пытаетесь решить? Если вы не хотите писать геттеры и сеттеры, взгляните на проект ломбок (осторожно: проект lombok использует манипуляции с байтовым кодом).

Turing85 02.05.2018 20:00

Почему эти показатели должны быть статичными?

Compass 02.05.2018 20:01

Если вам не нужно отдельное поле для каждой метрики, почему бы не использовать карту (возможно, с ключом перечисления)? Тогда у вас будет один метод count и reset, который принимает дополнительный параметр перечисления.

crizzis 02.05.2018 20:01

Вместо того, чтобы пытаться сгруппировать все ваши метрики в один класс, как насчет класса с именем Counter (похоже, это то, что вам нужно), у которого есть счетчик, имя и некоторые общедоступные методы для увеличения / сброса? Вы можете создать n экземпляров класса и сохранить их в коллекции.

Nick DeFazio 02.05.2018 20:05

@ Turing85, не говоря уже о том, как неприятно иметь атрибуты статическийmetric1, metric2, metric3 ...

crizzis 02.05.2018 20:07

Отредактировал вопрос с учетом ваших комментариев: 1) Это пример кода, очевидно, что я не использую эти имена переменных в производстве. : P 2) Я получаю ваши жалобы на статические атрибуты и методы, но из-за контекста, в котором находится код, должен быть статичен.

LLCampos 03.05.2018 09:56
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
6
53
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проще всего создать класс Metric:

public class Metric {

    private int count = 0;
    private final String name;


    public Metric(final String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return String.format("Metric{name='%s', count=%d}", name, count);
    }

    public int count() {
        return ++count;
    }

    public void reset() {
        count = 0;
    }
}

В своем классе вы бы назвали это так:

private Metric someMetric = new Metric("Whatever you want to measure");

Поскольку вы, кажется, предпочитаете что-то со статическим доступом, как насчет простой карты?

public class Metrics {

    private static Map<String, Integer> metricsMap = new HashMap<>();

    public static int countMetric(String metric) {
        int newValue = metricsMap.compute(metric, 
                                          (s, value) -> value == null 
                                          ? 1 : value + 1);
        return newValue - 1 /* old value */;
    }

    public static void resetMetric(String metric){
        metricsMap.remove(metric);
    }
}

Хороший. Однако у него есть недостаток в том, что он теряет «статичность» кода. :) (вопрос уже редактировал, отражая этот факт)

LLCampos 03.05.2018 09:58

@LLCampos правда, но я не уверен, что считаю это недостатком.

Sean Patrick Floyd 03.05.2018 19:59

@LLCampos добавил более статичную альтернативу

Sean Patrick Floyd 03.05.2018 20:12

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