解耦和耦合

Posted 纯真的梦

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了解耦和耦合相关的知识,希望对你有一定的参考价值。

概念:

 耦合是指两个或两个以上的体系或两种运动形式间通过相互作用而彼此影响以至联合起来的现象。

 解耦就是用数学方法将两种运动分离开来处理问题,常用解耦方法就是忽略或简化对所研究问题影响较小的一种运动,只分析主要的运动。
 

什么是与Servlet API解耦?

为了避免与servlet API耦合在一起,方便Action做单元测试,

Struts2对HttpServletRequest,HttpSession,和ServletContext进行了封装,构造了3个Map对象来替代这三个对象,在Action中可以直接使用HttpServletRequest,HttpSession,ServletContext对应的Map对象来保存和读取数据。

 

两种解耦方式:

1、    使用Struts2提供的工具类中提供的静态方法,得到对用的封装后对象。

  

复制代码
复制代码
package cn.itcast.context;

import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;

public class ContextAction extends ActionSupport {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    public String test() throws Exception{
        System.out.println("ContextAction ****** test()");
        
        HttpServletRequest request=ServletActionContext.getRequest();
        request.setAttribute("username","username_request");
        
        HttpServletResponse response=ServletActionContext.getResponse();
        
        Map sessionMap=ServletActionContext.getContext().getSession();
        sessionMap.put("username", "username_session");
        
        ServletContext sc=ServletActionContext.getServletContext();
        sc.setAttribute("username", "username_application");
        
        return "attr";
    }
}
复制代码
复制代码

 

2、    Action实现ServletRequestAware,ServletResponseAware,ServletContextAware,SessionAware四个接口,分别重写对应的set方法,达到操作该4个封装后对象。

复制代码
复制代码
package cn.itcast.context;

import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts2.ServletActionContext;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.struts2.interceptor.SessionAware;
import org.apache.struts2.util.ServletContextAware;

import com.opensymphony.xwork2.ActionSupport;

public class Context02Action extends ActionSupport 
    implements ServletRequestAware,ServletResponseAware,ServletContextAware,SessionAware{

    HttpServletRequest request;
    HttpServletResponse response;
    ServletContext context;
    Map<String, Object> sessionMap;
    
    private static final long serialVersionUID = 1L;

    public String test() throws Exception{
        System.out.println("ContextAction ****** test()");
        
        HttpServletRequest request=ServletActionContext.getRequest();
        request.setAttribute("username","username_request");
        
        HttpServletResponse response=ServletActionContext.getResponse();
        
        Map sessionMap=ServletActionContext.getContext().getSession();
        sessionMap.put("username", "username_session");
        
        ServletContext sc=ServletActionContext.getServletContext();
        sc.setAttribute("username", "username_application");
        
        return "attr";
    }

    public void setSession(Map<String, Object> session) {
        this.sessionMap=session;
    }

    public void setServletContext(ServletContext context) {
        this.context=context;
        
    }

    public void setServletResponse(HttpServletResponse response) {
        this.response=response;
    }

    public void setServletRequest(HttpServletRequest request) {
        this.request=request;
        
    }
}
复制代码
复制代码

其他代码:

 

 struts_context.xml
 context/test.jsp
 context/success.jsp
 context/attr.jsp

 

struts2与servlet的耦合有三种实现方案:

1.ActionContext

在xwork2.jar的com.opensymphony.xwork2.ActionContext中。

这个是最推荐的一种实现。

action不需要实现接口,只需要引入这个目录就可以。

ActionContext.getContext().put("zhangsan","helloworld");

 

只需要一句代码就可以放入response中,页面直接用EL表达式${requestScope.zhangsan}获取。取代了标签

<s:property value="zhangsan"/>

 

2.servletActionContext

在struts2-core.jar中,org.apache.struts2.ServletActionContext

同样action不需要实现接口,只需要引入这个目录就可以。

HttpServletResponse response = ServletActionContext.getResponse();

 

实现了response对象,然后只需要像往常一样适用

 

Cookie cookie = new Cookie("username", this.getUsername());
cookie.setMaxAge(1000);
response.addCookie(cookie);

 

3.ServletRequestAware,ServletResponseAware接口实现

首先实现接口,然后实现request或response对象。

 

复制代码
复制代码
package com.test.action;

.

public class LoginAction extends ActionSupport implements ServletRequestAware {

    private static final long serialVersionUID = 3936066275134469754L;
    // private HttpServletResponse response;

     private HttpServletRequest request;

    @SuppressWarnings("unchecked")
    public String execute() throws Exception {
        .        
    }

    @SuppressWarnings("unchecked")
    public String hello() throws Exception {

        .

            request.setAttribute("zhangsan","helloworld");

        .

    }

    public void setServletRequest(HttpServletRequest request) {

        this.request=request;
    }

}

以上是关于解耦和耦合的主要内容,如果未能解决你的问题,请参考以下文章

程序的耦合和解耦

阶段3 2.Spring_02.程序间耦合_3 程序的耦合和解耦的思路分析1

解耦和耦合

Spring中如何使用工厂模式实现程序解耦?

Spring学习:程序的耦合和解耦的思路分析

工厂模式