簡體   English   中英

如何避免許多if-else有很多條件

[英]How to avoid many if-else with many condition

在設計問題的邏輯時,我需要一些幫助。

模型豆

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. Model類的所有實例變量都可以有兩個值(null,不為null)

  2. 它們都可以為null或者它們都不能為空。

  3. 總共有512種組合(因為每個實例變量都有兩個狀態,並且有9個實例變量,所以條件的總數將是2 ^ 9)

  4. 實例變量的順序無關緊要。

  5. 我的項目使用Java 6,所以我不能在String上使用switch。

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

謝謝你的期待

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

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

也許您想嘗試使用Java Reflection來讀取模型的所有字段並閱讀它們。 您無需知道字段名稱即可閱讀。 因此,即使您擴展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/

這段代碼有意義嗎?

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();

}

我不確定你想要實現什么邏輯,但一般方法:創建接口,打印值的具體實現,使用NullValue模式隱藏空問題和使用工廠來控制對象創建應該可以解決問題。

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

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

正如我在我的評論中提到,你並不需要一個不同的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();
}

看起來您想要為每個非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方法中包含適當的邏輯來補償它。

我不知道為什么你需要兩個if語句:

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);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM