Groovy如此强大,我想知道是否有简单的方法可以做到这一点。
场景:
我有一个抽象类AbstractSequence
。然后,我有两个(实际上是更多)子类,分别称为say CasedSequence
和LowerCaseSequence
。这些具体类中的每一个都必须具有一个“身份映射表”,即像Set
一样,但是可以根据功能相等性(覆盖equals
和hashCode
来提取元素
所以我们有:
class CasedSequence extends AbstractSequence {
static Map identityMap = [:]
...
class LowerCaseSequence extends AbstractSequence {
static Map identityMap = [:]
实际上,由于需要花费太长时间解释的原因,在各个类中对这些标识映射的操纵还使用了许多静态方法,从一个子类到另一个子类都相似/相同。因此,我想知道如何重构身份映射到抽象基类中(然后在其中迁移很多重复的静态方法)。
这导致我想到这个:
abstract class AbstractSequence {
static Map getIdentityMap( Class clazz ) {
if( ! ( clazz in identityMaps ))
identityMaps[ clazz ] = [ : ]
identityMaps[ clazz ]
}
static Map identityMaps = [:]
然后在具体的类中,每次您想要使用身份映射时,都必须这样做:
class CasedSequence extends AbstractSequence {
def someMethod( CasedSequence seq1 ){
CasedSequence seq2 = getIdentityMap( CasedSequence )[ seq1 ]
...
同样,要解释为什么需要这种方式检索东西太复杂了……但是我只是想知道AbstractSequence.getIdentityMap()
中是否有一种方法(一种优雅的Groovy方法?)来标识该类。子类调用getIdentityMap()
,而不必将此类作为参数传递?
PS我宁愿不使用Thread.stackTrace
:它很麻烦,并且不会提供实际的类对象,只有类名以及Groovy中的堆栈跟踪很常见。我在考虑Groovy反射,Groovy元类...
答案 0 :(得分:0)
将有兴趣听取任何Groovy专家的意见。
同时,我利用了一些Groovy魔术作为变通办法,利用了Groovy GDK向class
类添加了一些方法的事实,其中一个是newInstance()
-非常有用。根据所寻找的序列是否已经在身份图中,“生成或获取”序列对象。
static makeOrGet( String string, Class clazz ) {
def dummySeq = clazz.newInstance( DUMMY_STRING )
// NB the constructor identifies the string DUMMY_STRING to prevent this new object being
// properly "registered" (i.e. put in the identity map), which would be wrong because
// the dummy seq is just to find out whether the sequence with "string" is actually
// present in the map
def seq
// disguise the dummy sequence to flush out an existing sequence with String "string"
dummySeq.string = string
if( dummySeq in getIdentityMap( clazz ) )
seq = getIdentityMap( clazz )[ dummySeq ]
else
// NB constructor puts the new "clazz" object in the identity map
seq = clazz.newInstance( string )
seq
}
...因此可以用各种不同的类作为参数2调用上述方法,然后传递clazz
类的对象,该对象可以从身份映射中提取或构造(并放入映射中)。 / p>