java - 重构 Java Servlets - 寻找一个好的命名方案

标签 java design-patterns servlets refactoring

我正在重构一个现有的 (Ajax) Java Web 应用程序,该应用程序目前将许多逻辑直接保存在 servlet 中。 (servlet 甚至使用一些卑鄙的技巧相互调用......)

重构本身很痛苦,但非常简单(现在重构所有内容以使用依赖注入(inject))。

我的问题是,我真的想不出完美的命名方案:

重构后的 Servlet 现在只包含最少的逻辑(处理 ServletRequest 和 ServletResponse,发送 HTTP 错误代码等),然后它们称之为我目前所说的 Processors (好/坏的名字?!?),它可以被多个 Servlet、测试类、...重用。处理器执行操作所需的逻辑,类似于 session Bean 将执行的操作,如果我们使用EJB。

我从来没有想过,“Session Bean”会是个好名字。而且我也不太热衷于定义一个单一的“外观”。我主要是在寻找一个比“Processor”更好的名称,或者可能是如何构建您的 Servlet 处理代码的一些想法。

例子

这是一个简化的示例(实际应用程序使用 GWT 和 Gilead,...但这并不重要):

public class UserRegistrationServlet extends HttpServlet {

@Inject
UserRegistrationProcessor userRegistrationProcessor;

@Override
protected void doPost(final HttpServletRequest req, 
        final HttpServletResponse resp)
        throws ServletException, IOException {

    RegistrationRequest registrationRequest = parseRegistrationRequest(req);

    RegistrationResult registrationResult = 
                userRegistrationProcessor.process(registrationRequest);

    pw.print(toJson(registrationResult));

    ...
}
}

如示例所示,我更喜欢拥有专门的处理器,它们只负责一项任务(或者可能是一些非常相关的任务)——而不是处理许多不同操作的大类。

最佳答案

这是我基于之前讨论的示例:

public class UserRegistrationServlet extends HttpServlet {

    @Inject
    private UserRequestExtractor userRequestExtractor;

    @Inject
    private UserRegistrationService userRegistrationService;

    @Override
    protected void doPost(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
        PrintWriter pw = response.getWriter();
        pw.print(createResponse(userRequestExtractor.extract(request)));
    }

    protected String createResponse(User newUser) {
        if (newUser == null) {
            return "{'message' : 'the user parameters are not valid'}";
        }
        else {
            UserRegistrationResult result = userRegistrationService.register(newUser);
            switch (result) {
                case SUCCESS:
                    return "{'message' : 'hurray'}";
                case EMAIL_IN_USE:
                    return String.format("{'message' : 'the email address %s is already in use'}", newUser.email);
                case USERNAME_IN_USE:
                    return String.format("{'message' : 'the user name %s is already in use'}", newUser.username);
                default:
                    return "{'message' : 'an error occurred'}";
            }
        }
    }
}

public class User {
    private String username;
    private String email;

    public boolean isValid() {
        return username != null && email != null;
    }
}

/**
 * Extractor which instantiates an object of type T from a request
 * 
 * @param <T>
 */
public interface RequestExtractor<T> {
    public T extract(HttpServletRequest request);
}

public class UserRequestExtractor implements RequestExtractor<User> {
    public User extract(HttpServletRequest request) {
        User user = new User();
        user.username = request.getParameter("username");
        user.email = request.getParameter("email");
        // validation could also be a responsibility of the RequestExtractor
        if (!user.isValid()) {
            return null;
        }
        return user;
    }
}

public interface UserRegistrationService {
    public UserRegistrationResult register(User user);
}

// implementation of UserRegistrationService omitted

public enum UserRegistrationResult {
    SUCCESS, EMAIL_IN_USE, USERNAME_IN_USE;
}

/**
 * Unit test
 */
public class UserRegistrationServletTest {

    @Test
    public void test() {
        UserRegistrationServlet cut = new UserRegistrationServlet();
        User user = new User();
        user.username = null;
        user.email = "test@test.test";

        String response = cut.createResponse(user);

        Assert.assertEquals("{'message' : 'the user parameters are not valid'}", response);
    }
}

希望这对您有所帮助。

关于java - 重构 Java Servlets - 寻找一个好的命名方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6897691/

相关文章:

java - FirebaseUser - 如何为 FirebaseUser.updatePhoneNumber(PhoneAuthCredential) 使用 PhoneAuthCredential 参数

sql - 存储库模式困境 : Redundant Queries vs. 数据库往返

java - 给定一个可变类,如何使这个类的特定对象不可变?

java - servlet接收xml数据时出错

ajax 就绪状态达到 4 但状态始终为 200

java - 客户端订阅 channel 后 Cometd 扫描 session

java - 固定线程池的理想大小是多少?

java - 解耦工厂以允许自定义工厂实现

java - 当登录用户关闭浏览器时,如何强制 Tomcat 删除过期的 session ?

java - 编写一个带有两个 int 参数的方法。如何使用下面提供的信息声明更多局部 int 变量