patternjavaMinor
Adventure game player using public fields instead of getters and setters
Viewed 0 times
publicplayerfieldsadventuregettersinsteadgameusingandsetters
Problem
I was writing class
In the end, my class looks like this:
```
package com.game.quest.core.domain;
import com.game.quest.core.domain.armor.Accessory;
import com.game.quest.core.domain.armor.Armor;
import com.game.quest.core.domain.armor.Weapon;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
public class Player {
public PlayerData is;
public Chars crs;
{
is = new PlayerData();
crs = new Chars();
}
public class PlayerData {
public List stats = new ArrayList<>();
public List skills = new ArrayList<>();
public List titles = new ArrayList<>();
public List inventory = new ArrayList<>();
public Map quests = new HashMap<>();
public Map armor = new HashMap<>();
public Map weapons = new HashMap<>();
public Map accessories = new HashMap<>();
class PlayerDataHelper {
public Map filterQuestStatus(String filter) {
Map filtered = new HashMap<>();
for (Entry e : quests.entrySet()) {
if (e.getValue().getStatus().equals(filter)) {
filtered.put(e.getKey(), e.getValue());
}
}
return filtered;
}
public List getArmor() {
return new ArrayList<>(armor.values());
}
public void equipArmor(String bodyPart, Armor armor) {
unequipArmor(bodyPart);
PlayerData.this.armor.put(bodyPart, armor);
}
public voi
Player with private fields and getters and setters. But the number of methods started to grow, I used lists and maps so additionally I had to create methods to get size of them and every item by index, key and etc. I got tired and decided to use public fields instead of getters and setters. Additionally, I grouped them into inner classes.In the end, my class looks like this:
```
package com.game.quest.core.domain;
import com.game.quest.core.domain.armor.Accessory;
import com.game.quest.core.domain.armor.Armor;
import com.game.quest.core.domain.armor.Weapon;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
public class Player {
public PlayerData is;
public Chars crs;
{
is = new PlayerData();
crs = new Chars();
}
public class PlayerData {
public List stats = new ArrayList<>();
public List skills = new ArrayList<>();
public List titles = new ArrayList<>();
public List inventory = new ArrayList<>();
public Map quests = new HashMap<>();
public Map armor = new HashMap<>();
public Map weapons = new HashMap<>();
public Map accessories = new HashMap<>();
class PlayerDataHelper {
public Map filterQuestStatus(String filter) {
Map filtered = new HashMap<>();
for (Entry e : quests.entrySet()) {
if (e.getValue().getStatus().equals(filter)) {
filtered.put(e.getKey(), e.getValue());
}
}
return filtered;
}
public List getArmor() {
return new ArrayList<>(armor.values());
}
public void equipArmor(String bodyPart, Armor armor) {
unequipArmor(bodyPart);
PlayerData.this.armor.put(bodyPart, armor);
}
public voi
Solution
Using public fields is considered rather immoral, but I can feel your pain. I'm using project Lombok, which takes care of them. But your problem is different: you need no getters and setters, but a way to deal with your lists and maps and Lombok won't help you with them much (it'd help slightly and I'd use it anyway).
Initializer blocks are rather confusing and safe you nothing when compared to a constructor.
But actually, this should be
Variable names like
But still... now class
You're offering multiple ways how to do something and that's just bad. So make all mutable members
Use
This makes little sense to me. You're having
I'd for sure prefer some getter-setter-boilerplate to having a confusing class.
(*) With Lombok, I'd made them
public class Player {
public PlayerData is;
public Chars crs;
{
is = new PlayerData();
crs = new Chars();
}Initializer blocks are rather confusing and safe you nothing when compared to a constructor.
But actually, this should be
public class Player {
public PlayerData playerData = new PlayerData();
public Chars chars = new Chars();Variable names like
is are terrible at best.But still... now class
Player contains public mutable fields. So someone may get the field and modified it and nothing happens as someone else replaced them like insomeone: playerData.stats.clear();
someoneElse: playerData = new PlayerData();You're offering multiple ways how to do something and that's just bad. So make all mutable members
final.public Map armor = new HashMap<>();Use
final.public List getArmor() {
return new ArrayList<>(armor.values());
}This makes little sense to me. You're having
Map, which anyone can use at will and provide a List returning and copying getter. That's too confusing.I'd for sure prefer some getter-setter-boilerplate to having a confusing class.
- Either it's just a stupid container and then
publicfields could be acceptable assumingfinalon all mutable parts (*)
- or it's a class doing something interesting and then all fields should be private
(*) With Lombok, I'd made them
private final and use @Getter. At the very least, I'd get something I could put a breakpoint on.Code Snippets
public class Player {
public PlayerData is;
public Chars crs;
{
is = new PlayerData();
crs = new Chars();
}public class Player {
public PlayerData playerData = new PlayerData();
public Chars chars = new Chars();someone: playerData.stats.clear();
someoneElse: playerData = new PlayerData();public Map<String, Armor> armor = new HashMap<>();public List<Armor> getArmor() {
return new ArrayList<>(armor.values());
}Context
StackExchange Code Review Q#96068, answer score: 5
Revisions (0)
No revisions yet.