Нужно предложение по практике кодирования по понятию «Не повторяйся» - PullRequest
1 голос
/ 13 мая 2019

Я хочу получить лучшее понимание чистого кодирования и ООП. Я создаю для этого экземпляра шахматную игру.

Теперь один из основных принципов: «Не повторяй себя». Прямо сейчас я не могу понять, как я мог бы создать Объект Player, который содержит список ChessFigures, не повторяя себя в методе createFigures ().

По моей логике класс Player содержит в начале каждой игры 16 цифр. Здесь я повторяюсь 6 раз. Какой будет предложенный алгоритм в этом случае?

public class Player {

    private ArrayList<Figure> figures = new ArrayList<Figure>(16);
    private ColorEnum playerColor;

    Player(ColorEnum color){
        this.playerColor = color; 
        createFigures();
    }

    private void createFigures(){
        addFigure(8, PAWN);
        addFigure(2, KNIGHT);
        addFigure(2, BISHOP);
        addFigure(2, ROOK);
        addFigure(1, QUEEN);
        addFigure(1, KING);
    }

    private void addFigure(int amount, FigureTypeEnum type){
        for(int i = 0; i < amount; i++) {
            this.figures.add(new Figure(type, this.playerColor));
        }
    }

    public ArrayList<Figure> getFigures() {
        return figures;
    }
}

Ответы [ 2 ]

2 голосов
/ 13 мая 2019

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

Но я бы не стал воспринимать ваш код как нарушение принципа DRY, так каку вас есть только один метод и все вызовы имеют разные аргументы.Код очень читабелен, как есть.

Нарушение принципа СУХОЙ будет, если у вас есть такие же вызовы и где-то еще.

1 голос
/ 13 мая 2019

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

В случае с шахматами это может быть немного излишним, но в более общем смысле это кажется чистым решением.

В качестве альтернативы, вы можете использовать static final Map<FigureTypeEnum, Integer> для хранения конфигурации и заполнить ее статическим блоком инициализатора. Однако статические блоки инициализатора не очень распространены (по крайней мере, по моему опыту) и могут запутать начинающих разработчиков.

Некоторые другие советы:

  • Не используйте свидетель типа в инициализации ArrayList. Этого должно быть достаточно: private ArrayList<Figure> figures = new ArrayList<>();
  • Я не уверен насчет начального размера списка массивов. Это работает в этом случае, потому что вы знаете, что есть 16 штук. Но вы создаете неявную зависимость между createFigures и инициализацией. Кроме того, это кажется преждевременной оптимизацией.
  • Рассмотрите возможность определения фигур в виде списка вместо ArrayList. Какая реализация List выбрана, похоже, не имеет отношения к вашему коду.

EDIT: Еще одно соображение: если вы возвращаете фактический список в методе getFigures (), вы позволяете другим добавлять или удалять элементы из этого списка. Это может быть нежелательно. Вы можете использовать некоторый неизменный список (см., Например: https://www.baeldung.com/java-immutable-list) или вернуть копию списка.

...