Java 如何避免多种情况下的多种if-else

Java 如何避免多种情况下的多种if-else,java,algorithm,jakarta-ee,Java,Algorithm,Jakarta Ee,我需要一些帮助来设计问题的逻辑 模型豆 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 = nu

我需要一些帮助来设计问题的逻辑

模型豆

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();
    }
}
我想以这样的方式编写
公共字符串构建(modelm)
,这样我就不必在其他条件下编写512

条件:

  • 模型类的所有实例变量都可以有两个值(null,非null)

  • 它们都可以为null,也可以都不为null

  • 总共有512个组合(因为每个实例变量有两个状态,并且有9个实例变量,所以条件的总数为2^9)

  • 实例变量的顺序并不重要

  • 我的项目使用Java6,所以我不能使用字符串上的开关

  • 我研究过各种模式,但没有一种符合我的要求


    感谢您查找

    私人助手方法,如下所示-

    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反射读取模型的所有字段并读取它们。您不需要知道字段名就可以读取它。因此,它将是完全动态和通用的,即使您扩展了模型类

        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>));
        }
    
    classmodelclass=Class.forName(Model.Class.getName());
    Field[]fields=circleClass.getFields()//包括模型类中声明的所有字段
    用于(字段f:字段){
    System.out.println(“字段”+f.getName()+”的值为:“+f.get());
    }
    
    示例代码改编自:
    -这段代码有意义吗

    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();
    
    }
    
    与字符串器的接口{
    (b)无效;
    }
    类NullToString实现ToString{
    公共无效附件(StringBuilder sb){
    //无所事事
    }
    }
    类IntegerToStringer实现ToString{
    私有字符串字段名;
    私有整数val;
    公共IntegerToStringer(字符串字段名,整数值){
    this.fieldName=字段名;
    this.val=val;
    }
    公共无效附件(StringBuilder sb){
    sb.append(字段)。append(“=”)。append(val);
    }
    }
    公共类ToStringFactory{
    公共ToString getToStringer(字符串字段名,整数val){
    if(val==null){
    返回新的NullToString();
    }否则{
    返回新的IntegerToStringer(字段名,val);
    }
    }       
    公共ToString getToStringer(字符串字段名,字符串值){
    ...
    }
    }
    公共字符串生成(模型m){
    ArrayList=。。。;
    添加(ToStringFactory.getToStringer(“f”,m.f));
    添加(ToStringFactory.getToStringer(“g”,m.g));
    添加(ToStringFactory.getToStringer(“h”,m.h));
    StringBuilder sb=。。。;
    用于(ToString实例tsi:list){
    (某人);;
    }
    使某人返回字符串();
    }
    
    我不确定您试图实现什么逻辑,但一般的方法是:创建接口、打印值的具体实现、使用NullValue模式隐藏null问题以及使用factory控制对象创建

    通过使用这种方法,您可以通过避免多个if-else语句来避免2^9组合出现问题


    更新。我刚想起。你可以使用反射。遍历所有字段,获取每个字段的值,如果不为空,则打印它。也许这就足够了。

    我不知道为什么您需要两个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);
    }
    

    正如我在评论中提到的,您不需要为每个组合使用不同的
    if
    。您只需要附加不为null的值,并忽略为null的值。让我知道这是否适合你

    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
    方法中包含适当的逻辑来补偿这一点。

    我不明白为什么这会被否决。我不明白为什么您需要九个以上的条件。你能进一步扩展你的例子吗?也许可以展示你设想的512条件解决方案的前十几行。@Kevin给我一分钟,我将向你展示超过9行内容。我同意Kevin的观点。你对每一个组合都做了不同的事情吗?事实上,如果(m.a!=null){//do something}其他{//something}如果(m.b!=null){//do something}其他{//do something}您似乎只需要执行
    ,如果(m.b!=null){//do something for b}其他{…
    这个问题似乎离题了,因为它似乎是一个巨魔。谢谢你的建议,我将继续投票,但我不喜欢使用反射,因为它有可能让你的努力失败。