Java - method implementation depends on parameter value

Consider the method

public void doSomething(String actionID){
switch (actionID){
    case "dance":
            System.out.print("I'm dancing");
            break;
    case "sleep":
            System.out.print("I'm sleeping");
            break;
    default: 
            System.out.print("I've no idea what I'm doing");
}

The implementation of the method depends on the value of the parameter. Is there a more elegant way to do this or another design pattern for replicating behavior?

+4
source share
4 answers

If the caller decides which logic runs by passing different lines, then why not just call their different methods:

public void doSomething(String actionID) {...}
...
doSomething("dance");
doSomething("sleep");

VS :.

public void dance() {...}
public void sleep() {...}
...
dance();
sleep();

It seems that you are unnecessarily redirecting all calls to doSomething


But strings may not always be literals. What if you take them from the console?

You can provide static mappings from strings to the corresponding functions:

class MyClass {
    private static final Map<String, Consumer<MyClass>> map = new HashMap<>();

    static {
        map.put("sleep", MyClass::sleep);
        map.put("dance", MyClass::dance);
    }

    public void doSomething(String actionID) {
        map.getOrDefault(actionID, MyClass::doNothing).accept(this);
    }

    public void dance() {
        System.out.print("I'm dancing");
    }

    public void sleep() {
        System.out.print("I'm sleeping");
    }

    private void doNothing() {
        System.out.println("I've no idea what I'm doing");
    }
}

, .

+4

,

  public interface HumanState {

    public void tellMeWhatYouAreDoing();
  }

  public class DancingState implements HumanState {
    @Override
    public void tellMeWhatYouAreDoing() {
      System.out.println("I'm dancing");
    }
  }

  public class SleepingState implements HumanState {

    @Override
    public void tellMeWhatYouAreDoing() {
      System.out.println("I'm sleeping");
    }
  }

  public class UnknownState implements HumanState {

    @Override
    public void tellMeWhatYouAreDoing() {
      System.out.println("I've no idea what I'm doing");
    }
  }

. .

public class HumanStateExample {

  public static void main(String[] args) {
    HumanStateExample humanStateExample = new HumanStateExample();

    humanStateExample.doSomething("dance");
    humanStateExample.doSomething("sleep");
    humanStateExample.doSomething("unknown");
  }

  private final HashMap<String, HumanState> humanStateMap;


  public HumanStateExample(){
    humanStateMap = new HashMap<String, HumanState>();
    humanStateMap.put("dance", new DancingState());
    humanStateMap.put("sleep", new SleepingState());

  }

  public void doSomething(String action) {
    HumanState humanState = humanStateMap.get(action);
    if(humanState == null){
      humanState = new UnknownState();
    }

    humanState.tellMeWhatYouAreDoing();
  }
}
+1

, , , :

, , . , .

edit: FancyParameterAction Factory FancyParameterAction : factory,

//Your method, but this time with a complex object, not with a simple string.
public void doSomething(FancyParameterObject fpo){
    FancyParameterActionUtility.invokeOn(fpo);
}


 //The utility which can handle the complex object and decides what to do.
public class FancyParameterActionUtility{
    public Interface FPAHandler{
        void invoke(FancyParameterObject fpo);
        boolean handles(FancyParameterObject fpo);
    }

    //Omitted: Different implementations of FPAHandler

    public static List<FPAHandler> handlers = new LinkedList<>();

    static{
        handlers.add(new DanceHandler());
        handlers.add(new SleepHandler());
        //Omitted: Different implementations of FPAHandler
    }

    public static void invokeOn(FancyParameterObject fpo){
        for(FPAHandler handler:handlers){
            if (handler.handles(fpo)){
                handler.invoke(fpo);
                return;
            }
        }
        //Default-Behavior
    }

}
+1

, . AbstractCommand, . createCommand() . , . - doAction(), undefined, .

public abstract class AbstractCommand {
    public static AbstractCommand createCommand(String name) {
        try {
            String clsName = name + "Command";
            Class<?> cls = Class.forName(clsName);
            AbstractCommand command = (AbstractCommand) cls.newInstance();

            return command;
        }
        catch (Exception e) {
            System.out.println("Something went wrong.");
        }
    }

    public abstract void doAction();
}

public class DanceCommand extends AbstractCommand {
    public void doAction() {
        System.out.println("I'm dancing");
    }
}

public class TestCommandPattern {
    public void doSomething(String actionID) {
        AbstractCommand cmd = AbstractCommand.createCommand(actionID);
        cmd.doAction();
    }

    public static void main(String[] args) {
        TestCommandPattern test = new TestCommandPattern();
        test.doSomething("Dance");  // should print "I'm dancing"
    }
}

, , . , SleepCommand, I'm sleeping, , .

0

All Articles