状态模式:状态为Hibernate单例实体

时间:2013-11-20 08:49:02

标签: java spring hibernate design-patterns

我拥有的是什么:
我已经实现了一个`State Pattern。现在我的应用程序中有十几个状态,所有这些都是Spring的bean,比如:

@Service(value = "FinishedState")
@Scope("singleton")
public class FinishedState extends AbstractState {    
  private final String stateName = "Finished";
  private final String badgeColor = "#459852";

  //implementation of state API
}

我想要的是什么:
能够更改stateNamebadgeColor而无需重新编译我的应用程序。或者换句话说,我想将我的状态存储在DB中。

真是个问题:

  1. 将所有州作为Singleton实体是否是个好主意?
  2. 我可能面临哪些困难?
  3. 意味着我将手动为每个状态设置一个id,如id = this.getClass().getSimpleName(),并将所有状态兄弟映射到一个表中。


    编辑(适用于@Adam Arold):

    还值得一提的是,我需要其他实体可以引用该单身人士的状态

    @Service(value = "FinishedState ")
    @Scope("singleton")
    public class FinishedState extends AbstractState {
      private final String stateName = "Finished";
      private final String badgeColor = "#459852";
    
      @Override
      public void someMethod1(Session session, String newState, MyEntity entity) {
           entity.setStatus(newState);
           writeHistory(entity);
      }
    
      @Override
      protected boolean someMethod2(Session session, AbstractState newState, MyEntity entity) 
      {
          return true;
      }
    }
    

2 个答案:

答案 0 :(得分:0)

我唯一一次建立自己的州单身就是我经常改变状态的时候。当性能至关重要时,这很有用 - 如果我不希望每次从状态切换来回调用new

<强>建议

我建议你分析:

  • 您的系统如何运作状态?
  • 你经常改变状态吗?
  • 你是否可以在内存中拥有一堆实例 系统执行期间的状态是否存在?

我看到你遇到的唯一问题是,当你的系统运行时,Singleton状态将一直存在,直到系统完成。

个人 我会让他们成为单身人士

答案 1 :(得分:0)

我结束了:

@MappedSuperclass
@Inheritance(strategy= InheritanceType.SINGLE_TABLE)
@Table(name = "state")
public class StateBase {

    /**
     * Entity API
     */
    @Id
    @Column(name = "id")
    private String id = this.getClass().getSimpleName(); //prevent from creating two instances of state

    @Column(name = "name")
    private String name;

    @Column(name = "badgeColor")
    private String badgeColor;

    //only Getters! also hashCode and Equals
    //.....................

    /**
     * ======== State API ========
     * Use TEMPLATE METHOD and hooks
     */
    final public void changeState(Session session, State newState, StateEntity entity) { //StateEntity is interface that is implemented by all entities that have a state
        if(newState.equals(this)) return;

        if (canMove(session, newState, entity)) {
            hook(session, newState, entity);
            beforeTransition(session, newState, entity);
            makeTransition(session, newState, entity);
            afterTransition(session, newState, entity);
        } else {
            throw new TransitionDeniedException("Transition from " + getName() + " to " + newState.getName() + " is denied.");
        }
    }

    //Defauls implementation for all (or almost all hooks)
    protected void beforeTransition(Session session, State newState, StateEntity entity) {
        entity.setState(newState);
    }

    protected void afterTransition(Session session, State newState, StateEntity entity) {
        writeHistory(entity);
       session.merge(entity);
    }
    //..........................
}

而不是:

@Entity
public class SpecificState extends StateBase {

    //Override hook
    @Override
    public void makeTransition(Session session, State newState, StateEntity entity) {
        MyEntity myEntity = (MyEntity ) entity;
        String commentText = "some comment";
        String author = "[autogenerated]";
        addProfileComment(session, myEntity, commentText, author);
    }
}

由于我的实现,所有状态都是entites,但它们只有没有Setter的私有String字段。所以他们没有可变状态。因此,如果存在一个或多个特定状态的实体(在内存中),则无关紧要。在DB中,我只能同时存储一个特定状态类的实体。

优点

  1. 这让我忘记了状态同步的麻烦以及与用Hibernate实体替换Spring单例bean相关的另一个可能的困难。
  2. 它还允许用户通过管理工具更改namebadgeColor,而无需重新编译整个应用程序。
  3. 缺点:

    没有观察到。