hibernate - сохранение интерфейса композиции шаблона стратегии - PullRequest
0 голосов
/ 02 июля 2018

У меня следующая структура класса:

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

Моя цель - сохранить объекты Существа за одной таблицей в базе данных. Подклассы SkillInterface без полей. Поскольку они определяют поведение, я хочу преобразовать выбранное имя класса SkillInterface в строку, так как мне нужно только сохранить имя класса текущей стратегии навыка существа со строкой, подобной skill.getClass (). GetSimpleName (). Я пытался реализовать это с помощью аннотации @Converter, используя класс AttributeConverter для преобразования SkillInterface в String и сохранения, но всегда были исключения из сопоставления. Я хочу иметь возможность сохранить его как строку и получить как объект SkillInterface.

Но как я могу реализовать это с Hibernate? Или у меня ошибка дизайна?

Ответы [ 2 ]

0 голосов
/ 03 июля 2018

Хорошо, похоже, я нашел базовое решение, которое можно использовать для сохранения реализаций интерфейсов Strategy Pattern. Я использовал аннотацию @Converter и класс AttributeConverter для преобразования имен классов стратегии в столбец при сохранении в базу данных и преобразования полученной строки обратно в класс стратегии следующим образом:

@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
    }
}
0 голосов
/ 03 июля 2018

Вы можете использовать для этого поле прокси, как показано ниже:

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
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...