Проблемы проектирования использования абстрактного класса с интерфейсом - PullRequest
2 голосов
/ 16 марта 2019

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

Я разработал такое решение, которое реализует абстрактный интерфейс и интерфейс, и в конструкторе он вызывает defaultметод интерфейса для инициализации карты.

Вот мой интерфейс:

   public interface ICalculator{

        int VALUE_OF_X= 10;
        int VALUE_OF_Y= 50;
        int VALUE_OF_Z = 70;


        Map<String, Integer> CHAR_VAL_MAP = new HashMap<String, Integer>(7);

        default void initValueMap(){
            CHAR_VAL_MAP.put("X", VALUE_OF_X);
            CHAR_VAL_MAP.put("Y", VALUE_OF_Y);
            CHAR_VAL_MAP.put("Z", VALUE_OF_Z);
        }

        public int calculate(final String inStr);
}

И создал абстрактный класс:

 public abstract  class AbstractCalculator implements ICalculator{

    protected AbstractCalculator(){

        initValueMap();
    }
}

Моя идея была здесь, чтобы убедиться, чтоМетод initValueMap неявно вызывается абстрактным классом.

И конкретный класс, расширяющий абстрактный класс:

public class MyCalculator extends AbstractCalculator{

    public int calculate(final String romanNumberStr){
        // some logic code
    }
}

У меня в основном два вопроса:

1)Есть ли проблема дизайна или неправильное использование концепций ООП?2) В С ++.использование const для параметра - хорошее поведение при программировании.Но в Java-слове это не так часто.Разве плохо использовать final в параметрах метода?

Ответы [ 2 ]

3 голосов
/ 16 марта 2019

Вы слишком усложняете вещи.Java 9 добавила несколько приятных of () методов в служебный класс Collections.Вы можете использовать их для создания карты, заполненной значениями, без необходимости вызывать дополнительный метод init.Затем вы передаете этот экземпляр карты в new HashMap () , чтобы получить эти данные в изменяемый экземпляр карты.А в более старых версиях Java всегда можно написать метод, который создает , а возвращает предварительно заполненную карту.Нет необходимости делать создание и заполнение, как вы (в отдельных частях кода).

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

Что касается финала, у const есть несколько отличий от C ++.Единственное, что дает вам последний параметр - это проверка, которая предотвращает непреднамеренную запись в параметр.Это может быть полезно, но большинство людей просто не используют его, потому что они добавляют такой небольшой выигрыш, но делают код довольно трудным для чтения.

0 голосов
/ 16 марта 2019

Есть несколько способов гарантировать, что calculate вызывается только после полной инициализации карты.Один из способов - объявить и инициализировать его непосредственно в интерфейсе:

public interface ICalculator {

    int VALUE_OF_X = 10;
    int VALUE_OF_Y = 50;
    int VALUE_OF_Z = 70;

    Map<String, Integer> CHAR_VAL_MAP = initValueMap();

    static Map<String, Integer> initValueMap() {

        Map<String, Integer> map = new HashMap<String, Integer>(7);
        map.put("X", VALUE_OF_X);
        map.put("Y", VALUE_OF_Y);
        map.put("Z", VALUE_OF_Z);

        return map;
    }

    public int calculate(final String inStr);
}

Это может быть предпочтительнее, поскольку static данные инициализируются статически, где они объявляются (хотя большинству из нас это не особо нравитсясопрягать интерфейсы с таким кодом).

Если вы хотите вызвать этот код инициализации в абстрактном классе, вы все равно можете использовать блок static:

public abstract class AbstractCalculator implements ICalculator {
    static {
        ICalculator.initValueMap();
    }
}

Но самый простойвозможно, будет идти с Map.of, как предложено в ответе GhostCat, если только ваша среда выполнения Java не старше 9.

...