2011-12-02 31 views
0

我想再次談談關於設計問題的看法。JavaBean設置屬性。多個if語句的替代方案

我有一個擁有15個屬性的JavaBean。爲了提供屬性,我有一個循環的,它迭代了一系列鍵值對(具體地說是SAML屬性,我將屬性響應映射到校長屬性)。我的鍵值調用相應的二傳手方法的基礎,這就是:

.../... 
    for (SAML2AttributeInfo attr : attrs) { 
     if (attr.getAttributeName().equals("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn")) { 
      customPrincipal.setUpn(attr.getAttributeValues().iterator().next()); 
     } 
     .../... so on and so forth 
    } 

它的工作原理,沒關係,但我有一個醜陋的代碼,15 if語句像上面看起來不很優雅。

我使用Reflection想,這就是開發出獨特的設置方法,並通過它的屬性,他的價值的名稱。

另一種選擇,可以存儲在Map的屬性,但我不知道......

任何想法?

由於提前,

路易斯

回答

1

多態性救援

enum Attribute { 
    UPN("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn") { 
     void setValue(Principal principal, String value) { 
      principal.setUpn(value); 
     } 
    }, 
    ... 
    ; 

    private final String name; 

    private Attribute(String name) { 
     this.name = name; 
    } 

    public abstract setValue(Principal principal, String name); 

    public static Attribute getByName(String name) { 
     for (Attribute attribute : values()) 
      if (attribute.name.equals(name)) 
       return attribute; 

     return null; 
    } 

    public static void setByName(Principal principal, String name, String value) { 
     Attribute attribute = getByName(name); 

     if (attribute == null) 
      throw new IllegalArgumentException("No such attribute"); 

     attribute.setValue(principal, value); 
    } 
} 

如果你知道你想要設置沒有理由去通過名字去屬性:

Attribute.UPN.setValue(principal, "something"); 
+1

我會走得更遠,並在枚舉中添加一個靜態屬性getByName(String name)方法,以避免強制客戶端遍歷所有值。 –

+0

謝謝Ckuck,非常好的解決方案!優雅.. – Gaucho

+0

嗨JB Nizet,非常感謝你。我已經實現這樣的方法:'公共靜態屬性GetAttributeByName函數(字符串名稱){ \t \t屬性屬性= NULL; \t \t爲(屬性ATTR:Attribute.values()){ \t \t \t如果(attr.getName()等於(名稱)。) \t \t \t \t屬性=屬性; \t \t \t break; \t \t} \t \t回報屬性; \t}'我不確定這是否是最好的實施... – Gaucho

2

我會用地圖和與屬性鍵聲明靜態變量:

public class Bean { 
    public static final String ATTRIBUTE_1 = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn"; 
    public static final String ATTRIBUTE_2 = "..."; 
    ... 
    public static final String ATTRIBUTE_N = "..."; 


    private Map<String, Object> map = new HashMap<String, Object>(); 

    public void put(String key, Object value) { 
    map.put(key, value); 
    } 

    public Object get(String key) { 
    map.get(key); 
    } 
} 

然後,您coud存儲/使用靜態變量檢索值:

Bean bean = new Bean(); 

bean.set(Bean.ATTRIBUTE_1, someValue); 

Object value = bean.get(Bean.ATTRIBUTE_1); 
+0

這樣的常數列表應該由枚舉來代替。 – CKuck

+0

非常感謝Pablo。這也是我的第一個方法。 – Gaucho