首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >状态模式:状态作为Hibernate单例实体

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

Stack Overflow用户
提问于 2013-11-20 08:49:02
回答 2查看 1.1K关注 0票数 1

我拥有的:

我已经暗示了一个‘国家模式’。现在我的应用程序里有十几个州,它们都是Spring的豆子,就像:

代码语言:javascript
复制
@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. 让所有国家都成为单一实体是个好主意吗?
  2. 我能面对什么困难?

这意味着我将手动为每个州设置一个id,如id = this.getClass().getSimpleName(),并将所有状态兄弟关系映射到一个表中。

编辑(@ Arold):

同样值得说的是,我需要其他实体可以引用辛格尔顿的状态。

代码语言:javascript
复制
@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;
  }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-11-27 08:58:08

我的结尾是:

代码语言:javascript
复制
@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);
    }
    //..........................
}

超过:

代码语言:javascript
复制
@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);
    }
}

由于我的实现,所有的状态都是实体,但是它们只有私有字符串字段而没有Setters。所以他们没有不可改变的状态。因此,如果可以存在一个或多个特定状态的实体(在内存中),那就不太现实了。在DB中,我只能同时存储特定状态类的一个实体。

优势

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

缺点:

没有被注意到。

票数 0
EN

Stack Overflow用户

发布于 2013-11-25 12:25:36

唯一一次我使我的国家单身是当我是经常改变状态。在性能必不可少的情况下,这是有用的--如果我不希望每次从状态来回切换时都调用new

建议

我对你的建议是:

  • 你的系统在美国是如何运作的?
  • 你经常更换状态吗?
  • 您是否有足够的空间来记忆在系统执行过程中存在的一组状态实例?

我看到的唯一问题是,当您的系统运行时,Singleton状态将一直存在,直到系统结束。

就个人而言,,我会通过使他们成为单身汉

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20091168

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档