【问题标题】:Design Pattern to implement Business Rules with hundreds of if else in java在 java 中使用数百个 if else 实现业务规则的设计模式
【发布时间】:2013-05-31 04:15:47
【问题描述】:

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

if this
      then this
else if
      then this
.
. // hundreds of lines of rules
 else
      that

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

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

然后是 Is,And, Or 方法的实现,但我认为这不能节省我编写 if else 的时间(可能是我的理解不正确)...

是否有任何最佳方法来实现具有如此多 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>

【问题讨论】:

标签: java if-statement design-patterns specification-pattern


【解决方案1】:

您应该查看规则设计模式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 {
    ...
}

作曲规则:

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

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

class SomeService {
        public evaluate(IRule rule, Thing thing) {
            return rule.isSatisfied(thing);
        }
    }

用法:

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

var thing = new Thing();

new SomeService().evaluate(rule, thing);

这里也有回答:https://softwareengineering.stackexchange.com/questions/323018/business-rules-design-pattern

【讨论】:

【解决方案2】:

策略模式在这里可能很有用。请查看Replace Conditional Logic with Strategy

【讨论】:

  • 它可能不符合我的要求。我已经编辑了我的问题以包含一个条件逻辑示例。我对规则一的类的某些属性和其他一些属性有条件逻辑(可能包括规则一中使用的一些属性)用于规则二
【解决方案3】:

您可以使用Command patternFactory pattern

命令模式可用于替换繁琐的 switch/if 块,这些块会随着您添加新选项而无限增长。

public interface Command {
     void exec();
}

public class CommandA() implements Command {

     void exec() {
          // ... 
     }
}
// etc etc

然后构建一个 Map&lt;String,Command&gt; 对象并使用 Command 实例填充它:

commandMap.put("A", new CommandA());
commandMap.put("B", new CommandB());

那么您可以将 if/else if 链替换为:

commandMap.get(value).exec();

工厂模式中,您将 if/switch 包含在工厂中,该工厂负责处理丑陋并隐藏大量 ifs。 Example code for Factory Pattern.

【讨论】:

  • 感谢您的信息。您能否提供一些示例示例,这些模式可以帮助减少 if/else 。
  • 看起来是一个很好的例子,但可能不符合我的要求。我已经编辑了我的问题以包含一个条件逻辑示例。我对规则一和一些类的某些属性有条件逻辑规则二的其他属性(可能包括规则一中使用的一些属性)。
【解决方案4】:

Drools 这样的规则引擎可能会有所帮助。虽然这不是一种设计模式,所以这可能不是您正在寻找的答案。但是IMO,您应该考虑一下。这是一篇关于 when you should use a rules engine 的精彩文章。

【讨论】:

  • 谢谢,但我的要求是不使用任何规则引擎,项目原因:(,所以我正在寻找一些设计模式
  • 同意 tieTYT。规则引擎是实现 BR 的理想选择。以我个人的经验,它生成的代码超级干净且易于维护。并将开发时间缩短了几个数量级。
【解决方案5】:

设计模式可以帮助您使代码更具可读性或提高其可维护性,但如果您确实需要评估如此多的条件,则无法避免使用 IF 语句。

我会考虑从其他角度看待问题(例如:我真的需要一百个条件语句来解决问题吗?)我会尝试改变或改进algorithm.

Expression Language 可以提供一些帮助,因为您可以通过编程方式创建一个表示每个 IF 语句的字符串并使用此工具评估结果,但您仍然必须解决与执行相关的特定逻辑相关的问题每个条件。

【讨论】:

    【解决方案6】:

    一个简单的python策略演示:

    class Context(object):
      def __init__(self, strategy):
        self.strategy = strategy
    
      def execute(self, num1, num2):
        return self.strategy(num1, num2)
    
    class OperationAdd(object):
      def __call__(self, num1, num2):
        return num1 + num2
    
    
    class OperationSub(object):
      def __call__(self, num1, num2):
        return num1 - num2
    
    
    if __name__ == '__main__':
      con = Context(OperationAdd())
      print "10 + 5 =", con.execute(10, 5)
    
      con = Context(OperationSub())
      print "10 - 5 =", con.execute(10, 5)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-07
      • 1970-01-01
      • 1970-01-01
      • 2017-08-23
      • 1970-01-01
      • 2011-06-27
      • 1970-01-01
      • 2019-11-04
      相关资源
      最近更新 更多