Java 要使用嵌套的泛型集合或自定义中间类?
在将泛型引入Java语言之前,我已经编写了封装集合集合集合的类。例如:Java 要使用嵌套的泛型集合或自定义中间类?,java,generics,oop,Java,Generics,Oop,在将泛型引入Java语言之前,我已经编写了封装集合集合集合的类。例如: class Account { private Map tradesByRegion; //KEY=Region, VALUE=TradeCollection } class TradeCollection { private Map tradesByInstrument; //KEY=Instrument, Value=Trade } 当然,对于泛型,我可以做到: class Account { pr
class Account {
private Map tradesByRegion; //KEY=Region, VALUE=TradeCollection
}
class TradeCollection {
private Map tradesByInstrument; //KEY=Instrument, Value=Trade
}
当然,对于泛型,我可以做到:
class Account {
private Map<Region, Map<Instrument, Trade>> trades;
}
类帐户{
私人地图行业;
}
我现在倾向于选择选项#2(而不是选项#1的一般化版本),因为这意味着我不会出现大量的类,这些类的存在仅仅是为了包装一个集合。但我总觉得这是一个糟糕的设计(例如,在声明新类之前应该使用多少嵌套集合)。意见?我更喜欢2。它更清楚正在发生的事情,并且在编译时是类型安全的(我更喜欢在编译时让尽可能多的事情出错,而不是让它们发生在运行时……一般来说,我喜欢在没有出错的情况下)
编辑:
我可以从两个方面看到。。。我想这取决于你会使用哪一种:
class Account
{
private Map<Region, TradeCollection> tradesByRegion;
}
class TradeCollection
{
private Map<Instrument, Trade> tradesByInstrument;
}
类帐户
{
私人地图贸易区;
}
类交易集合
{
私人地图交易仪器;
}
或
类帐户
{
私人地图贸易区;
}
类交易集合
{
私人地图交易仪器;
}
我为自己制定了一条简单的规则:最好不要超过两个2,因为:
- 更少的代码可以实现同样的效果 效果(实际上更好,如#1 您的某些类型信息存在 (仅在评论中)
- 发生了什么完全清楚 开
- 您的类型错误将在编译时被捕获
有什么可推荐的吗?诚然,Map
对于保存数据,泛型是一件很棒的事情。但是,当您添加交易或帐户时,您仍然希望方法进行验证,并且如果没有某种类包装您的集合,没有人可以控制它。我认为最好记住对象,少强调集合。物化是你的朋友
例如,如果要为学校建模系统,自然会有学生和课程对象。分数应该在哪里记录?我认为它们属于学生和课程相遇的对象——报告卡。我不会有一个收集。给它一些真实的行为。我认为答案是这取决于情况。通常,如果引入类型还引入与该类型相关的方法,如果这些中间类型是独立传递的,那么引入类型是有用的 您可能会发现Rich Hickey(Clojure的创建者)关于创建可互操作库的建议非常有趣:
这是对Clojure图书馆作者的具体建议,但我认为即使在Java中也是一个有趣的想法。当然;但我可以通过包含泛型使1类型安全。我将编辑我的问题我开始这么说了。但当我把它变成通用的时候,我得到了基本相同的代码。。。我会再试一次,看看我得到了什么。我已经编辑了这个问题,以明确后泛型选项#1仍然是类型安全的,因为我会参数化MapsI不会向您显示我的泛型,然后(我有一个覆盖了大约10行以保持可读性:-)@ToBubeer最好不要这样做。在我的世界里,这是只写代码:)当然,#1的一个问题是,你最终会问很多问题,比如“什么是TradeCollection?”——也就是说,您需要从Account类进行更多的代码浏览,以了解交易集合的实际结构is@krosenvold我正在扼杀它:-)我当然同意:我认为这些集合是一个实现细节,我不会将它们传递或公开。我同意:ReportCard vsGradeCollection是我书中优秀设计选择的一个很好的例子。
class Account<R extends Region, I extends Instrument, T extends Trade, C extends TradeCollection<I, T>>
{
private Map<R, C> tradesByRegion;
}
class TradeCollection<I extends Instrument, T extends Trade>
{
private Map<I, T> tradesByInstrument;
}