繁体   English   中英

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

[英]How to use design Pattern in place of switch case

我有枚举课

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 controller = new TaskController()

这样该对象只能创建一次

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

但我被困在命令类中如何使用我的UserDaoJpaImpl,FriendDaoJpaImpl,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();

}

我想将整个逻辑从TaskController.doIt()移至将实现命令接口的其他命令类。

我正在使用Websocket。 我不想用spring解决这个问题

提前致谢

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

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

除非我完全误解了您的问题,因为您从未真正展示过有关Command类的任何内容。

您还应该考虑针对此特定问题使用框架,例如Spring Framework

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

}

您可以像这样使用命令模式消除切换情况,GroupDaoJpaImpl- MessageDaoJpaImpl可以被视为接收器对象。您可以更改创建对象的位置来优化代码。

与@epicPandaForce的想法相同,但是在Java 8中,它的处理方式可能有所不同。 通过将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(...);
     }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM