4

I'm relatively new to design patterns and in the following example I am using what I believe is a Strategy Pattern. However, I am repeating myself inside some, not all, concrete strategies and wondering is there a way to avoid this? Notice how ACommand and CCommand have the same code before doing something unique.

public interface Command 
{
    public boolean execute(CommandSender sender, String[] args);
    public String getName();
    //...
}

public abstract class PlayerCommand implements Command 
{
    protected BukkitPlugin plugin = BukkitPlugin.getInstance();

    private String name;
    //...

    public PlayerCommand(String name) 
    {
        this.name = name;
    }

    public String getName() 
    {
        return this.name;
    }

    //...
}

ACommand

    public class ACommand extends PlayerCommand
    {
        public ACommand()
        {
            super("A");
        }

        public boolean execute(CommandSender sender, String[] args)
        {
            Player player = (Player) sender;
            PlayerInventory inventory = player.getInventory();
            ItemStack itemInHand = inventory.getItemInHand();

            if(itemInHand.getType() != Material.COMPASS)
            {
                sender.sendMessage("You must be holding a phone to use this command");
                return true;
            }

            int id = itemInHand.getDurability();

            MobilePhoneManager phoneManager = plugin.getMobilePhoneManager();       
            boolean isMobilePhone = phoneManager.isMobilePhone(id);

            if(!isMobilePhone)
            {
                sender.sendMessage("You must be holding a mobile phone to use this command");
                return true;
            }

            //DO SOMETHING UNIQUE HERE
        }
}

BCommand

public class BCommand extends PlayerCommand
        {
            public BCommand()
            {
                super("B");
            }

            public boolean execute(CommandSender sender, String[] args)
            {
                //SOMETHING ELSE
            }
    }

CCommand

    public class CCommand extends PlayerCommand
    {
        public CCommand()
        {
            super("C");
        }

        public boolean execute(CommandSender sender, String[] args)
        {
            Player player = (Player) sender;
            PlayerInventory inventory = player.getInventory();
            ItemStack itemInHand = inventory.getItemInHand();

            if(itemInHand.getType() != Material.COMPASS)
            {
                sender.sendMessage("You must be holding a phone to use this command");
                return true;
            }

            int id = itemInHand.getDurability();

            MobilePhoneManager phoneManager = plugin.getMobilePhoneManager();       
            boolean isMobilePhone = phoneManager.isMobilePhone(id);

            if(!isMobilePhone)
            {
                sender.sendMessage("You must be holding a mobile phone to use this command");
                return true;
            }

            //DO SOMETHING UNIQUE HERE
        }
}
Jonathan
  • 3,016
  • 9
  • 43
  • 74
  • 2
    This looks like a command pattern. If you see the same line of code all the time factor it out into a function. no need for a new design pattern. – andre Mar 12 '13 at 20:46

2 Answers2

8

You could use the template pattern as the basis for a common base class between ACommand and CCommand. The template method in the base class would hold the common code, then call an (abstract) method to doSomethingUnique().

sharakan
  • 6,821
  • 1
  • 34
  • 61
0

Andre is right on all counts. You are using a Command pattern and you just need to tweak your interface a bit to include some notion of whether the command is currently in a state where it can execute

bool canExecute();
boll canExecute(args)

You usually don't see the execute method return anything though.

HTH,
Berryl

Berryl
  • 12,471
  • 22
  • 98
  • 182