当前位置:  开发笔记 > 编程语言 > 正文

Design Patterns基于Web的应用程序

如何解决《DesignPatterns基于Web的应用程序》经验,为你挑选了3个好方法。

我正在设计一个简单的基于Web的应用程序.我是这个基于Web的域的新手.我需要您对设计模式的建议,例如如何在Servlet中分配责任,制作新Servlet的标准等.

实际上,我的主页上有很少的实体,并且每个实体都对应于我们添加,编辑和删除等几个选项.之前我每个选项使用一个Servlet,比如Servlet1,用于添加entity1,Servlet2用于编辑entity1等等,这样我们最终得到了大量的servlet.

现在我们正在改变我们的设计.我的问题是你如何选择如何选择servlet的责任.我们是否应该为每个实体安装一个Servlet,它将处理所有选项并将请求转发给服务层.或者我们应该为整个页面都有一个servlet来处理整个页面请求,然后将其转发到相应的服务层?此外,请求对象是否应转发到服务层.



1> BalusC..:

有点像样的Web应用程序由多种设计模式组成.我只会提到最重要的一些.


模型视图控制器模式

您要使用的核心(架构)设计模式是模型 - 视图 - 控制器模式.该控制器是由(上)直接创建/使用特定一个Servlet来表示模型察看基于该请求.该模型由Javabean类表示.在商业模型中,这通常可以进一步分类,其中包含动作(行为)和包含数据(信息)的数据模型.该视图是由具有对(直接访问JSP文件来表示数据)模型由EL(表达式语言).

然后,根据动作和事件的处理方式进行变化.受欢迎的是:

基于请求(动作)的MVC:这是最简单的实现.的(业务)模式直接与HttpServletRequestHttpServletResponse对象.您必须自己收集,转换和验证请求参数(主要是).该视图可以通过普通的香草HTML/CSS/JS来表示,它不跨请求维护状态.这就是其他Spring MVC,Struts和Stripes的工作原理.

基于组件的MVC:这更难实现.但最终会得到一个更简单的模型和视图,其中所有"原始"Servlet API都被完全抽象出来.您不应该自己收集,转换和验证请求参数.所述控制器执行此任务,并设置在所收集的,转换和验证请求参数模型.您需要做的就是定义直接与模型属性一起使用的操作方法.该视图由JSP标记库或依次产生HTML/CSS/JS的XML元素的味道"组件"来表示.观点的状态后续请求在会话中保留.这对于服务器端转换,验证和值更改事件特别有用.这是其他JSF,Wicket和Play等等!作品.

作为旁注,使用自行开发的MVC框架进行游戏是一项非常好的学习练习,只要您将其保留用于个人/私人目的,我就会推荐它.但是一旦你专业,那么强烈建议选择一个现有的框架,而不是重新发明自己的框架.与自己开发和维护一个强大的框架相比,学习现有的,完善的框架需要更长的时间.

在下面的详细解释中,我将限制自己请求基于MVC,因为这更容易实现.


前控制器模式(中介模式)

首先,Controller部分应该实现Front Controller模式(这是一种特殊的Mediator模式).它应该只包含一个servlet,它提供所有请求的集中入口点.它应该基于请求可用的信息创建模型,例如pathinfo或servletpath,方法和/或特定参数.该商业模式被称为Action在下面的HttpServlet例子.

protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    try {
        Action action = ActionFactory.getAction(request);
        String view = action.execute(request, response);

        if (view.equals(request.getPathInfo().substring(1)) {
            request.getRequestDispatcher("/WEB-INF/" + view + ".jsp").forward(request, response);
        }
        else {
            response.sendRedirect(view); // We'd like to fire redirect in case of a view change as result of the action (PRG pattern).
        }
    }
    catch (Exception e) {
        throw new ServletException("Executing action failed.", e);
    }
}

执行操作应返回一些标识符以定位视图.最简单的方法是将它用作JSP的文件名.将此servlet映射到特定url-patternweb.xml,例如/pages/*,*.do甚至只是*.html.

在前缀模式情况下,例如/pages/*,你可以然后调用URL的喜欢http://example.com/pages/register,http://example.com/pages/login等,提供/WEB-INF/register.jsp,/WEB-INF/login.jsp使用适当的GET和POST行为.的部件register,login等然后可通过request.getPathInfo()如在上面的例子.

当你使用后缀模式,比如*.do,*.html等等,那么你可以然后调用URL的喜欢http://example.com/register.do,http://example.com/login.do,等你应该改变这个答案中的代码示例(也是ActionFactory)来代替提取registerlogin部分request.getServletPath().


战略模式

Action应遵循的策略模式.它需要被定义为一个抽象/接口类型,它应该基于抽象方法的传入参数来完成工作(这与Command模式的区别在于,抽象/接口类型应该基于在创建实现期间传入的参数).

public interface Action {
    public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception;
}

您可能希望Exception使用自定义异常更具体ActionException.这只是一个基本的启动示例,其余部分由您决定.

这是一个例子LoginAction(如其名称所示)登录用户.它User本身又是一个数据模型.该视图是知道的存在User.

public class LoginAction implements Action {

    public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        User user = userDAO.find(username, password);

        if (user != null) {
            request.getSession().setAttribute("user", user); // Login user.
            return "home"; // Redirect to home page.
        }
        else {
            request.setAttribute("error", "Unknown username/password. Please retry."); // Store error message in request scope.
            return "login"; // Go back to redisplay login form with error.
        }
    }

}

工厂方法模式

ActionFactory应遵循工厂方法模式.基本上,它应该提供一个创建方法,它返回一个抽象/接口类型的具体实现.在这种情况下,它应该Action根据请求提供的信息返回接口的实现.例如,方法和pathinfo(pathinfo是请求URL中上下文和servlet路径之后的部分,不包括查询字符串).

public static Action getAction(HttpServletRequest request) {
    return actions.get(request.getMethod() + request.getPathInfo());
}

actions反过来应该是一些静态/应用程序范围Map持有所有已知的行动.这取决于你如何填写这张地图.硬编码:

actions.put("POST/register", new RegisterAction());
actions.put("POST/login", new LoginAction());
actions.put("GET/logout", new LogoutAction());
// ...

或者可以基于类路径中的属性/ XML配置文件进行配置:(伪)

for (Entry entry : configuration) {
    actions.put(entry.getKey(), Class.forName(entry.getValue()).newInstance());
}

或者基于类路径中的扫描动态地实现特定接口和/或注释的类:(伪)

for (ClassFile classFile : classpath) {
    if (classFile.isInstanceOf(Action.class)) {
       actions.put(classFile.getAnnotation("mapping"), classFile.newInstance());
    }
}

请记住,在Action没有映射的情况下创建"无所事事" .让它举例来说直接返回request.getPathInfo().substring(1).


其他模式

到目前为止,这些都是重要的模式.

为了更进一步,您可以使用Facade模式创建一个Context类,该类又包装请求和响应对象,并提供委托给请求和响应对象的几个便捷方法,并将其作为参数传递给Action#execute()方法.这会添加一个额外的抽象层来隐藏原始的Servlet API.那么你应该在每个实现中基本上都以 import javax.servlet.*声明结束Action.在JSF术语中,这就是FacesContextExternalContext类正在做的事情.你可以在这个答案中找到一个具体的例子.

然后是状态模式,您希望添加一个额外的抽象层来分割收集请求参数,转换它们,验证它们,更新模型值和执行操作的任务.在JSF术语中,这就是它LifeCycle正在做的事情.

然后是您要创建基于组件的视图的复合模式,该视图可以与模型连接,其行为取决于基于请求的生命周期的状态.在JSF术语中,这就是UIComponent代表.

通过这种方式,您可以逐步向基于组件的框架发展.


也可以看看:

Java核心库中的GoF设计模式示例

请求MVC和组件MVC之间的区别

使用MVC和DAO模式在JSP页面中以HTML格式显示JDBC ResultSet

JSF MVC框架中的MVC是什么组件?

JSF控制器,服务和DAO


@masato:您可以在例如静态初始化程序块中执行此操作.
执行"post_servlet"应该在操作中执行的工作.你不应该有多个servlet.业务应该在行动课上完成.如果您希望它是一个新请求,则返回到另一个视图,该视图将导致重定向并在与GET请求关联的新操作中执行该作业.
要看.最简单的方法是在`Action`实现中以与普通servlet相同的方式执行它(另请参阅[servlets wiki](http://stackoverflow.com/tags/servlets/info)以获取基本示例,您可以可以自由地重构一些`Validator`接口).但是您也可以在调用操作之前执行此操作,但这更复杂,因为它需要在每个视图的基础上知道验证规则.JSF通过在XHTML标记中提供`required ="true"`,`validator ="customValidatorName"`等来解决这个问题.
@AndreyBotalov:检查MVC框架的源代码,如JSF,Spring MVC,Wicket,Struts2等.它们都是开源的.

2> Alexander Po..:

在被打败的MVC模式中,Servlet是"C" - 控制器.

其主要工作是进行初始请求评估,然后根据初始评估将处理发送给特定工作人员.工作者的职责之一可能是设置一些表示层bean并将请求转发到JSP页面以呈现HTML.因此,仅凭此原因,您需要将请求对象传递给服务层.

不过,我不会开始写原始Servlet课程.他们所做的工作是非常可预测的和样板,这个框架非常好.幸运的是,有许多可用的,经过时间考验的候选者(按字母顺序排列):Apache Wicket,Java Server Faces,Spring等等.



3> Kangkan..:

恕我直言,如果你从责任分配的角度来看它,在网络应用的情况下没有太大的区别.但是,要保持图层的清晰度.在表示层中保留任何纯粹用于演示目的的内容,例如特定于Web控件的控件和代码.只需将您的实体保留在业务层和业务层中的所有功能(如添加,编辑,删除)等.但是,将它们渲染到要在表示层中处理的浏览器上.对于.Net,ASP.NET MVC模式在保持层分离方面非常好.看看MVC模式.

推荐阅读
拾味湖
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有