需要有关“不要重复自己”概念的编码实践的建议

时间:2019-05-13 10:47:23

标签: java oop coding-style

我想更好地了解干净的编码和OOP。我为此实例创建了一个国际象棋游戏。

现在,基本原则之一是:“不要重复自己”。现在,我不知道如何创建一个播放器对象,该对象可以保存一个ChessFigures列表,而无需在createFigures()方法中重复自己的工作。

按照我的逻辑,Player类在每个游戏开始时都保持16位数字。我在这里重复六遍。在这种情况下,建议的算法是什么?

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 个答案:

答案 0 :(得分:2)

如果您真的想摆脱重复,可以将计数添加到枚举并对所有枚举值进行插值。

但是我不会认为您的代码违反了DRY原理,因为您只有一个方法,并且调用都具有不同的参数。该代码是非常可读的。

如果您在其他地方也有相同的呼叫,则会违反DRY原则。

答案 1 :(得分:1)

这在很大程度上是一个见解,我认为您当前的方法并没有多大问题。但是,我认为片段的类型和数量是配置,而不是程序的一部分。您可以创建一个配置文件,该文件定义每个玩家可用的棋子。如果由于某种原因国际象棋的规则更改为包括另一部分,则只需要更改配置,就无需弄清楚在源代码中的定义位置。

在国际象棋的实际情况下,这可能有点过大,但从更一般的意义上讲,这似乎是一个干净的解决方案。

或者,您可以使用static final Map<FigureTypeEnum, Integer>来保存配置,并将其填充到静态初始化程序块中。但是,静态初始化程序块并不是很常见(至少以我的经验),并且可能会使初级开发人员感到困惑。

其他一些提示:

  • 在ArrayList的初始化中不要使用类型见证。这应该满足:private ArrayList<Figure> figures = new ArrayList<>();
  • 我不确定数组列表的初始大小。在这种情况下它可以工作,因为您知道有16件。但是,您需要在createFigures和初始化之间创建隐式依赖关系。另外,这似乎是过早的优化。
  • 考虑将图形定义为列表而不是ArrayList。选择哪种List实现似乎与您的代码无关。

编辑: 另一个注意事项:如果您在getFigures()方法中返回实际列表,则允许其他人从该列表中添加或删除项目。这可能不是理想的。您可以使用一些不可变的列表(例如:https://www.baeldung.com/java-immutable-list)或返回列表的副本。