0
votes

I am making something right now that gives you an item based on a command and it's input. If the command is /item mythical destroyer or /item mythical 1 (an ID system) it gives you a destroyer item (arbitrary, don't worry about the specifics).

Looking at other questions, they all have to do with enums, but what I am looking for is how to do it with integers and strings.

Here is what I am doing right now:

    interface MythicalItem {

        ItemStack getItem();

        int getPrice();

        void setPrice(int var1);

        int getID();

    }
    class DestroyerMI implements MythicalItem {
        private int price = 50;
        int getID(){
            return 1;
        }

        void setPrice(int var1){
            this.price = var1;
        }

        int getPrice(){
            return price;
        }

        Item getItem(){
            Item item = new Item()
            return item;
        }

    }
class MythicalUtil{
    public static ItemStack parseItem(MythicalItem mythicalItem){
        return mythicalItem.getItem();
    }

    public static int parseID(MythicalItem mythicalItem){
        return mythicalItem.getID();
    }

    public static int parsePrice(MythicalItem mythicalItem){
        return mythicalItem.getPrice();
    }
}

My problem arises right here, and it doesn't seem like there is a way to get the mythical item by name/id without a giant switch or if/else, which I am trying to prevent.

                 // String[] args = {"mythical", "destroyer"};

                    if(args[0].equalsIgnoreCase("mythical")){
//                      I know it is supposed to be Integer.parseInt(args[1]), but dont worry about that please.
                        if(args[1].equals("1") || args[1].equalsIgnoreCase("destroyer")){
                            player.giveItem(MythicalUtil.parseItem(new DestroyerItem()));

                        }else if(args[1].equalsIgnoreCase("shooter"){
                            plaer.giveItem(MythicalUtil.parseItem(new ShooterItem()));
                        }else if(...
                    }

I want to make a method that can return the item to me without spaghettifying my code.

1
You could convert args[0] and args[1] to lowercase strings so you don't have to use equalsIgnoreCase, and then use a switch block. It seems like a question for Code Review Stack Exchange though - user
Yes, but I would like to not use dozens of switches. - zachary cohen
Try using a map, then? - user
The general refactoring you're looking for is Replace Conditional with Polymorphism. The precise details on how to do this are beyond the scope of SO, but if you decide to post over on CR (after reviewing their question standards, of course), feel free to @ me here with the link. - chrylis -cautiouslyoptimistic-

1 Answers

0
votes

If you really need to do all of that on Strings and Integers and you don't want to refactor all the code you already have but that particular part only, you can try to use switch case

String appropriateNameForArg0 = args[0].toUpperCase();
String appropriateNameForArg1 = args[1].toUpperCase();

if (appropriateNameForArg0.equals("MYTHICAL")) {
    switch (appropriateNameForArg1) {
        case "1":
        case "DESTROYER":
            player.giveItem(MythicalUtil.parseItem(new DestroyerItem()));
            break;
        case "SHOOTER":
            plaer.giveItem(MythicalUtil.parseItem(new ShooterItem()));
            break;
        case "...":
            // some other action here
        default:
            // here you have a place for actions which will be triggered if appropriateNameForArg1 will not meet any of the defined cases
            break;
    }
}