选择`Collection <myobject>`内部与`MyObject`类之外[Java]

时间:2017-10-25 19:29:21

标签: java collections

存储Collection<MyItem>的最佳方式是什么?对于当前用户,此集合实际上是静态的。每个用户只能看到他们的收藏。 MyItem项目实施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*/
}

我可以在其他位置存储Collection<MyItem>,但我无法从MyItem访问私有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*/
}

MyItem类内部(请参阅注释掉的选项):

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 - 存储所有项目的静态列表。看起来内存效率很高,但是如果我将来需要存储单独的MyItem集合呢?这极不可能,但仍然......

allItemsList - 同一个类有两个不同的功能。它要么是

存储单个项目,在这种情况下allItemsList/Map = null;
 或
 allItemsList = new ArrayList<>();,而其他字段为空。  这似乎没问题,但它打破了最低惊喜原则。

存储MyItemCollection的方法更自然?

此外,我应该将Item存储为Map还是List,因为MyItem myItem = getMyItemByID(int id);是访问MyItem的主要方式?

更新

我们可以实现一个Item类,以便实例可以保存Item实例的集合或建模数据,但不能同时保存两者。

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
} 

但成本是多少?本课程违反了单一责任原则。

结论 - 在大多数情况下,Item实例的集合应该存储在Item类之外。

1 个答案:

答案 0 :(得分:1)

在OOP中,对象的数据元素也称为对象的属性。因此,您应该问自己一个项目集合是否是项目的属性。

例如,假设您的项目是学生。你会说学生名单是学生的一个属性吗? - 可能不是,因为学生名单不是学生的一部分。相反,学生是学生名单的一部分。

由于学生名单不是现实生活中的学生属性,因此我不会在代码中对其进行不同的模拟,只是为了使其在技术上更加优雅。

您的类的设计应该由您正在使用的域的结构驱动。当您需要决定放置属性的位置时,请不要问&#34;将它放在这里是否有意义因为我的编程语言提供的功能?&#34;但请问&#34;此属性在我的域中属于哪个位置?&#34;。