使用Java和EclipseLink实现状态模式

时间:2015-05-20 18:48:08

标签: java design-patterns state

我想在java中为以下场景实现状态模式:

  • 整个故事都以EclipseLink

  • 为基础
  • Person的{​​{1}}(=安全级别)。

  • 根据以前SecurityState的人,操作SecurityState(可能还有其他操作)会有不同的行为。

人类

changeSecurityLevel

SecurityState:

@Entity
public class Person extends DatabaseObject{
    // .... lots of properties....
    @ManyToOne(fetch=FetchType.LAZY)
    private SecurityState securityState;

    public changeSecurityState(SecurityState newState){
       securityState.changeSecurityState(newState);
    }  

}

例如@Entity public abstract class SecurityState extends DatabaseObject{ private int level; // 1 = low, 2 = medium, 3 = high private Person person; public SecurityState(Person p){ this.person = p; } public changeSecurityState(SecurityState newState){ // not implemented } public void someOtherOperation(){ } // getter and setter }

HighSecurityState

问题: - 状态模式是或多或少正确实现的?我不喜欢if-else某种方式,这感觉不对。

  • 如何坚持SecurityState?应该保留哪个类/表,抽象@Entity public class HighSecurityState extends SecurityState { private int level = 3; public changeSecurityState(SecurityState newState){ if(newState.getLevel() == 1){ // do specific stuff for High-to-Low status changes person.securityState = new LowSecurityState(); }else if(newState.getLevel() == 2){ person.securityState = new MediumSecurityState(); }else{ } } } ?还是具体的州级?

1 个答案:

答案 0 :(得分:0)

对这些简单的案件不要担心if-else;没关系。

也许switch看起来好一点 - 但它本质上是一样的

switch(newState.getLevel())
    case 1:
             ...
    case ...

    default: throw new AssertionError();

或者你甚至可以申请访客模式 - 它真的值得吗?

public changeSecurityState(LowSecurityState newState)
...    
public changeSecurityState(MediumSecurityState newState)
...    
public changeSecurityState(HighSecurityState newState)
...

关于第二个问题 - 安全状态只是一个简单的int;你不需要一个单独的桌子;它应该只是person表中的整数列。如果您愿意,可以将其设为Java中的enum类型。