Reputation: 1431
What is the best way to store a Collection<MyItem>
? This collection is effectively static for current user. Each user can only see their collection. MyItem
item implements IItem
:
public interface IItem {
public Integer getItemID();
public void setItemID(Integer id);
public String getTitle();
public void setTitle(String title);
/*more getters and setters*/
public IItem parseServerResponse(String response);
public int postItem(); //posts this IItem to server, return ok ->200, unauth->401, etc
public IItem findItem(String[] filters);
/*more advanced methods*/
}
I can store Collection<MyItem>
elsewhere, but then I can't access private MyItem
methods from CurrentMyItems
:
public class CurrentMyItems{
private final List<IItem> allItemsList;
public CurrentMyItems(String allItemsServerResponseString){
JSONArray rawItems = parseResponse(allItemsServerResponseString);
int arrSize = rawItems.length()+estimateQuantityOfNewItems();
List<IItem> allItemsList = new ArrayList<>(arrSize);
for (int i = 0; i < Items.length(); i++) {
allItems.add(i, parseItem(Items.get(i)));
}
}
/*methods*/
}
Or inside of the MyItem
class (see commented out options):
public class MyItem implements IItem {
/*
private final static List<IItem> allItemsStaticList = new ArrayList<>();
private final static Map<Integer, IItem> allItemsStaticMap = new HashMap<>();
private final List<IItem> allItemsList; //
private final static Map<Integer, IItem> allItemsMap;
*/
/*implemented methods*/
}
allItemsStaticList
- stores a static list of all Items. Seems memory efficient, but what if I need to store separate collections of MyItems in future? This is highly unlikely, but still...
allItemsList
- Same class has two distinct functions. It is either
storing a single Item, in which case allItemsList/Map = null;
or
allItemsList = new ArrayList<>();
, while other fields are empty.
This seems OK, but it breaks the Least Surprise Principle.
Which approach to store a MyItemCollection
is more natural?
Also, should I store Item
s as a Map
or a List
given that MyItem myItem = getMyItemByID(int id);
is the main way to access MyItem
?
Update
We can implement an Item
class so that an instance can either hold a collection of Item
instances or the modeled data, but not both.
public class Item {
private final Map<Integer, Item> itemsMap;
private final IntegerProperty itemID; // private final String[] names;
public Item(){
itemsMap = new HashMap<>();
itemID = null; //names = null;
}
private Item(Integer id) {
itemsMap= null;
itemID = new SimpleIntegerProperty(id); //names = new String[1];
}
public Item makeGenericItem(){
return itemsMap == null ? null : new Item(itemsMap.size());
}
// other methods, including getters and setters
}
But at what cost?.. This class violates single responsibility principle.
Conclusion - in most cases a Collection of Item instances should be stored outside of Item class.
Upvotes: 1
Views: 60
Reputation: 4011
In OOP the data elements of an object are also known as attributes of the object. So, you should ask yourself whether a collection of items is an attribute of an item or not.
For example, when you assume your items are students. Would you say that a list of students is an attribute of a student? -- Probably not, as a list of students is not part of a student. Instead a student is part of a list of students.
Since a list of students is not an attribute of students in real life, I would not model it differently in code just to make it technically more elegant.
The design of your classes should be driven by the structure of the domain that your are working in. When you need to decide where to put an attribute do not ask "does it make sense to put it here because of the features my programming language offers?" but ask "where does this attribute belongs to in my domain?".
Upvotes: 1