使用字符串键区分外部键和内部键

问题描述:

我们有两种ID,internal和externalA。当前记录具有内部ID和外部ID,并且将来可能会有externalB类型的ID,因此某些记录可能具有内部和外部B ID。使用字符串键区分外部键和内部键

我们当前将所有ID表示为字符串。它可能导致错误,方法期望内部,但externalA键实际上被传递。

我们如何防止这种类型的错误?将包装字符串键到InternalID,ExternalAID,ExternalBID类和使用那些包装到处为我们工作? 我很担心内存占用情况,如果我们正在谈论数以亿计的密钥,以及可能出错的其他内容,这可能会发生。

我认为你需要一个所有字符串键的鉴别器。例如:

String internalKey= "I1000201"; 
String externalAKey= "A1000201"; 
String externalBKey= "B1000201"; 

然后你就可以通过的第一个字符检查实际密钥类型防止错误,例如:

char type = key.charAt(0); 
if(type != 'I') throw new IllegalArgumentException("Invalid key"); 
// go on 

您也可以从String键,如果所有创建自己的Key类的钥匙需要一个独特的鉴别器。

Key internal = Key.from("I1000201"); //internal key 
Key external = Key.from("A1000201"); //external key A 
Key.from("X1000201"); 
//  ^--- throws IllegalArgumentException for invalid key type 

public class Key { 
    private final String key; 
    private final Visibility visibility; 

    private static final BitSet externals = new BitSet(); 

    static { 
     // register your own external key here 
     externals.set('A'); 
     externals.set('B'); 
    } 

    //  v--- make the Key constructor private. 
    private Key(String key, Visibility visibility) { 
     this.key = key; 
     this.visibility = visibility; 
    } 


    public static Key from(String key) { 
     return new Key(key, visibilityOf(key)); 
    } 

    private static Visibility visibilityOf(String key) { 
     char type = key.charAt(0); 
     return type == 'I' ? Visibility.INTERNAL 
          : externals.get(type) ? Visibility.EXTERNAL 
               : failsOnInvalidKey(key); 
    } 

    private static Visibility failsOnInvalidKey(String key) { 
     throw new IllegalArgumentException("Invalid Key: \"" + key + "\""); 
    } 

    public char type() { 
     return key.charAt(0); 
    } 

    public String value() { 
     return key.substring(1); 
    } 

    public boolean isExternal() { 
     return visibility == Visibility.EXTERNAL; 
    } 

    public String toString() { 
     return key; 
    } 

    // preserve it maybe will introduce additional behavior in future 
    private enum Visibility { 
     EXTERNAL, 
     INTERNAL 
    } 
} 
+2

这是我的想法正好 – Eugene

+0

@Eugene我还通过在休眠所有实体一个表支持的启发。 :) –

+2

如果我没有记错的话,我们在内部也是这样做的,我们在那里携带一个byte [],而第一个byte只是一些元数据。 – Eugene