Шаблон проектирования для реализации бизнес-правил с сотнями если еще в Java

Я должен реализовать определенные бизнес-правила с сотнями строк кода ниже

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

Есть ли у нас какой-либо шаблон проектирования, который может эффективно реализовать это или повторно использовать код, чтобы его можно было применять ко всем различным правилам. Я слышал о Specification Pattern, который создает что-то вроде ниже

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 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>

6 ответов

Вам следует ознакомиться с шаблоном разработки правил http://www.michael-whelan.net/rules-design-pattern/. Он выглядит очень похоже на пример кода, который вы дали, и состоит из базового интерфейса, который определяет метод для определения, выполняется ли правило, а затем различные конкретные реализации для различных правил. Насколько я понимаю, ваш оператор switch может превратиться в некий простой цикл, который просто оценивает вещи до тех пор, пока ваш набор правил не будет удовлетворен или не сработает.

interface IRule {
    bool isSatisfied(SomeThing thing);
}

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

class RuleA: 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 {публичная оценка (правило IRule, 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

Шаблон стратегии может быть полезен здесь. Пожалуйста, отметьте " Заменить условную логику на стратегию"

Вы можете использовать шаблон команды или шаблон фабрики.

Шаблон команды может использоваться для замены громоздких блоков switch/if, которые имеют тенденцию расти бесконечно по мере добавления новых опций.

public interface Command {
     void exec();
}

public class CommandA() implements Command {

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

затем построить Map<String,Command> возьмите объект и заполните его экземплярами Command:

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

тогда вы можете заменить вашу цепочку if/else if на:

commandMap.get(value).exec();

В Factory Pattern вы включаете свой if/switch в Factory, который заботится о безобразии и скрывает изобилие ifs. Пример кода для Factory Pattern.

Что-то, что может помочь, - это механизм правил, такой как Drools. Это не шаблон дизайна, поэтому, возможно, это не тот ответ, который вы ищете. Но ИМО, вы должны рассмотреть это. Вот отличная статья о том, когда вы должны использовать механизм правил.

Простая демоверсия стратегии с 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)

Шаблон проектирования может помочь вам сделать код более читабельным или улучшить его удобство сопровождения, но если вам действительно необходимо оценить такое количество условий, операторов IF нельзя избежать.

Я хотел бы рассмотреть проблему с другой точки зрения (например: действительно ли мне нужно сто условных выражений для решения проблемы?), И я бы попытался изменить или улучшить алгоритм.

Язык выражений может оказать некоторую помощь, поскольку вы можете программно создать строку, представляющую каждый оператор IF, и оценить результат с помощью этого инструмента, но вам все равно придется решить проблему, связанную с выполнением конкретной логики, связанной с каждым условием.

Другие вопросы по тегам