Java OOD和代码重复

时间:2015-10-24 06:47:20

标签: java oop code-duplication

我开始创建一个基本的角色扮演游戏,现在我正在研究基础知识。我有一个代码重复用于创建新角色和现有角色,这是一个非常糟糕的事情。我将解释我的问题 - 一开始玩家可以通过使用CharacterCreator来选择角色类(如战士)。我有一个Character类,它描述了有关角色的所有信息。我还有一个名为abstract的{​​{1}}类,它描述了特定属性和字符类的其他内容(如Fighter,而不是java类)。 CharacterClass有一些子类(如CharacterClassFighter等)。代码有效,但设计不好。

如何摆脱MageCharacter的代码重复?我应该改变设计吗?

CharacterClass
public class Game {
    public static void main(String[] args) {
        Character hero =  CharacterCreator.CharacterCreator();
    }
}


public class CharacterCreator {

    public static Character CharacterCreator() {
        System.out.println("Choose a character: ");
        System.out.println("1. Fighter");
        System.out.println("2. Rogue");
        System.out.println("3. Mage");
        System.out.println("4. Cleric");


        Scanner sc = new Scanner(System.in);
        int scan = sc.nextInt();
        String choice = getCharacterClass(scan);

        System.out.println("Choose Name:");
        Scanner nameIn = new Scanner(System.in);
        String name = nameIn.next();

        CharacterClass chosenClass = null;
        Character hero = null;

        switch (choice){
        case "Fighter":
            chosenClass = new Fighter();
            break;
        case "Rogue":
            chosenClass = new Rogue();
            break;
        case "Mage":
            chosenClass = new Mage();
            break;
        case "Cleric":
            chosenClass = new Cleric();
            break;
        }

        try {
            hero = new Character(name, chosenClass);
            System.out.println("A hero has been created");
            hero.displayCharacter();
        } catch (Exception e){
            System.out.println("There was a problem assigning a character class");
        }

        return hero;

    }

    public static String getCharacterClass(int scan){

        String classIn;

        switch (scan) {
        case 1:
            classIn = "Fighter";
            break;
        case 2:
            classIn = "Rogue";
            break;
        case 3:
            classIn = "Mage";
            break;
        case 4:
            classIn = "Cleric";
            break;
        default:
            System.out.println("Enter again");
            classIn = "def";
        }

        return classIn;
    }
}

public class Character {

    private String name;
    private String characterClass;
    private int level;
    private int hp;
    private int currentHp;
    private int armorClass;

    private long xp;
    /*private int BAB; /*Base attack bonus*/

    private int strength;
    private int constitution;
    private int dexterity;
    private int intelligence;
    private int wisdom;
    private int charisma;

    Character(String name, CharacterClass chosenClass){

        this.name = name;
        this.characterClass = chosenClass.getCharacterClass();
        level =  chosenClass.getLevel() ;
        hp = ( chosenClass.getHp() + getModifier( chosenClass.getConstitution() )  );
        currentHp = hp;
        setArmorClass(10 + getModifier( + chosenClass.getDexterity()));
        strength = chosenClass.getStrength();
        constitution = chosenClass.getConstitution();
        dexterity = chosenClass.getDexterity();
        intelligence = chosenClass.getIntelligence();
        wisdom = chosenClass.getWisdom();
        charisma = chosenClass.getCharisma();
        xp = 0;


    }

    void displayCharacter() throws IOException {
        System.out.print("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
        System.out.println("Name: " + getName());
        System.out.println("Class: " + getCharacterClass());
        System.out.println("Level: " + getLevel());
        System.out.println("HP: " + getHp());
        System.out.println("Armor Class: " + getArmorClass());

        System.out.println("***************");
        System.out.println("Attributes: ");
        System.out.println("Strength: " + getStrength());
        System.out.println("Constitution: " + getConstitution());
        System.out.println("Dexterity: " + getDexterity());
        System.out.println("Intelligence: " + getIntelligence());
        System.out.println("Wisdom: " + getWisdom());
        System.out.println("Charisma: " + getCharisma());
        System.out.println("***************");
        System.out.println("XP: " + getXp());

    }

    public int getModifier(int number){
        int mod = (int)((number -10)/2);
        return mod;
    }

    public String getName() { return name; }
    public String getCharacterClass() { return characterClass; }
    public int getLevel() { return level; }
    public int getHp() { return  hp; }
    public int getCurrentHp() { return  currentHp; }
    public int getArmorClass() { return  armorClass; }
    public int getStrength(){ return strength; }
    public int getConstitution(){ return constitution; }
    public int getDexterity(){ return dexterity; }
    public int getIntelligence(){ return intelligence; }
    public int getWisdom(){ return wisdom; }
    public int getCharisma(){ return charisma;}
    public long getXp(){ return xp;}


    protected void setLevel(int lvl){ level = lvl; }
    protected void setHp(int hitPoints){ hp = hitPoints; }
    protected void setCurrentHp(int curHp){ currentHp = curHp; }
    protected void setArmorClass(int ac){ armorClass = ac; }
    protected void setStrength(int str){ strength = str; }
    protected void setConstitution(int con){ constitution = con; }
    protected void setDexterity( int dex) { dexterity = dex; }
    protected void setIntelligence(int intel){ intelligence = intel; }
    protected void setWisdom(int wis){ wisdom = wis; }
    protected void setCharisma(int cha){charisma = cha; }



}

2 个答案:

答案 0 :(得分:2)

建议:

  1. CharacterCreator.CharacterCreator()。方法应该是动词并描述动作,即createCharacter
  2. 看广告设计图案工厂。你的造物主是'工厂'。方法'createCharacter'应该使用参数characterType。这意味着,从System.in获取信息应该在调用该方法的类中完成。
  3. 为characterClass添加enum并映射到数字(查看枚举中的内部地图)。

答案 1 :(得分:0)

虽然这不是您问题的直接解决方案,但从长远来看,这应该对您有所帮助。当涉及到游戏,特别是RPG类型时,你有许多似乎相似而又不同的对象,继承并不是设计的最佳基础。在您拥有的示例之上,在设计耗材/武器/齿轮/ NPC等时也会遇到问题。这意味着您最终会在许多类中使用重复的代码,因为使用抽象类意味着所有子类都具有相同的行为,但事实并非如此。

在这种情况下,更好的方法是避免继承并使用ECS。这意味着一切都是一种实体。为了向实体添加一些“功能”,您将使用组件类型。例如,物品没有HP属性,但是当放在地上时,它们可能会受到攻击和破坏。这意味着我们需要为它添加动态属性。我们可以这样做:

entityItem.addComponent(new HPComponent(50));

这将允许其他系统(如攻击/损坏)“看到”该实体具有HP组件并且可能受到攻击。

这只是ECS的一个小例子,还有很多其他内容。我建议阅读更多关于它的内容,因为这将使游戏开发设计(对于大多数游戏)显得更加顺畅。