2017-07-28 49 views
4

我們有兩種ID,internal和externalA。當前記錄具有內部ID和外部ID,並且將來可能會有externalB類型的ID,因此某些記錄可能具有內部和外部B ID。使用字符串鍵區分外部鍵和內部鍵

我們當前將所有ID表示爲字符串。它可能導致錯誤,方法期望內部,但externalA鍵實際上被傳遞。

我們如何防止這種類型的錯誤?將包裝字符串鍵到InternalID,ExternalAID,ExternalBID類和使用那些包裝到處爲我們工作? 我很擔心內存佔用情況,如果我們正在談論數以億計的密鑰,以及可能出錯的其他內容,這可能會發生。

回答

3

我認爲你需要一個所有字符串鍵的鑑別器。例如:

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