解耦与耦合

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

}
复制代码
复制代码

 

Action类案例:

 

public class FirstAction implements Action,ModelDriven<UserInfo>,ServletRequestAware{
	private Map<String, Object> map;
	private HttpServletRequest request;
	//前台输入的用户名和密码 在Action中如何捕获
		private UserInfo user=new UserInfo();
		public String execute() throws Exception {
			System.out.println("====FirstAction   ==============+++execute");
			System.out.println("================="+user);
			if(user.getUsername().equals("admin")&&user.getPassword().equals("admin")){

				//解耦合方式一
				//Map<String, Object> session = ActionContext.getContext().getSession();
				
				
				//解耦合方式2:IOC(注入)SessionAware
				
				
				//耦合方式一
				/*HttpSession session2 = ServletActionContext.getRequest().getSession();
				
				//耦合方式2
				Map<String, Object> session = ServletActionContext.getContext().getSession();
				*/
				//session.put("uname", user.getUsername());
				
				//session2.setAttribute("uname", user.getUsername());
				
				
				
				//map.put("uname", user.getUsername());
				
				request.getSession().setAttribute("uname", user.getUsername());
			 return "success";
			}else{
				return "login";
			}
		}
		
		
	public Map<String, Object> getMap() {
		return map;
	}

	public void setMap(Map<String, Object> map) {
		this.map = map;
	}

	
	public HttpServletRequest getRequest() {
		return request;
	}

	public void setRequest(HttpServletRequest request) {
		this.request = request;  
	}

	
	public UserInfo getUser() {
		return user;
	}
	public void setUser(UserInfo user) {
		this.user = user;
	}

	public UserInfo getModel() {
		return null;
	}

	public void setServletRequest(HttpServletRequest request) {
		this.request=request;
		
	}
	public void setSession(Map<String, Object> map) {
		this.map=map;
   }
}

 

  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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

解耦与耦合的你我他

Struts2 与Servlet API解耦,耦合的访问方式

工厂模式

工厂模式

解耦和耦合

Spring 从入门到精通系列 02——程序的耦合问题及工厂模式解耦