Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Object-Oriented design - how important is encapsulation when there're lots of data-fields in one class?

I've a question regarding encapsulation:

Is it recommended to use encapsulation when a class has lots of data-fields?

Using the following class as an example:

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

}

Would storing most of the data-fields in different classes, such as strength and constitution in a Stats class, be considered as a better design?

like image 244
Niminim Avatar asked Nov 18 '15 15:11

Niminim


People also ask

Why is encapsulation the most important part of a single class?

The main purpose or usage of encapsulation is to guarantee security for a class's data. To secure the data, we must employ private access modifiers, which limit access to the data outside of the class. Access modifiers are used to specify the level of access or scope of class members such as data members and functions.

What is importance of encapsulation in object-oriented programming?

Encapsulation is one of the fundamentals of OOP (object-oriented programming). It refers to the bundling of data with the methods that operate on that data. Encapsulation is used to hide the values or state of a structured data object inside a class, preventing unauthorized parties' direct access to them.

Why are encapsulation and information hiding important characteristics of object-oriented systems?

The main purpose of encapsulation is you would have full control on data by using the code. In encapsulation, the variables of a class can be made hidden from other classes, and can be accessed only through the methods of their current class. Therefore, it is also known as data hiding.

How does encapsulation allow you to change the internal implementation of a class?

How does encapsulation allow you to change the internal implementation of a class? When a class is encapsulated clients cannot directly access its fields, so changing those fields will not disturb client behavior as long as the external view (method behavior) is consistent.


1 Answers

I think you're referring to decomposition - the act of breaking large systems down into smaller, easier to understand parts.

To properly decompose your code, you must focus on cohesion: How many things does your class represent? How well do they "stick" together?

Your class currently represents quite a few things:

  1. Character identity info, such as name
  2. Skill Tracker, such as constition
  3. Experience Tracker
  4. Inventory
  5. Personal Scale

Your 1 class represents multiple entities; it has low cohesion.


So to answer your question, yes, moving stat related fields to a stat class would be a good thing. But it's not just the fields you should move, it's the entire responsibility. This means if you have a resetStats() method, it too would go to the Stat class.

Decomposition helps further encapsulation if the members being moved are private, since it further hides info. But decomposition is it's own subject.

like image 94
Vince Avatar answered Oct 03 '22 09:10

Vince