5

Let's have a simplified business logic like this:

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
}

And let's say it is mapped to my Business Object like this:

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

When the workflow arrives for example Stage two, the BusinessObject will be updated and LOGIC field should be set to BusinessLogic.STAGE_TWO, therefore you can use functions like "start process" and "do stuff", before that you can't "do stuff", altough when it reached stage three, you can't do anything else, but "finish" the process.

Does this kind of business logic structure has something to do against good practice?
I mean for example: maintainability, not fully represented in Database or anything else I didn't think of?

6
  • What is the actual purpose of this? To instantiate an enum with a value corresponding to some predetermined stage in a business process? Why? Jan 28, 2015 at 17:06
  • @RobertHarvey For example to allow/disallow certain operates on business objects by simply using businessObject.getLogic().isCanDoStuff(), and it looks comfortable to switch these booleans on one place if the client wants change in workflow. I see this "pattern" here where I work. I decided to ask around if it has some setbacks. Jan 28, 2015 at 17:09
  • Seems sensible to me, but since I'm seeing your enum out of context with the rest of your application, it's hard to tell. Jan 28, 2015 at 17:41
  • Don't call a class BusinessLogic if instances of it aren't business logics. Is STAGE_ONE "a business logic"? Is STAGE_TWO? Is STAGE_THREE?
    – user253751
    Jan 28, 2015 at 18:24
  • @immibis it serves only the purpose of example, might be imperfect, so please feel free to suggest edit. Jan 28, 2015 at 18:45

2 Answers 2

4

I use enums this way all the time. Enums are a great way to write immutable helper objects that you only need exactly one copy of; they help reduce the chance of memory leaks and easily group many related classes together in a clear way.

What I would not do is expose the control of which particular BusinessLogic you're using to external classes using a public getter and setter method; that is violating encapsulation.

It looks like your use case uses the State Pattern, which is a great use for enums in Java. However, by removing the state transition logic from the class, you can't guarantee that other code will change the state when you don't expect. Fix this by having the state transition code inside the BusinessObject class itself, or at least in a package private object that you inject into the BusinessObject class.

4

It may be a good idea to encapsulate behavior into a Java enum (or C++ enum class) when you find yourself writing switch statements like the following, especially when the switch is repeated in different parts of the code.

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

It may make sense to change it to the following:

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

Then instead of a switch, you do this:

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

Essentially, you are abstracting a switch statement using dynamic dispatch instead.

Note that this is a simple example, the enum method may take parameters and return a value. This is only the general structure.

2
  • Interestingly I didn't think of putting abstract method into enum, but makes sense. Jan 29, 2015 at 8:22
  • It sounds a little counter-intuitive because in Java, enums are final and cannot be extended... except by anonymous classes defined in the enumeration instance list.
    – user22815
    Jan 29, 2015 at 15:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.