Padrão de Design para implementar regras de negócios com centenas de if else em java

Tenho de aplicar certas regras de negócio com centenas de linhas abaixo do Código

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

temos algum padrão de design que possa efetivamente implementar isto ou reutilizar o código para que ele possa ser aplicado a todas as regras diferentes. Ouvi falar de Padrão de especificação que cria algo como abaixo

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

e,em seguida, a implementação de Is, e, ou métodos, mas eu acho que isso não pode me salvar escrevendo o caso contrário(pode ser meu entendimento é incorreto)...

Existe qualquer melhor abordagem para implementar tais regras de negócio com tantas declarações se mais?

editar: apenas um exemplo.A,B, C etc são propriedades de uma classe.Para além destes, existem muitas outras regras semelhantes.Vou fazer um código genérico para isto.

    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>
Author: BalusC, 2013-05-31

6 answers

O padrão de estratégia pode ser útil aqui. Verifique por favor Substituir a lógica condicional pela estratégia
 8
Author: vishal_aim, 2013-05-31 04:30:11

Você pode usar padrão de Comando ou padrão de Fábrica.

O Padrão de comandos pode ser usado para substituir os comutadores pesados / se os blocos que tendem a crescer indefinidamente à medida que adiciona novas opções.

public interface Command {
     void exec();
}

public class CommandA() implements Command {

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

Então constrói um objecto Map<String,Command> e preenche-o com instâncias de comando:

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

Depois pode substituir a sua cadeia if / else por:

commandMap.get(value).exec();

EmFábrica padrão Você inclui o seu if / switch numa fábrica que leva cuidado com a fealdade e esconde a abundância de se. exemplo de código para Padrão de fábrica .

 5
Author: fortytwo, 2013-05-31 04:45:13

Algo que pode ajudar é um motor de regras como Baba. Não é um padrão de design, então esta pode não ser a resposta que você está procurando. Mas IMO, devias considerar isso. Aqui está um grande artigo sobre Quando você deve usar um motor de Regras.

 1
Author: Daniel Kaplan, 2013-05-31 04:20:15

Um padrão de design pode ajudá-lo a tornar o código mais legível ou a melhorar a sua manutenção, mas se você realmente precisar de avaliar tais números de condições, as declarações IF não podem ser evitadas.

Eu consideraria ver o problema de outro ponto de vista (por exemplo: eu realmente preciso de cem declarações condicionais para resolver o problema?) and I would try to change or to improve the algorithm.

Uma linguagem de expressãopode ajudar. porque você poderia criar programaticamente uma cadeia que representa cada declaração IF e avaliar o resultado usando esta ferramenta, mas você ainda tem que resolver o problema relacionado com a execução da lógica particular associada a cada condição.

 1
Author: Gabriel Aramburu, 2017-05-23 12:34:24

Uma demonstração de estratégia simples com 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)
 1
Author: lancerex, 2015-02-02 09:01:32

Você deve verificar se as Regras Padrão de Design http://www.michael-whelan.net/rules-design-pattern/. Parece muito semelhante ao código de exemplo que você deu e consiste de uma base de interface que define um método para determinar se uma regra é satisfeita e, em seguida, várias implementações concretas por regras diferentes. Pelo que sei, a sua declaração de troca transformar-se-ia numa espécie de loop simples que apenas avalia as coisas até a sua composição de regras estar satisfeita ou falha.

interface IRule {
    bool isSatisfied(SomeThing thing);
}

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

class RuleA: IRule {
    ...
}

class RuleC: IRule {
    ...
}

Regras De Composição:

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);
}
Um método de serviço que governa uma coisa. classe SomeService { avaliação pública (regra da regra, coisa) ( Regra do regresso.isSatisfied (coisa); } }

Utilização:

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

var thing = new Thing();

new SomeService().evaluate(rule, thing);
Isto também foi respondido aqui: https://softwareengineering.stackexchange.com/questions/323018/business-rules-design-pattern
 0
Author: bingles, 2017-11-24 09:12:14