2013-10-24 64 views
2

我需要一些幫助設計我的問題的邏輯。如何避免許多if-else與許多條件

模型bean

package com.ashish.model; 
public class Model { 
    public Integer a,b,c,d; 
    public String f,g,h,i,j; 
} 

服務類

package com.ashish.service; 

import com.ashish.model.Model; 
public class Service { 
    public StringBuilder query = null; 
    public Service(){ 
     query = new StringBuilder("Select * from A where "); 
    } 
    public String build(Model m){ 
      if(m.a != null&&m.b==null&&m.c==null&&m.d==null&m.e==null&&m.f==null&&m.g==null&&m.h==null&&m.i==null&&m.j==null) 
     query.append("a="+m.a); 
    if(m.a == null&&m.b!=null&&m.c==null&&m.d==null&m.e==null&&m.f==null&&m.g==null&&m.h==null&&m.i==null&&m.j==null) 
     query.append("b="+m.b); 
    if(m.a == null&&m.b==null&&m.c!=null&&m.d==null&m.e==null&&m.f==null&&m.g==null&&m.h==null&&m.i==null&&m.j==null) 
     query.append("c="+m.c); 
    if(m.a == null&&m.b==null&&m.c==null&&m.d!=null&m.e==null&&m.f==null&&m.g==null&&m.h==null&&m.i==null&&m.j==null) 
     query.append("d="+m.d); 
    if(m.a == null&&m.b==null&&m.c==null&&m.d==null&m.e!=null&&m.f==null&&m.g==null&&m.h==null&&m.i==null&&m.j==null) 
     query.append("e="+m.e); 
    if(m.a == null&&m.b==null&&m.c==null&&m.d==null&m.e==null&&m.f!=null&&m.g==null&&m.h==null&&m.i==null&&m.j==null) 
     query.append("f="+m.f); 
    if(m.a == null&&m.b==null&&m.c==null&&m.d==null&m.e==null&&m.f==null&&m.g!=null&&m.h==null&&m.i==null&&m.j==null) 
     query.append("g="+m.g); 
    if(m.a == null&&m.b==null&&m.c==null&&m.d==null&m.e==null&&m.f==null&&m.g==null&&m.h!=null&&m.i==null&&m.j==null) 
     query.append("h="+m.h); 
    if(m.a == null&&m.b==null&&m.c==null&&m.d==null&m.e==null&&m.f==null&&m.g==null&&m.h==null&&m.i!=null&&m.j==null) 
     query.append("i="+m.i); 
    if(m.a == null&&m.b==null&&m.c==null&&m.d==null&m.e==null&&m.f==null&&m.g==null&&m.h==null&&m.i==null&&m.j!=null) 
     query.append("j="+m.j); 
    if(m.a != null&&m.b!=null&&m.c==null&&m.d==null&m.e==null&&m.f==null&&m.g==null&&m.h==null&&m.i==null&&m.j==null) 
     query.append("a="+m.a);query.append(" b="+m.b); 
    if(m.a != null&&m.b==null&&m.c!=null&&m.d==null&m.e==null&&m.f==null&&m.g==null&&m.h==null&&m.i==null&&m.j==null) 
     query.append("a="+m.a);query.append(" c="+m.c); 
    if(m.a != null&&m.b==null&&m.c==null&&m.d!=null&m.e==null&&m.f==null&&m.g==null&&m.h==null&&m.i==null&&m.j==null) 
     query.append("a="+m.a);query.append(" d="+m.d); 
    // ... 512 lines in this pattern 
    return query.toString(); 

     return query.toString(); 
    } 
} 

我想以這樣的方式來寫public String build(Model m),這樣我就不必寫512的if-else條件。

條件:

  1. 模型類的所有實例變量可以有兩個值(NULL,NOT NULL)

  2. 他們都可以爲空或都可以不爲空。

  3. 會有512個組合(因爲每個實例變量具有兩個狀態,並且有9個實例變量所以條件總數將是2^9)的實例變量無關緊要的

  4. 訂單。

  5. 我的項目使用Java 6,所以我不能使用開關字符串。

我已經研究過各種模式,但沒有一個符合我的要求。

感謝您尋找

+0

我只是不明白爲什麼這是downvoted。 – Ashish

+0

我不明白你爲什麼需要超過九個條件。你能擴展你的例子嗎?也許顯示你預想的512條件解決方案的前十幾行。 – Kevin

+0

@凱文給我一分鐘,我會告訴你超過9 – Ashish

回答

3

的私人助手方法如下應該這樣做 -

private void appendIfNotNull(String fieldOp, String val) { 
    if(val != null) { 
     query.append(fieldOp).append(val); 
    } 
} 

然後,只需調用它在build方法 -

public String build(Model m) { 
    appendIfNotNull("a=", m.a); //no null check, just need to repeat this for all fields 
+0

非常感謝,這應該對我工作。 – Ashish

+0

不客氣。 –

1

也許你想嘗試使用Java反射來閱讀您的模型的所有領域並閱讀它們。你不需要知道字段名稱就可以閱讀它。因此,即使擴展了Model類,它也是完全動態和通用的。改編自

Class modelClass = Class.forName(Model.class.getName()); 
    Field[] fields = circleClass.getFields(); //includes all fields declared in you model class 
    for (Field f : fields) { 
     System.out.println("field " + f.getName() + " has value: " + f.get(<YOUR_MODEL_INSTANCE>)); 
    } 

示例代碼: - http://forgetfulprogrammer.wordpress.com/2011/06/13/java-reflection-class-getfields-and-class-getdeclaredfields/

+0

感謝您的建議,我會upvote,但我不喜歡使用反射,因爲它是有風險的 – Ashish

1

這段代碼纔有意義?

interface ToStringer { 
    void appendTo(StringBuilder sb); 
} 

class NullToStringer implements ToStringer { 
    public void appendTo(StringBuilder sb) { 
     // Do nothing 
    } 
} 

class IntegerToStringer implements ToStringer { 
    private String fieldName; 
    private Integer val; 
    public IntegerToStringer(String fieldName, Integer val) { 
     this.fieldName = fieldName; 
     this.val = val; 
    } 


    public void appendTo(StringBuilder sb) { 
     sb.append(field).append(" = ").append(val); 
    } 
} 

public class ToStringFactory { 
    public ToStringer getToStringer(String fieldName, Integer val) { 
     if (val == null) { 
      return new NullToStringer(); 
     } else { 
      return new IntegerToStringer(fieldName, val); 
     } 
    }  

    public ToStringer getToStringer(String fieldName, String val) { 
     ... 
    } 
} 

public String build(Model m){ 
    ArrayList<ToStringInstance> list = ...; 
    list.add(ToStringFactory.getToStringer("f", m.f)); 
    list.add(ToStringFactory.getToStringer("g", m.g)); 
    list.add(ToStringFactory.getToStringer("h", m.h)); 

    StringBuilder sb = ...; 

    for (ToStringInstance tsi : list) { 
     tsi.appendTo(sb); 
    } 

    return sb.toString(); 

} 

我不知道你想實現什麼邏輯,但一般的方法:創建界面,印刷值的具體implementaion,使用NullValue屬性模式隱藏空問題,並利用工廠來控制對象的創建應該做的招。

通過使用這種方法,您可以通過避免多個if-else語句來避免2^9組合出現問題。

更新。剛到我腦海。你可以使用反射。遍歷所有字段,獲取每個字段的值,如果不是null,則打印它。也許這就夠了。

0

我不知道爲什麼你需要兩個如果此聲明:

if(m.a == null) { 
    query.append("m=null"); 
} else { 
query.append("m="+m.a); 
} 
if(m.b == null) { 
    query.append("m=null"); 
} else { 
query.append("m="+m.b); 
} 
1

正如我在我的評論中提到,你不需要爲每一個組合不同if。你只需要附加非空的值,並忽略那些值。讓我知道這是否適合你。

public String build(Model m) { 
    // use this to know when to add " AND " to separate existing values 
    boolean appended = false; 

    if (m.a != null) { 
     query.append("a=" + m.a); 
     appended = true; 
    } 
    if (m.b != null) { 
     if (appended) { 
      query.append(" AND "); 
     } 
     query.append("b=" + m.b); 
     appended = true; 
    } 
    if (m.c != null) { 
     if (appended) { 
      query.append(" AND "); 
     } 
     query.append("c=" + m.c); 
     appended = true; 
    } 
    if (m.d != null) { 
     if (appended) { 
      query.append(" AND "); 
     } 
     query.append("d=" + m.d); 
     appended = true; 
    } 
    if (m.e != null) { 
     if (appended) { 
      query.append(" AND "); 
     } 
     query.append("e=" + m.e); 
     appended = true; 
    } 
    if (m.f != null) { 
     if (appended) { 
      query.append(" AND "); 
     } 
     query.append("f=" + m.f); 
     appended = true; 
    } 
    if (m.g != null) { 
     if (appended) { 
      query.append(" AND "); 
     } 
     query.append("g=" + m.g); 
     appended = true; 
    } 
    if (m.h != null) { 
     if (appended) { 
      query.append(" AND "); 
     } 
     query.append("h=" + m.h); 
     appended = true; 
    } 
    if (m.i != null) { 
     if (appended) { 
      query.append(" AND "); 
     } 
     query.append("i=" + m.i); 
     appended = true; 
    } 
    if (m.j != null) { 
     if (appended) { 
      query.append(" AND "); 
     } 
     query.append("j=" + m.j); 
     appended = true; 
    } 
    return query.toString(); 
} 
1

好像要追加到查詢不是null每個元素。

public class Service { 
    public StringBuilder query = null; 
    public Service(){ 
     query = new StringBuilder("Select * from A where "); 
    } 
    public String build(Model m) { 
     boolean added = first; 
     first &= !maybeAdd("a", m.a, first); 
     first &= !maybeAdd("b", m.b, first); 
     . . . // all the rest of the fields of m 
    } 

    /** 
    * Add an equality test to an SQL query if the value is not {@code null}. 
    * @param key the field name for the query 
    * @param value the value to test for equality 
    * @param first flag indicating that no conditions have been added 
    * @return {@code true} if the value was appended; {@code false} otherwise. 
    */  
    private boolean maybeAdd(String key, Object value, boolean first) { 
     if (value != null) { 
      if (!first) { 
       query.append(" AND "); 
      } 
      query.append(key).append('=').append(value); 
      return true; 
     } 
     return false; 
    } 
} 

注意,如果模型的所有領域都null,您的查詢將不能正確形成:這可以很簡單地用一個輔助方法或兩個來完成。您可能需要在maybeAdd方法中包含適當的邏輯來彌補這一點。

+0

感謝特德爲你的努力。 – Ashish