lundi 10 avril 2017

Design pattern for calling specific classes that override an especific method

So I am having a bit of a problem when trying make a class that can be appended subclasses with different functionalities and share a common ancestor without having really big hierarchy trees.

What I am trying to do is make n different sub classes of the Skill interface which are allocated in a list and then called to be execute. All the in Skill are sublclasses of Event (not here).

My problem resides in SkillManager that takes an Event object, determine which class it holds and then call all clases and the ones that are overriden and not empty get executed.

Is this an effective way to do it or is there a pattern design to optimize it? I heard that Strategy Pattern might work but I wouldn't know how to make it fit in here

This is my Skill.class interface

public abstract class Skill
{
    /**
     * Returns the name of this skills, this should also be the same
     * name of the class implementing this interface for initialization
     * propouses
     * @return name of skills
     */
    public abstract String getName();


    /**
     * This method gets called if implemented by a skill
     * and returns a EntityDamageEntityEvent and a few
     * usefull object for handling it
     * @param player attacker
     * @param event event involved
     */
    public void onAttack(DPlayer player, EntityDamageByEntityEvent event){}

    /**
     * This method gets called if implemented by a skill
     * and returns BlockBreakEvent and a few usefull
     * objects
     * @param dp player who broke the block
     * @param event event involved
     */
    public void onBreak(DPlayer dp, BlockBreakEvent event){}

    /**
     * This method gets called if implemented by a skill
     * and returns an interaction event and the player
     * part of it
     * @param dp player performing action
     * @param event action event
     */
    public void onInteract(DPlayer dp, PlayerInteractEvent event){}

    /**
     * This method gets called if implemented by a skill
     * and returns a ToggleSneakEvent and the player who is
     * sneaking
     * @param dp
     * @param event
     */
    public void onSneak(DPlayer dp, PlayerToggleSneakEvent event){}

    /**
     * This method gets called if implemented by a skill
     * and returns a EntityShootBow event and the player
     * who shot the bow
     * @param dp shooter
     * @param event vent involved
     */
    public void onShoot(DPlayer dp, EntityShootBowEvent event){}
}

This is my SkillManager.class

  public class SkillManager
{
    private static final SkillManager instance = new SkillManager();
    private static final List<Skill> SKILLS =new ArrayList<>();

    private SkillManager(){}

    public static SkillManager get(){return instance;}
    public void registerSkill(Skill s){
        SKILLS.add(s);
    }
    public void registerSkills(Skill... s){
        for(Skill skill : s){
            SKILLS.add(skill);
        }
    }
    public void unregisterSkill(String name){
        for(Skill skill : SKILLS){
            if(skill.getName().equalsIgnoreCase(name)){
                SKILLS.remove(skill);
            }
        }
    }
    public void callEvent(DPlayer dp, Event e) {

        if(e instanceof PlayerToggleSneakEvent){
            for(Skill s : SKILLS){
                s.onSneak(dp, (PlayerToggleSneakEvent) e);
            }
        }
        else if(e instanceof PlayerInteractEvent){
            for(Skill s : SKILLS){
                s.onInteract(dp, (PlayerInteractEvent) e);
            }
        }
        else if(e instanceof EntityDamageByEntityEvent){
            for(Skill s : SKILLS){
                s.onAttack(dp, (EntityDamageByEntityEvent) e);
            }
        }
        else if(e instanceof BlockBreakEvent){
            for(Skill s : SKILLS){
                s.onBreak(dp, (BlockBreakEvent) e);
            }
        }
        else if(e instanceof EntityShootBowEvent){
            for(Skill s : SKILLS){
                s.onShoot(dp, (EntityShootBowEvent) e);
            }
        }
    }

}

This is Sneak.class the example implementation

public class Sneak extends Skill {

    @Override
    public String getName() {
        return "Sneak";
    }

    @Override
    public void onSneak(DPlayer dp, PlayerToggleSneakEvent event){
        if(dp.getTag("skills_sneak").isPresent()){

        }
    }
}

Thanks for the help.

Aucun commentaire:

Enregistrer un commentaire