É uma boa prática gravar lógica de negócios no Enums?

5

Vamos ter uma lógica de negócios simplificada como esta:

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
}

E digamos que ele esteja mapeado para meu Objeto de Negócios da seguinte forma:

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 o fluxo de trabalho chegar, por exemplo, no Estágio dois, o BusinessObject será atualizado e o campo LOGIC deverá ser definido como BusinessLogic.STAGE_TWO, portanto, você poderá usar funções como "iniciar processo" e "fazer coisas", antes disso "fazer coisas", mesmo quando chegou ao terceiro estágio, você não pode fazer mais nada, mas "terminar" o processo.

Esse tipo de estrutura lógica de negócios tem algo a ver com as boas práticas?
Quero dizer, por exemplo: manutenção, não totalmente representada no banco de dados ou qualquer outra coisa que eu não pensava?

    
por CsBalazsHungary 28.01.2015 / 17:50
fonte

2 respostas

4

Eu uso enum s dessa maneira o tempo todo. As enums são uma ótima maneira de escrever objetos auxiliares imutáveis dos quais você precisa apenas de uma cópia; eles ajudam a reduzir as chances de vazamentos de memória e agrupam facilmente muitas classes relacionadas de maneira clara.

O que eu não faria é expor o controle de qual BusinessLogic específico você está usando para classes externas usando um método public getter and setter; que está violando o encapsulamento.

Parece que seu caso de uso usa o Padrão de estado , que é um ótimo uso para enums em Java. No entanto, removendo a lógica de transição de estado da classe, você não pode garantir que outro código alterará o estado quando você não espera. Corrija isso tendo o código de transição de estado dentro da própria classe BusinessObject , ou pelo menos em um objeto privado do pacote que você injete na classe BusinessObject .

    
por 28.01.2015 / 19:54
fonte
3

Pode ser uma boa ideia encapsular o comportamento em um Java enum (ou C ++ enum class ) quando você estiver escrevendo instruções switch como as seguintes, especialmente quando o switch é repetido em diferentes partes do o código.

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

Pode fazer sentido alterá-lo para o seguinte:

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

Então, em vez de um switch, você faz isso:

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

Essencialmente, você está abstraindo uma instrução switch usando o despacho dinâmico.

Observe que este é um exemplo simples, o método enum pode receber parâmetros e retornar um valor. Esta é apenas a estrutura geral.

    
por 28.01.2015 / 21:35
fonte