设计模式在java中使用数百个if else实现业务规则

SCo*_*der 22 java design-patterns if-statement specification-pattern

我必须使用数百行以下代码实现某些业务规则

if this
      then this
else if
      then this
.
. // hundreds of lines of rules
 else
      that
Run Code Online (Sandbox Code Playgroud)

我们是否有任何设计模式可以有效地实现这一点或重用代码,以便它可以应用于所有不同的规则.我听说过规范模式,它创建了类似下面的内容

public interface Specification {

boolean isSatisfiedBy(Object o);

Specification and(Specification specification);

Specification or(Specification specification);

Specification not(Specification specification);
}


public abstract class AbstractSpecification implements Specification {

public abstract boolean isSatisfiedBy(Object o);

public Specification and(final Specification specification) {
 return new AndSpecification(this, specification);
}

public Specification or(final Specification specification) {
 return new OrSpecification(this, specification);
}

 public Specification not(final Specification specification) {
 return new NotSpecification(specification);
}
}
Run Code Online (Sandbox Code Playgroud)

然后执行Is,And,或者方法,但我认为这不能救我写if if(可能是我的理解不正确)...

是否有任何最佳方法来实现具有如此多if else语句的业务规则?

编辑:只是一个示例示例.A,B,C等是类的属性.除此之外还有类似的其他规则.我想为此制作一个通用代码.

    If <A> = 'something' and <B> = ‘something’ then
    If <C> = ‘02’ and <D> <> ‘02’ and < E> <> ‘02’  then
        'something'
    Else if <H> <> ‘02’ and <I> = ‘02’ and <J> <> ‘02’  then
        'something'
    Else if <H> <> ‘02’ and <I> <> ‘02’ and <J> = ‘02’  then
        'something'
    Else if <H> <> ‘02’ and <I> = ‘02’ and <J> = ‘02’  then 
        'something'
    Else if <H> = ‘02’ and <I> = ‘02’ and <J> <> ‘02’  then 
        'something'
    Else if <H> = ‘02’ and <I> <> ‘02’ and <J> = ‘02’  then 
        'something'
    Else if <H> = ‘02’ and <I> = ‘02’ and <J> = ‘02’  then:
        If <Q> = Y then
            'something'
        Else then 
            'something'
Else :
Value of <Z>
Run Code Online (Sandbox Code Playgroud)

vis*_*aim 9

战略模式在这里很有用.请检查用策略替换条件逻辑


bin*_*les 8

您应该查看“规则设计模式” http://www.michael-whelan.net/rules-design-pattern/。它看起来与您提供的示例代码非常相似,并且包含一个基本接口,该基本接口定义了一种方法,该方法用于确定是否满足规则,然后确定每个不同规则的各种具体实现。据我了解,您的switch语句将变成某种简单的循环,仅对事物进行评估,直到您的规则组合得到满足或失败为止。

interface IRule {
    bool isSatisfied(SomeThing thing);
}

class RuleA: IRule {
    public bool isSatisfied(SomeThing thing) {
        ...
    }
}

class RuleB: IRule {
    ...
}

class RuleC: IRule {
    ...
}
Run Code Online (Sandbox Code Playgroud)

组成规则:

class OrRule: IRule {
    private readonly IRule[] rules;

    public OrRule(params IRule[] rules) {
        this.rules = rules;
    }

    public isSatisfied(thing: Thing) {
        return this.rules.Any(r => r.isSatisfied(thing));
    }
}

class AndRule: IRule {
    private readonly IRule[] rules;

    public AndRule(params IRule[] rules) {
        this.rules = rules;
    }

    public isSatisfied(thing: Thing) {
        return this.rules.All(r => r.isSatisfied(thing));
    }
}

// Helpers for AndRule / OrRule

static IRule and(params IRule[] rules) {
    return new AndRule(rules);
}

static IRule or(params IRule[] rules) {
    return new OrRule(rules);
}
Run Code Online (Sandbox Code Playgroud)

在事物上运行规则的一些服务方法:

class SomeService {
        public evaluate(IRule rule, Thing thing) {
            return rule.isSatisfied(thing);
        }
    }
Run Code Online (Sandbox Code Playgroud)

用法:

// Compose a tree of rules
var rule = 
    and (
        new Rule1(),
        or (
            new Rule2(),
            new Rule3()
        )
    );

var thing = new Thing();

new SomeService().evaluate(rule, thing);
Run Code Online (Sandbox Code Playgroud)

在这里也得到了回答:https : //softwareengineering.stackexchange.com/questions/323018/business-rules-design-pattern


for*_*two 6

您可以使用命令模式工厂模式.

命令模式可用于替换繁琐的开关/ if块,当您添加新选项时,这些块往往会无限增长.

public interface Command {
     void exec();
}

public class CommandA() implements Command {

     void exec() {
          // ... 
     }
}
// etc etc
Run Code Online (Sandbox Code Playgroud)

然后构建一个Map<String,Command>对象并使用Command实例填充它:

commandMap.put("A", new CommandA());
commandMap.put("B", new CommandB());
Run Code Online (Sandbox Code Playgroud)

然后你可以用以下代码替换你的if/else if链:

commandMap.get(value).exec();
Run Code Online (Sandbox Code Playgroud)

工厂模式中,您可以在工厂中包含if/switch,它可以处理丑陋并隐藏丰富的ifs. 工厂模式的示例代码.

  • 给予原始答案的学分:):/sf/ask/83975251/ (2认同)

Dan*_*lan 3

像Drools这样的规则引擎可能会有所帮助。但这不是一种设计模式,因此这可能不是您正在寻找的答案。但在我看来,你应该考虑一下。这是一篇关于何时应该使用规则引擎的精彩文章。