如何不复制代码,而是创建一个方法?

问题描述 投票:0回答:1

我有一个方法

    private void positionMagican() {
        int x;
        int y;
        boolean magicanIsCreated;
        magicanIsCreated = false;
        while (!magicanIsCreated){
            x = random.nextInt(sizeX);
            y = random.nextInt(sizeY);
            if(field.getFieldable(x,y) instanceof Empty){
                mag = new Magician(x,y,sizeX,sizeY,field,player,this);
                field.setFieldable(x,y,mag);
                magicanIsCreated = true;
            }
        }
    }

方法完全相同,但不是魔术师,而是蛇、桶等。

这是一个例子

    private void positionGoblin() {
        int x;
        int y;
        boolean goblinIsCreated;
        goblinIsCreated = false;
        while (!goblinIsCreated){
            x = random.nextInt(sizeX);
            y = random.nextInt(sizeY);
            if(field.getFieldable(x,y) instanceof Empty){
                goblin = new Goblin(x,y,player,field,this,sizeX,sizeY);
                field.setFieldable(x,y,goblin);
                goblinIsCreated = true; 
            }
        } 
     } ``` 

这里的区别仅在于对象的类及其参数,因此项目中有许多相同的方法,我不明白如何创建一个可以输入所需参数的方法。是否可以创建一种结合这些方法的方法?我不明白。如何确保创建具有所需参数的所需类的对象。

java java-8 dry
1个回答
0
投票

将构造函数包装在一个接口中。

您的 Magician 和 Goblin 构造函数以不同的顺序获取参数,但这没关系,因为这是接口可以解决的问题之一:

private interface CharacterGenerator {
    GameCharacter createCharacter(int x,
                                  int y,
                                  int sizeX,
                                  int sizeY,
                                  Field field,
                                  Player player,
                                  Game game);
}

(我假设 Magician 和 Goblin 继承了一个共同的父级,要么是一个共同的超类,要么是一个共同的接口——为了举例,我将其命名为

GameCharacter
。)

我选择使用与 Magician 构造函数相对应的顺序,但这并不重要,因为该接口的每个实现都可以选择随心所欲地使用构造函数,包括重新排序它们:

private static class MagicianGenerator
implements CharacterGenerator {
    @Override
    public GameCharacter createCharacter(int x,
                                         int y,
                                         int sizeX,
                                         int sizeY,
                                         Field field,
                                         Player player,
                                         Game game) {

        return new Magician(x, y, sizeX, sizeY, field, player, game);
    }
}

private static class GoblinGenerator
implements CharacterGenerator {
    @Override
    public GameCharacter createCharacter(int x,
                                         int y,
                                         int sizeX,
                                         int sizeY,
                                         Field field,
                                         Player player,
                                         Game game) {

        return new Goblin(x, y, player, field, game, sizeX, sizeY);
    }
}

现在您可以创建一种定位方法而不是两种方法,并将实现了 CharacterGenerator 的对象传递给该一种定位方法:

private void positionCharacter(CharacterGenerator generator) {
    while (true) {
        int x = random.nextInt(sizeX);
        int y = random.nextInt(sizeY);
        if (field.getFieldable(x,y) instanceof Empty) {
            GameCharacter c = generator.createCharacter(
                x, y, sizeX, sizeY, field, player, this);
            field.setFieldable(x, y, c);
            break;
        }
    }
}

并且将使用以下调用之一来调用该方法:

positionCharacter(new MagicianGenerator());
positionCharacter(new GoblinGenerator());

请注意,我删除了您的布尔“created”变量。 你不需要它。 只需使用

break
即可退出循环。

正如其他人所指出的,如果您要使 Magician 构造函数和 Goblin 构造函数以完全相同的顺序采用相同的参数,,您可以使这变得更加简洁,因为这将允许您将 CharacterGenerator 接口视为函数式接口,它允许您使用方法引用而不是显式实现类:

positionCharacter(Magician::new);
positionCharacter(Goblin::new);
© www.soinside.com 2019 - 2024. All rights reserved.