简体   繁体   中英

EJB 3.1 Pattern for generating objects from a template

I am searching for a design pattern to generate objects from a template object. In my game i have different kind of items which will be generated out of a template object.

Currently i solved it by inheritance where each template entity implements the method:

   public Item generate(EntityManager em);

My inheritance structure is:

    ItemTemplate                  -> creates an Item
         |_ ArmorTemplate         -> creates and Armor
         |_ WeaponTemplate        -> creates an Weapon
         |_ ....and more ....

When i create a item i pass the entity manager to the template and i get a persisted object. Eg an ArmorTemplate returns me a persisted Armor and so on.

If the item generation needs any specific entities i have to do a lookup inside the generation method. I would like to solve it with a container based solution where i can inject my needed EJBs and do not have to pass my entity manager through the creation workflow.

From Hibernate i get a List of template objects and i do not want to do a instanceof to call the correct factory method.

My current solution works, but feels not very elegant. Any input would be fine. ;-)

Thanks in advance. greetings, m

It is not possible to inject EJBs into the template objects as long they are domain objects with Java EE:

Inject EJB into domain object with Java EE 6

It is possible with spring:

http://java.dzone.com/articles/domain-object-dependency-injection-with-spring

I would however probably try to split the template domain object from the object persiting part. (just for my understanding: the ArmorTemplate is some kind of armor and there are multiple different with varying attributes, each ArmorItem is one instance of exactly one ArmorTemplate and there can be multiple items for one template)

Here is a suggestion. The complicated generic part is to enable, that an ArmorItem can only by build by an ArmorTemplate and that you can access specific properties from this template without cast.

static abstract class Item<I extends Item<I, T>, T extends ItemTemplate<I, T>> {
    T template;
}
static abstract class ItemTemplate<I extends Item<I, T>, T extends ItemTemplate<I, T>> {
    abstract I createItem();
}

// JPA Domain Objects:
static class Armor extends Item<Armor, ArmorTemplate> {}
static class ArmorTemplate extends ItemTemplate<Armor, ArmorTemplate> {
    public final int hitpoints;

    public ArmorTemplate(int hitpoints) {
        this.hitpoints = hitpoints;
    }

    @Override
    Armor createItem() {
        return new Armor();
    }
}

// This POJO can be CDI managed
static class ItemDao {
    // @Inject public EntityManager em;

    public <I extends Item<I, T>, T extends ItemTemplate<I, T>> 
    List<I> createItemsFromTemplates(List<T> templates) {
        List<I> result = new ArrayList<I>();
        for (T template : templates) {
            I item = template.createItem();
            item.template = template;
            // em.persist(item);
            result.add(item);
        }
        return result;
    }
}

public static void main(String[] args) {
    List<ArmorTemplate> armorTemplates = Arrays.asList(
            new ArmorTemplate(100), new ArmorTemplate(80));

    List<Armor> armorItems = new ItemDao().createItemsFromTemplates(armorTemplates);

    for (Armor armor : armorItems) {
        System.out.println(armor.template.hitpoints);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM