È buona norma masterizzare la logica di business in Enums?

5

Abbiamo una logica aziendale semplificata come questa:

public enum BusinessLogic {
   STAGE_ONE(true, false, false),
   STAGE_TWO(true, true, false),
   STAGE_THREE(false, false, true);

  private final Boolean canStartProcessing; 
  private final Boolean canDoStuff; 
  private final Boolean canFinish;

  private BusinessLogic(Boolean canStartProcessing, Boolean canDoStuff, Boolean canFinish){
     ... usual simple constructor
  }
  ... getters
}

Diciamo che è mappato al mio oggetto Business in questo modo:

public class BusinessObject {
  ... constructors, fields, getters, setters, etc...

  private BusinessLogic logic

  @Enumerated(EnumType.STRING)
  @Column(name = "LOGIC")
  public BusinessLogic getLogic(){...usual getter...} 

  public BusinessLogic setLogic(){...usual setter...}
}

Quando arriva il flusso di lavoro, ad esempio Fase 2, BusinessObject viene aggiornato e il campo LOGIC deve essere impostato su BusinessLogic.STAGE_TWO, quindi è possibile utilizzare funzioni come "avvio processo" e "fare cose", prima che non sia possibile "fai roba", anche se ha raggiunto la terza fase, non puoi fare altro, ma "finire" il processo.

Questo tipo di struttura della logica aziendale ha qualcosa a che fare con le buone pratiche? Intendo per esempio: manutenibilità, non completamente rappresentata nel Database o qualsiasi altra cosa a cui non avessi pensato?

    
posta CsBalazsHungary 28.01.2015 - 17:50
fonte

2 risposte

4

Uso enum s in questo modo sempre. Le enumerazioni sono un ottimo modo per scrivere oggetti helper immutabili di cui hai solo bisogno esattamente una copia; aiutano a ridurre la possibilità di perdite di memoria e raggruppano facilmente molte classi correlate in modo chiaro.

Quello che non farei è esporre il controllo di quale particolare% di% di conversione stai usando a classi esterne usando un metodo getter e setter BusinessLogic ; questo sta violando l'incapsulamento.

Sembra che il tuo caso d'uso usi il Pattern di stato , che è di grande utilità per le enumerazioni in Java. Tuttavia, rimuovendo la logica di transizione dello stato dalla classe, non puoi garantire che un altro codice cambierà lo stato quando non ti aspetti. Risolvi questo problema inserendo il codice di transizione stato nella classe public stessa, o almeno in un oggetto privato del pacchetto che inserisce nella classe BusinessObject .

    
risposta data 28.01.2015 - 19:54
fonte
3

Potrebbe essere una buona idea incapsulare il comportamento in un enum di Java (o in% dienum class) quando ti trovi a scrivere switch istruzioni come le seguenti, specialmente quando switch viene ripetuto in diverse parti di il codice.

MyEnum x = ...;
switch (x) {
  case A:
    // Do something
    break;
  case B:
    // Do something
    break;
  case C:
    // Do something
    break;
  default:
}

Potrebbe avere senso cambiarlo in:

public enum MyEnum {
  A {
    public void doAction() { ... }
  },
  B {
    public void doAction() { ... }
  },
  C {
    public void doAction() { ... }
  },
  public abstract void doAction();
}

Quindi, invece di un interruttore, fai questo:

MyEnum x = ...;
x.doAction();

In sostanza, stai estraendo un'istruzione switch utilizzando la spedizione dinamica.

Si noti che questo è un semplice esempio, il metodo enum può prendere parametri e restituire un valore. Questa è solo la struttura generale.

    
risposta data 28.01.2015 - 21:35
fonte

Leggi altre domande sui tag