mercredi 20 septembre 2017

Abstract class with visitor - similar to typeOf

I am little confused how to avoid using casing in my manager method (last snippet of code) in terms of abstract class with it's derived classes (entities) and visitor design pattern eventually. Below I have an abstract class for entities called BaseEntity. It's not a real example, just pseudocode.

public abstract class BaseEntity {

    @Reference
    protected List<String> items = new ArrayList<>();

    public BaseEntity() {
    }

    public List<String> getItems() {
        return items;
    }

    public void setItems(List<String> items) {
        this.items = items;
    }
}

Below I have 3 derived classes from abstract class.

@Entity("CollectionA")
public class EntityA extends BaseEntity {
    //code
}

@Entity("CollectionB")
public class EntityB extends BaseEntity {
    //code
}

@Entity("CollectionC")
public class EntityC extends BaseEntity {
    //code
}

Then I created an visitor to reuse that in my manager to avoid using instanceOf.

public interface UpdateEntityVisitor {

    void create(EntityA entityA);

    void create(EntityB entityB);

    void create(EntityC entityC);
}

public class UpdateEntityVisitorImpl implements UpdateEntityVisitor {

    private final Factory factory;

    public UpdateEntityVisitorImpl() {
        factory = new FactoryImpl();
    }

    public UpdateEntityVisitorImpl(Factory factory) {
        this.factory = factory;
    }

    @Override
    public void create(EntityA entityA) {
        factory.getEntityA().create(entityA);
    }

    @Override
    public void create(EntityB entityB) {
        factory.getEntityB().create(entityB);
    }

    @Override
    public void create(EntityC entityC) {
        factory.getEntityC().create(entityC);
    }
}

And finally it's my manager class which has below method, where I would like to avoid casting down from BaseEntity to appropriate classes. There is a way to achieve that reusing above visitor class in manager ?

public void updateEntity(BaseEntity entity) {
    if (checkSmth()) {
        updateCollectionA((EntityA) entity);
    } else {
        updateCollectionB((EntityB) entity);
    }
}

I found this very useful library called typeOf http://ift.tt/1h0ikyM but I was wondering if there is other way to make it more clear to my current team.

Aucun commentaire:

Enregistrer un commentaire