Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用设计模式代替开关盒_Java_Design Patterns_Enums_Switch Statement - Fatal编程技术网

Java 如何使用设计模式代替开关盒

Java 如何使用设计模式代替开关盒,java,design-patterns,enums,switch-statement,Java,Design Patterns,Enums,Switch Statement,我有枚举类 public enum TaskName { LOGIN,REGISTER,MESSAGE } 我将此枚举与开关大小写一起使用 public class TaskController { private UserDao userDaoJpaImpl; private FriendDao friendDaoJpaImpl; private GroupDao groupDaoJpaImpl; private MessageDao messa

我有枚举类

public enum TaskName {
     LOGIN,REGISTER,MESSAGE
}
我将此枚举与开关大小写一起使用

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;
        }
    }
}
我将TaskController的对象创建为 静态TaskController=new TaskController()

所以这个对象只创建了一次

现在我计划用命令模式代替开关盒

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;
        }
    }
}
但是我被困在了如何在命令类中使用我的UserDaoJpaImpl、friendaojpaimpl、GroupDaoJpaImpl、MessageDaoJpaImpl

编辑

命令类

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();

}
公共接口命令{
void setSession(会话会话);//会话是websocket连接会话而不是HttpSession
void setConnectedUser(映射connectedUser);
void setData(字符串数据);
JSONObject execute();
}
我想将整个逻辑从TaskController.doIt()移动到另一个将实现命令接口的命令类

我正在使用Websocket。我不想用弹簧来解决这个问题


提前感谢

您正在寻找我对这个问题的解决方案

本质上

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);
    }
}
除非我完全误解了你的问题,因为你从来没有真正展示过你的
命令


你也应该考虑使用一个框架来解决这个问题,比如<强> Spring框架

< p>你在寻找我的这个问题的解决方案。

本质上

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);
    }
}
除非我完全误解了你的问题,因为你从来没有真正展示过你的
命令


你也应该考虑使用一个框架来解决这个问题,比如<强> Spring框架< /强> ./P> < P>保持这个问题有点模糊和主观给了我们想象的自由:这是我对结构的看法

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);
    }
}

所有的方法都被称为
doIt
,当然它们也会改变。

保持问题的模糊性和主观性让我们可以自由想象:)。这是我对结构的看法

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);
    }
}

所有的方法都被称为
doIt
,当然它们也会改变。

与@epicPandaForce的想法相同,但在Java8中,处理方法可能会有所不同。通过将lambda传递给构造函数

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(...);
     }
公共枚举任务名{
登录((任务控制器)->{
taskController.getUserDao().create(/*something*/);
//...
}),
寄存器((任务控制器)->{
//实施
}),
消息((任务控制器)->{
//...
});
私人最终消费者doIt;
私有任务名(使用者doIt){
this.doIt=doIt;
}
公共最终作废服务(…){
doIt(…);
}

与@epicPandaForce的思想相同,但在java 8中,它的处理方式可能有点不同

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(...);
     }
公共枚举任务名{
登录((任务控制器)->{
taskController.getUserDao().create(/*something*/);
//...
}),
寄存器((任务控制器)->{
//实施
}),
消息((任务控制器)->{
//...
});
私人最终消费者doIt;
私有任务名(使用者doIt){
this.doIt=doIt;
}
公共最终作废服务(…){
doIt(…);
}
公共接口命令{
公共无效执行();
}
公共类调用程序{
私有映射commandMap=newenummap(TaskName.class);
public void AddCommand(TaskName任务,Command命令){
commandMap.put(任务、命令);
}
public void HandleCommand(TaskName任务){
Command=commandMap.get(任务);
command.Execute();
}
}
公共类ConcreteMessageCommand实现该命令{
私有消息dao消息daojpaimpl;
公共消息命令(messagedaomd){
messageDaoJpaImpl=md;
}
@凌驾
public void Execute(){
//TODO自动生成的方法存根
messageDaoJpaImpl.create();
}
}
公共类ConcreteUserCommand实现该命令{
私有UserDao userDaoJpaImpl;
公共用户命令(userdaoud){
userDaoJpaImpl=ud;
}
@凌驾
public void Execute(){
userDaoJpaImpl.create();
}
}
公共类任务控制器{
调用者调用者;
公共任务控制器(){
EntityManagerFactory emfactory=Persistence.createEntityManagerFactory(“Eclipselink_JPA”);
invoker=newinvoker();
ConcreteUserCommand cuc=新ConcreteUserCommand(新用户DAOJPAIMPL(emfactory));
AddCommand(TaskName.LOGIN,cuc);
ConcreteMessageCommand cmc=new-ConcreteMessageCommand(new-MessageDaoJpaImpl(emfactory));
invoker.AddCommand(TaskName.MESSAGE,cmc);
}
public void doIt(TaskName TaskName)
{
invoker.HandleCommand(taskName);
}
}
公共班机{
公共静态void main(字符串[]args){
//TODO自动生成的方法存根
TaskController任务=新建TaskController();
task.doIt(TaskName.LOGIN);
}
}
您可以使用命令模式来消除这样的切换情况,GroupDaoJpaImpl-MessageDaoJpaImpl可以被视为接收方对象。您可以更改对象的创建位置以优化代码。

公共接口命令{
公共无效执行();
}
公共类调用程序{
私有映射commandMap=newenummap(TaskName.class);
public void AddCommand(TaskName任务,Command命令){
commandMap.put(任务、命令);
}
public void HandleCommand(TaskName任务){
Command=commandMap.get(任务);
command.Execute();
}
}
公共类ConcreteMessageCommand实现该命令{
私有消息dao消息daojpaimpl;
公共消息命令(messagedaomd){
messageDaoJpaImpl=md;
}
@凌驾
public void Execute(){
//TODO自动生成的方法存根
messageDaoJpaImpl.create();
}
}
公共类ConcreteUserCommand实现该命令{
私有UserDao userDaoJpaImpl;
P