簡體   English   中英

hibernate - 堅持策略模式的組合接口

[英]hibernate - Persisting a composition interface of strategy pattern

我有以下類結構:

public abstract class Creature{
   private String name;
   //strategy pattern composition
   private SkillInterface skill;
}

public interface SkillInterface {
   void attack();
}

public class NoSkill implements SkillInterface {
   @Override
   public void attack() {
       //statements
   }
}

我的目標是將Creature對象持久保存在數據庫中的一個表中。 SkillInterface的子類沒有任何字段。 當他們確定行為時,我想將選定的SkillInterface類名轉換為String,因為我只需要保持生物當前技能策略的類名,使用像skill.getClass()。getSimpleName()這樣的字符串。 我嘗試用@Converter注釋實現它,使用AttributeConverter類將SkillInterface轉換為String並保存,但始終有映射異常。 我希望能夠將其保存為String並檢索為SkillInterface對象。

但是如何用Hibernate實現呢? 或者我有設計錯誤?

好吧,我發現我已經找到了一個可用於持久化策略模式接口實現的基本解決方案。 我使用@Converter注釋和AttributeConverter類將策略類名轉換為列,同時保存到數據庫並將檢索到的String轉換回策略類,如下所示:

@Entity
public class Creature {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    @Convert(converter = SkillConverter.class)
    private SkillInterface skill;
}

public class SkillConverter implements AttributeConverter<SkillInterface,String> {
    @Override
    public String convertToDatabaseColumn(SkillInterface skill) {
        return skill.getClass().getSimpleName().toLowerCase();
    }

    @Override
    public SkillInterface convertToEntityAttribute(String dbData) {
        //works as a factory
        if (dbData.equals("noskill")) {
            return new NoSkill();
        } else if (dbData.equals("axe")) {
            return new Axe();
        }
        return null;
    }
}

public interface SkillInterface {
    public String getSkill();

    void attack();
}


public class NoSkill implements SkillInterface{
    public String getSkill() {
        return getClass().getSimpleName();
    }

    @Override
    public void attack() {
        //strategy statements
    }
}

您可以在下面使用代理字段:

abstract class Creature {
    @Column
    private String name;
    // strategy pattern composition
    private SkillInterface skill;

    @Column
    private String skillName;

    public String getSkillName() {
        return skill.getClass().getSimpleName();
    }

    public void setSkillName(String skillName) {
        //ignore
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM