Modèle de conception pour implémenter des règles métier avec des centaines de if else en java


Je dois implémenter certaines règles métier avec des centaines de lignes de code ci-dessous

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

Avons-nous un modèle de conception qui peut implémenter efficacement cela ou réutiliser le code afin qu'il puisse être appliqué à toutes les règles différentes. J'ai entendu parler de modèle de spécification qui crée quelque chose comme ci-dessous

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

Et puis l'implémentation des méthodes Is,And, Or mais je pense que cela ne peut pas m'empêcher d'écrire le if else(ma compréhension est peut-être incorrecte)...

Y a-t-il la meilleure approche pour mettre en œuvre de telles règles métier ayant tant de déclarations sinon?

EDIT : Juste un exemple d'exemple.A, B, C, etc. sont des propriétés d'une classe.En dehors de ceux-ci, il y a beaucoup d'autres règles similaires.Je wnat pour faire un code générique pour cela.

    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

Le modèle de stratégie pourrait être utile ici. Veuillez vérifier Remplacer la logique conditionnelle par la stratégie

 8
Author: vishal_aim, 2013-05-31 04:30:11

Vous pouvez utiliser modèle de Commande ou modèle de Fabrique.

Le modèle de commande peut être utilisé pour remplacer les blocs switch/if encombrants qui ont tendance à croître indéfiniment à mesure que vous ajoutez de nouvelles options.

public interface Command {
     void exec();
}

public class CommandA() implements Command {

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

Puis construisez un objet Map<String,Command> et remplissez-le avec des instances de commande:

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

Ensuite, vous pouvez remplacer votre chaîne if / else if par:

commandMap.get(value).exec();

Dans Usine Modèle vous d'inclure votre si/commutateur dans une Usine qui prend soin de la laideur et cache l'abondance defs. Exemple de code pour le modèle d'usine .

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

Quelque Chose qui peut aider est un moteur de règles comme Bave. Ce n'est pas un modèle de conception, donc ce n'est peut-être pas la réponse que vous recherchez. Mais OMI, vous devriez le considérer. Voici un excellent article sur lorsque vous devez utiliser un moteur de règles.

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

Un modèle de conception pourrait vous aider à rendre le code plus lisible ou à améliorer sa maintenabilité, mais si vous avez vraiment besoin d'évaluer un tel nombre de conditions, les instructions IF ne peuvent pas être évitées.

J'envisagerais de voir le problème d'un autre point de vue (par exemple: ai-je vraiment besoin de cent instructions conditionnelles pour résoudre le problème?) et j'essaierais de changer ou d'améliorer l'algorithme .

Un langage d'expression pourrait fournir une aide parce que vous pouvez créer par programme une chaîne qui représente chaque instruction IF et évaluer le résultat à l'aide de cet outil, mais vous devez toujours résoudre le problème lié à l'exécution de la logique particulière associée à chaque condition.

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

Une démonstration de stratégie simple avec 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

Vous devriez vérifier le modèle de conception de règles http://www.michael-whelan.net/rules-design-pattern / . Il ressemble beaucoup à l'exemple de code que vous avez donné et se compose d'une interface de base qui définit une méthode pour déterminer si une règle est satisfaite, puis diverses implémentations concrètes par différentes règles. Si je comprends bien, votre instruction switch se transformerait en une sorte de boucle simple qui évalue simplement les choses jusqu'à ce que votre composition de règles soit satisfaite ou échouer.

interface IRule {
    bool isSatisfied(SomeThing thing);
}

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

class RuleA: IRule {
    ...
}

class RuleC: IRule {
    ...
}

Règles de composition:

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

Une méthode de service qui exécute une règle sur une chose. classe SomeService { public évaluer (règle IRule, Chose chose) { retour à la règle.isSatisfied (chose); } }

Utilisation:

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

var thing = new Thing();

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

Cela a également été répondu ici: https://softwareengineering.stackexchange.com/questions/323018/business-rules-design-pattern

 0
Author: bingles, 2017-11-24 09:12:14