2015-11-18 23 views
5

Ho una domanda riguardante l'incapsulamento:Progettazione orientata agli oggetti: quanto è importante l'incapsulamento quando ci sono molti campi dati in una classe?

Si consiglia di utilizzare l'incapsulamento quando una classe ha molti campi dati?

Utilizzando la seguente classe come esempio:

abstract public class Character { 
    private String name; 
    private String characterClass; 
    private int level; 
    private int hitDice; 

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

    private int hp; 
    private int currentHp; 
    private int armorClass; 
    private int BaseAttackBonus; 

    private long xp; 
    private double gp; 

    private Inventory inventory; 
    private double carriedWeight; 

    private Equipment equipment; 

    protected Character(String name) { 

     setName(name); 
     setCharacterClass("Class"); 
     setLevel(1); 
     setHitDice(0); 

     setStrength(10); 
     setConstitution(10); 
     setDexterity(10); 
     setIntelligence(10); 
     setWisdom(10); 
     setCharisma(10); 

     setHp((int) getLevel() * (getHitDice() + getModifier(getConstitution()))); 
     setCurrentHp(getHp()); 
     setArmorClass(10 + getModifier(getDexterity())); 
     setBaseAttackBonus(0); 

     inventory = new Inventory(); 
     setCarriedWeight(0); 

     equipment = new Equipment(); 

     setXp(0); 
     setGp(20); 

    } 

    protected Character(String name, int lvl) { 

     setName(name); 
     setCharacterClass("Class"); 
     setLevel(lvl); 
     setHitDice(0); 

     setStrength(10); 
     setConstitution(10); 
     setDexterity(10); 
     setIntelligence(10); 
     setWisdom(10); 
     setCharisma(10); 

     setHp((int) getLevel() * (getHitDice() + getModifier(getConstitution()))); 
     setCurrentHp(getHp()); 
     setArmorClass(10 + getModifier(getDexterity())); 
     setBaseAttackBonus(0); 

     inventory = new Inventory(); 
     setCarriedWeight(0); 

     equipment = new Equipment(); 

     setXp(1000 * (getLevel() - 1)); 
     setGp(getLevel() * 20); 

    } 

    void displayCharacter() throws IOException { 
     System.out.print("\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("Current HP: " + getCurrentHp()); 
     System.out.println("Armor Class: " + getArmorClass()); 
     System.out.println("Base Attack Bonus : +" + getBaseAttackBonus()); 

     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("***************"); 
     equipment.showEquipment(); 
     inventory.showInventory(); 
     System.out.println("Carried weight: " + getCarriedWeight()); 

     System.out.println(""); 
     System.out.println("XP: " + getXp()); 
     System.out.println("Gold: " + getGp()); 
     System.out.println(""); 

    } 

    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 getHitDice() { 
     return hitDice; 
    } 

    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 int getHp() { 
     return hp; 
    } 

    public int getCurrentHp() { 
     return currentHp; 
    } 

    public int getArmorClass() { 
     return armorClass; 
    } 

    public int getBaseAttackBonus() { 
     return BaseAttackBonus; 
    } 

    public Equipment getEquipment() { 
     return equipment; 
    } 

    public Inventory getInventory() { 
     return inventory; 
    } 

    public double getCarriedWeight() { 
     return carriedWeight; 
    } 

    public long getXp() { 
     return xp; 
    } 

    public double getGp() { 
     return gp; 
    } 

    protected void setName(String Name) { 
     name = Name; 
    } 

    protected void setCharacterClass(String characterClass) { 
     this.characterClass = characterClass; 
    } 

    protected void setLevel(int lvl) { 
     level = lvl; 
    } 

    protected void setHitDice(int hd) { 
     hitDice = hd; 
    } 

    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; 
    } 

    protected void setHp(int hitPoints) { 
     hp = hitPoints; 
    } 

    protected void setCurrentHp(int curHp) { 
     currentHp = curHp; 
    } 

    protected void setArmorClass(int ac) { 
     armorClass = ac; 
    } 

    protected void setBaseAttackBonus(int bab) { 
     BaseAttackBonus = bab; 
    } 

    protected void setXp(int XP) { 
     xp = XP; 
    } 

    protected void setGp(double GP) { 
     gp = GP; 
    } 

    protected void setCarriedWeight(double weight) { 
     carriedWeight = weight; 
    } 

    public void attack(Character target) { 

     try { 
      ((Weapon) getEquipment().getPrimaryHand()).attack(this, target); 
     } catch (NullPointerException e) { 
      getEquipment().equipPrimaryHand(
        MeleeWeapon.meleeWeaponList.get(0)); /* equip fist weapon */ 
      ((Weapon) getEquipment().getPrimaryHand()).attack(this, target); 

      if (target.getCurrentHp() <= 0) { 
       System.out.println(target.getName() + " is down !"); 
      } 
     } 
    } 

    public void equip() { 
     getInventory().equip(this); 
    } 

    public void addToInventory(Item newItem) { 
     getInventory().addToInventory(this, newItem); 
    } 

} 

Sarebbe immagazzinare la maggior parte delle schede campi in classi diverse, come ad esempio strength e constitution in una classe Stats, essere considerato come un progetto migliore?

+1

Voglio dire, sembra abbastanza buono da quello che hai. Questa è più una domanda di revisione del codice, anche se credo. – 3kings

+1

"molti campi dati" non sono i criteri. È: sono tutti quei campi di dati lì per lo stesso scopo: https://en.wikipedia.org/wiki/Single_responsibility_principle – zapl

+1

"si consiglia di utilizzare l'incapsulamento quando una classe ha molti campi di dati" Dove l'hai trovato? Alcuni o molti campi NON sono il fattore per usare l'incapsulamento. Controlla il tuo OOP. – Loc

risposta

4

Penso che ti stia riferendo a decomposition - l'atto di rompere i sistemi di grandi dimensioni in parti più piccole, più facili da capire.

Per decomporre correttamente il codice, è necessario concentrarsi su cohesion: Quante cose rappresenta la classe? Quanto bene "si attaccano" insieme?

tua classe rappresenta attualmente un bel paio di cose:

  1. Character informazioni di identificazione, come ad esempio name
  2. Tracker abilità, come ad esempio constition
  3. Experience Tracker
  4. inventario
  5. scala personale

La tua classe 1 rappresenta più entità; ha una bassa coesione.


Quindi, per rispondere alla tua domanda, sì, spostando i campi relativi stat a una classe stat sarebbe una buona cosa. Ma non sono solo i campi che dovresti spostare, è l'intera responsabilità. Ciò significa che se hai un metodo resetStats(), anche questo andrebbe alla classe Stat.

La scomposizione aiuta a incapsulare ulteriormente se i membri da spostare sono private, poiché nasconde ulteriormente informazioni. Ma la decomposizione è un argomento personale.

+2

Grazie per la risposta. Sì, intendevo la decomposizione, sono nuovo nel mondo OO :) – Niminim

+0

Quindi la classe delle statistiche dovrebbe includere livello, forza, armorClass ecc.? Punti esperienza (xp) e oro (gp) non sono statistiche, dovrei anche includerli nella classe delle statistiche? – Niminim

+1

@Niminim Conterrà sicuramente 'strength', poiché si tratta di una stat. Non sono sicuro di cosa sia 'armorClass', quindi dipenderebbe dal suo contesto. Per me, sembra informazione sull'attrezzatura. 'gold' suona come un oggetto, e' xp' dipende molto da come gestisci le cose. Puoi scomporre ciascuna stat nel suo tipo, come "FireMaking", che ha tutti i dettagli per quell'abilità –

2

Gli oggetti hanno un comportamento. Lo stato all'interno dell'oggetto è lì per supportare tale comportamento. Separare un gruppo di stati, semplicemente come un contenitore di stato, piuttosto che un oggetto distinto con i propri comportamenti specifici, non ha molto senso nel quadro generale delle cose.