设计模式——装饰器模式

装饰器模式

在不改变源代码的基础上对一个对象的功能进行增强
可以对一个对象装饰多个功能

Java实现

1.实现和原对象一样的接口
2.重写需要增强的方法

原始未增强的代码
接口

public interface MyInter {
	public void print(String s);
}

原始类

public class Source implements MyInter {
	@Override
	public void print(String s) {
		System.out.println(s);
	}
}

测试类

public static void main(String[] args) throws Exception {
	MyInter source = new Source();
	source.print("aaa");//aaa
}
对print方法进行增强,将所有小写字符串改为大写
即MyInter source对象调用自身print方法时进行增强

1.print方法只属于MyInter类型
所以要增强就必须要增强类实现MyInter接口

2.增强类要重写print方法,这样在调用MyInter.print时,
就可以太子换狸猫,调用增强类的print方法
为了在增强类中执行原始类的print方法
必须将原始类作为增强类的属性,在构造器中初始化
就可以在增强类中调用并对其进行增强

装饰器1

public class Decorate implements MyInter {
	private MyInter source;//接口类型的原始类作为属性

	public Decorate() {
		super();

	}

	public Decorate(MyInter source) {//初始化
		super();
		this.source = source;
	}

	@Override
	public void print(String s) {
		System.out.println("Decorate增强前执行的代码...");
		s = s.toUpperCase();//字母全大写
		source.print(s);//将大写字母作为参数
		System.out.println("Decorate增强后执行的代码...");
	}
}

装饰器2

public class Decorate2 implements MyInter {

	private MyInter source;

	public Decorate2() {
		super();

	}

	public Decorate2(MyInter source) {
		super();
		this.source = source;
	}

	@Override
	public void print(String s) {
		System.out.println("Decorate2 增强前执行的代码...");
		s = s.toLowerCase();//转为全小写
		source.print(s);//将小写字母作为参数
		System.out.println("Decorate2 增强后执行的代码...");
	}
}

测试代码

public static void main(String[] args) throws Exception {
	MyInter s1 = new Source();
	MyInter source = new Decorate2(new Decorate(s1));
	source.print("aaa");
	//执行的是装饰器2的增强方法
	//将字母转为小写并作为参数传入装饰器1的增强方法,并调用装饰器1的增强方法
	//在装饰器1的增强方法中,将字符串转为大写,再调用原始类的方法输出字符串


	/*	Decorate2 增强前执行的代码...
		Decorate 增强前执行的代码...
		AAA
		Decorate 增强后执行的代码...
		Decorate2 增强后执行的代码...
	*/
}

实际应用

servlet中的request.getParameter("username")
对于get请求的乱码问题需要单独对参数进行编码与解码
protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {	
	String parameter = request.getParameter("username");	
	System.out.println(parameter);
	
}
这个时候就可以对其进行增强
在过滤器Filter中拦截所有请求,在doFilter方法中进行调用增强类
1.HttpServletRequest request有一个父类接口HttpServletRequestWrapper,
自定义MyRequest实现这个接口
2.重写getParameter方法
public class MyRequest extends HttpServletRequestWrapper{
	
	private HttpServletRequest request;
	//有参构造
	public MyRequest(HttpServletRequest request) {
		super(request);
		this.request = request;
	}
	//无参构造
	//...

	//对getParaameter增强
	@Override
	public String getParameter(String name) {
		String parameter = request.getParameter(name);//乱码
		try {
			parameter = new String(parameter.getBytes("iso8859-1"),"UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return parameter;
	}
	
}
增强后在Filter中用MyRequest替换(HttpServletRequest
@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {		
		//post方式乱码的解决代码
		request.setCharacterEncoding("UTF-8");

		
		//get方式乱码的解决代码
		HttpServletRequest req = (HttpServletRequest) request;
		//增强对象
		MyRequest myRequest = new MyRequest (req);
		
		//替换对象,放行请求
		chain.doFilter(myRequest , response);
		
	}

python实现

使用装饰器计算出代码运行时间
def function(f):
    def inner(*args,**kwagrs):
        start = time.time()#目标方法运行前执行的代码
        ret = f(*args,**kwagrs)#目标方法
        end =time.time() - start#目标方法运行后执行的代码
        print('程序运行时间为%.4f'% end)
        return ret #方法返回值
    return inner
    
@function
def code(n):
    for i in range(n):
        print(i)
    
code(10000)
print(code.__name__)#inner
将函数装饰器转换为方法装饰器
from django.utils.decorators import method_decorator
class MyTest(Object):

    @method_decorator(function)
    def code(n):
	    for i in range(n):
	        print(i)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值