1

I have enum class

public enum TaskName {
     LOGIN,REGISTER,MESSAGE
}

I use this enum with switch-case

public class TaskController {


    private UserDao userDaoJpaImpl;
    private FriendDao friendDaoJpaImpl;
    private GroupDao groupDaoJpaImpl;
    private MessageDao messageDaoJpaImpl;

    public TaskController() {
        EntityManagerFactory emfactory = Persistence.createEntityManagerFactory("Eclipselink_JPA");
        userDaoJpaImpl = new UserDaoJpaImpl(emfactory);
        friendDaoJpaImpl = new FriendDaoJpaImpl(emfactory);
        groupDaoJpaImpl = new GroupDaoJpaImpl(emfactory);
        messageDaoJpaImpl = new MessageDaoJpaImpl(emfactory);
    }

    public void doIt(String taskName)
    {
      switch (taskName) {
        case LOGIN:
            userDaoJpaImpl.create(/*Something*/);
            //Implementation
        break;
        case REGISTER:
            //Implementation
        break;
        case MESSAGE:
             messageDaoJpaImpl.create(/*Something*/);
            //Implementation
        break;
        }
    }
}

I create object of TaskController as static TaskController controller=new TaskController()

so that object created only once

Now I am planning to use Command Pattern in place of switch-case

but i am stuck how to use my UserDaoJpaImpl,FriendDaoJpaImpl,GroupDaoJpaImpl,MessageDaoJpaImpl inside Command classess

Edit

Command Class

public interface Command {

    void setSession(Session session); //Session is websocket connection session not HttpSession

    void setConnectedUser(Map<String, UserDTO> connectedUser);

    void setData(String data);        


    JSONObject execute();

}

I want to move whole logic from TaskController.doIt() to Other command class which will implement Command Interface.

I am using Websocket. I don't want to use spring for this problem

Thanks in advance

cahen
  • 15,807
  • 13
  • 47
  • 78
  • Command Pattern is fine. But now it's more like you need a factory pattern for this to create instances. What makes you think you need Command Pattern? Is that the requirement or you found challenge in this? But all your Impl classes should implement the interface and just invoke create method based on it. – Karthik R Aug 14 '15 at 07:20
  • sorry i have pasted old code i have already implemented interface. It is not requirement some1 has suggest me. – abhishek221192 Aug 14 '15 at 07:31
  • Your controller may be doing too much (at least that one method). Forget the command pattern or you will have another problem. – atamanroman Aug 14 '15 at 07:44

4 Answers4

3

You're looking for my solution to this problem here.

Essentially,

public enum TaskName {
     LOGIN {
         @Override
         public void doIt(TaskController taskController) {
              taskController.getUserDao().create(/*something*/);
              //...
         }
     },
     REGISTER {
         @Override
         public void doIt(TaskController taskController) {
              //Implementation
         }
     },
     MESSAGE {
         @Override
         public void doIt(TaskController taskController) {
              taskController.getMessageDao().create(/*something*/);
              //...
         }
     };

     private TaskName() {
     }

     public abstract void doIt(TaskController taskController);

     public static TaskName getByTaskName(String taskName) {
         for(TaskName taskEnum : TaskName.values()) {
             if(taskEnum.name().equalsIgnoreCase(taskName)) {
                 return taskEnum;
             }
         }
         throw new IllegalArgumentException("The Task Name [" + taskName + "] is not a valid task name!");
     }
}

public class TaskController {


    private UserDao userDaoJpaImpl;
    private FriendDao friendDaoJpaImpl;
    private GroupDao groupDaoJpaImpl;
    private MessageDao messageDaoJpaImpl;

    public TaskController() {
        EntityManagerFactory emfactory = Persistence.createEntityManagerFactory("Eclipselink_JPA");
        userDaoJpaImpl = new UserDaoJpaImpl(emfactory);
        friendDaoJpaImpl = new FriendDaoJpaImpl(emfactory);
        groupDaoJpaImpl = new GroupDaoJpaImpl(emfactory);
        messageDaoJpaImpl = new MessageDaoJpaImpl(emfactory);
    }

    public void doIt(String taskName) {
        TaskName.getByTaskName(taskName).doIt(this);
    }
}

Unless I totally misunderstood your question because you never really showed anything about your Command classes.

You should also consider using a framework for this particular problem, like the Spring Framework.

Community
  • 1
  • 1
EpicPandaForce
  • 79,669
  • 27
  • 256
  • 428
3

Keeping the question a bit vague and subjective gives us freedom to imagine :). Here is my take on the structure.

public interface Command {
    public void doIt(EntityManagerFactory emFactory);
}

class LoginCommand implements Command {
    @Override public void doIt(EntityManagerFactory emFactory) {
        UserDaoJpaImpl userDaoJpaImpl = new UserDaoJpaImpl(emFactory);
        // Do something
    }
}

class RegisterCommand implements Command {
    @Override public void doIt(EntityManagerFactory emFactory) {
    }
}

class MessageCommand implements Command {
    @Override public void doIt(EntityManagerFactory emFactory) {
    }
}

enum TaskName {
    LOGIN(new LoginCommand()), REGISTER(new RegisterCommand()), MESSAGE(new MessageCommand());

    private Command command;

    TaskName(Command command) {
        this.command = command;
    }

    public void doIt(EntityManagerFactory emFactory) {
        command.doIt(emFactory);
    }
}

public class TaskController {
    private EntityManagerFactory emFactory = Persistence.createEntityManagerFactory("Eclipselink_JPA");

    public void doIt(String taskName) {
        TaskName task = TaskName.valueOf(taskName);
        task.doIt(emFactory);
    }
}

All the methods are called doIt and of course they are expected to change.

Dakshinamurthy Karra
  • 5,353
  • 1
  • 17
  • 28
1
public interface Command {
 public void Execute();
}

public class Invoker {
    private Map<TaskName,Command> commandMap = new EnumMap<TaskName,Command>(TaskName.class);

    public void AddCommand(TaskName task,Command command){
        commandMap.put(task, command);
    }
    public void HandleCommand(TaskName task){
        Command command=commandMap.get(task);
        command.Execute();
    }
}


public class ConcreteMessageCommand implements Command {
    private MessageDao messageDaoJpaImpl;
    public ConcreteMessageCommand(MessageDao md){
        messageDaoJpaImpl=md;
    }
    @Override
    public void Execute() {
        // TODO Auto-generated method stub
        messageDaoJpaImpl.create();
    }

}



public class ConcreteUserCommand implements Command {
    private UserDao userDaoJpaImpl;

    public ConcreteUserCommand(UserDao ud){
        userDaoJpaImpl=ud;
    }

    @Override
    public void Execute() {
        userDaoJpaImpl.create();
    }

}



public class TaskController {

    Invoker invoker;
    public TaskController() {
        EntityManagerFactory emfactory = Persistence.createEntityManagerFactory("Eclipselink_JPA");
        invoker=new Invoker();
        ConcreteUserCommand cuc=new ConcreteUserCommand(new UserDaoJpaImpl(emfactory));
        invoker.AddCommand(TaskName.LOGIN, cuc);

        ConcreteMessageCommand cmc=new ConcreteMessageCommand(new MessageDaoJpaImpl(emfactory));
        invoker.AddCommand(TaskName.MESSAGE, cmc);


    }

    public void doIt(TaskName taskName)
    {
      invoker.HandleCommand(taskName);
    }
}

public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
      TaskController task=new TaskController();
      task.doIt(TaskName.LOGIN);
    }

}

You can use command pattern to eliminate switch-case like this,GroupDaoJpaImpl- MessageDaoJpaImpl can be thought as receiver objects.You can change where objects are created to optimize code.

Mustafa ASAN
  • 3,747
  • 2
  • 23
  • 34
0

The same idea as @epicPandaForce, but in java 8 it can be handled a bit differently. By passing a lambda to the constructor.

public enum TaskName {
     LOGIN((taskController) -> {
          taskController.getUserDao().create(/*something*/);
          //...
     }),
     REGISTER((taskController) -> {
          //Implementation
     }),
     MESSAGE((taskController) -> {
          //...
     });

     private final Consumer<TaskController> doIt;

     private TaskName(Consumer<TaskController> doIt) {
         this.doIt = doIt;
     }

     public final void service(...) {
         doIt(...);
     }
Joop Eggen
  • 107,315
  • 7
  • 83
  • 138