我有关于封装的问题:
当一个类有很多数据字段时,是否建议使用封装?
使用以下类作为示例:
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);
}
}
将大多数数据字段存储在strength
类中的不同类(例如constitution
和Stats
)会被视为更好的设计吗?
答案 0 :(得分:4)
我认为你指的是decomposition - 将大型系统分解为更小,更易于理解的部分的行为。
要正确分解代码,您必须关注cohesion:您的课程代表了多少内容?他们如何“坚持”在一起?
你的班级目前代表了很多东西:
name
constition
您的1个类代表多个实体;它具有低凝聚力。
所以要回答你的问题,是的,将统计相关字段移动到统计类是一件好事。但这不仅仅是你应该移动的领域,而是整个责任。这意味着如果您使用resetStats()
方法,它也会转到Stat
类。
如果被移动的成员是private
,则分解有助于进一步封装,因为它进一步隐藏了信息。但分解是它自己的主题。
答案 1 :(得分:2)
对象有行为。对象中的状态是支持该行为的。将一堆状态分开,仅仅作为一个状态的容器,而不是一个具有自己特定行为的独特对象,在事物的大局中并没有多大意义。