栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

设计模式之代理模式

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

设计模式之代理模式

代理模式
    • 1.简要概述
    • 2.模式分类
    • 3.模式结构
    • 4.实现代码
    • 5.优点好处
    • 6.缺点弊端
    • 7.应用场景
    • 8.应用示例

1.简要概述
  • 代理模式就是通过代理对象来控制对真实对象的访问,也就是详细的控制访问某个对象的方法,从而将一些统一的流程代码放到代理类中处理。
  • 代理模式中,被代理的对象可以是远程对象、创建开销大的对象、需要安全控制的对象。
  • 代理模式是面向切面编程的核心实现思想。
2.模式分类
  • 静态代理

    在静态代理中,需要定义一个公共接口,代理对象和被代理对象都要实现这个公共接口中的方法。

    // 教师接口
    public interface CommonTeacher{
        void teach();
    }
    
    // 真实教师角色
    public class RealTeacher implements CommonTeacher{
        @Override
        public void teach(){
            System.out.println("开始上课");
        }
    }
    
    // 代理教师角色
    public class ProxyTeacher implements CommonTeacher{
        private CommonTeacher realTeacher;
        
        public ProxyTeacher(CommonTeacher realTeacher){
            this.realTeacher = realTeacher;
        }
        
        @Override
        public void teach(){
            System.out.println("通知某个教师");
           	realTeacher.teach();
        }
    }
    
    // 测试客户端
    public class Client{
        public static void main(String[] args) {
    		ProxyTeacher proxy = new ProxyTeacher(new RealTeacher());
    		
    		proxy.teach();
    	}
    }
    

    优点:在不修改目标对象功能的前提下,能够通过代理对象实现对目标对象的扩展。

    缺点:由于代理对象和目标对象都要实现统一的接口,一旦接口中增加新的功能方法,那么二者都需要进行更改实现。

  • JDK动态代理

    在JDK动态代理中,需要定义一个接口,被代理对象要实现这个接口中的方法。但代理对象不需要实现接口,而是利用JDK中提供的API,动态的在内存中构建代理对象。

    // 教师接口
    public interface CommonTeacher{
        void teach();
    }
    
    // 真实教师角色
    public class RealTeacher implements CommonTeacher{
        @Override
        public void teach(){
            System.out.println("开始上课");
        }
    }
    
    // 代理教师角色
    public class ProxyTeacher implements InvocationHandler{
        private CommonTeacher realTeacher;
        
        public ProxyTeacher(CommonTeacher realTeacher){
            this.realTeacher = realTeacher;
        }
        
        @Override
        public Object invoke(Object proxy, Method method, Object[] args){
    		if(method.getName().equals("teach"))
    		{
                System.out.println("通知某个教师");
    			method.invoke(realTeacher, args);
    		}
    		
    		return null;
    	}
        
        public Object getProxy(){
            return Proxy.newProxyInstance(
                        ClassLoader.getSystemClassLoader(), 
                        new Class[] {CommonTeacher.class},
                        realTeacher);
        }
    }
    
    // 测试客户端
    public class Client{
        public static void main(String[] args) {
    		ProxyTeacher proxy = new ProxyTeacher(new RealTeacher());
    		CommonTeacher teacher = (CommonTeacher) proxy.getProxy();
    	
    		teacher.teach();
    	}
    }
    

    优点:它是Java原生支持的API,不需要任何其它第三方依赖

    缺点:它只能基于接口进行实现

  • Cglib代理

    在Cglib动态代理中,不需要定义接口,需要定义一个类去实现Cglib包中的MethodInterceptor类,然后在重写的intercept方法中完成被代理对象的调用,最后再通过Enhance工具类生成被代理对象的一个子类,让这个子类充当代理对象。Cglib是一个高性能的代码生成包,底层是通过使用字节码处理框架ASM来转换并生成新的类。

    // 真实教师角色
    public class RealTeacher{
        public void teach(){
            System.out.println("开始上课");
        }
    }
    
    // 代理教师角色
    public class ProxyTeacher implements MethodInterceptor{
        private RealTeacher realTeacher;
        
        public ProxyTeacher(RealTeacher realTeacher){
            this.realTeacher = realTeacher;
        }
        
        @Override
        public Object intercept(
            Object arg0, Method arg1, Object[] arg2, MethodProxy arg3){
            
    		System.out.println("通知某个教师");
            Object result = arg3.invokeSuper(arg0, arg2);
    		
    		return result;
    	}
        
        public Object getProxy(){
            Enhancer enhancer = new Enhancer();
    		enhancer.setSuperclass(RealTeacher.class);
    		enhancer.setCallback(realTeacher);
    
            return (RealTeacher) enhancer.create();
        }
    }
    
    // 测试客户端
    public class Client{
        public static void main(String[] args) {
    		ProxyTeacher proxy = new ProxyTeacher(new RealTeacher());
    		ProxyTeacher teacher = (ProxyTeacher) proxy.getProxy();
    
    		teacher.teach();
    	}
    }
    

    优点:它与代理的目标对象没有使用限制,无需定义和实现任何接口

    缺点:无法处理被final修饰的方法,因为在创建子类对象的时候无法继承

3.模式结构

通常由一个抽象角色( 负责定义真实角色和代理角色的一些公共方法 ),一个代理角色( 负责通过真实角色的业务逻辑方法来实现抽象方法,并附加一些别的操作 ),一个真实角色( 负责实现抽象角色,定义真实角色所要实现的业务逻辑供代理角色调用 ),一个客户类( 负责调用代理对象,完成对真实角色的访问)共同组成。

4.实现代码

举例  :假设我们现在要租房,而房东希望我们先和中介进行商量已确定价格,然后我们才给房东进行付钱,那么这个处理过程我们就可以使用代理模式处理。

房子(抽象角色)

public interface House {
	// 谈价格
	void talk();
    
    // 付租金
	void pay();
}

房子中介(代理角色)

public class HouseProxy implements House{
	
	private Landlord landlord;
	
	public HouseProxy(Landlord landlord) {
		this.landlord = landlord;
	}

    @Override
	public void talk() {
		System.out.println("找中介谈价格");
	}

    @Override
	public void pay() {
		landlord.pay();
	}
}

房东(真实角色)

public class Landlord implements House{
	@Override
	public void talk() {
		System.out.println("");
	}
    
	@Override
	public void pay() {
		System.out.println("给房东付钱");
	}
}

客户类

// 测试客户端
public class HouseClient{
    public static void main(String[] args) {
        House proxy = new HouseProxy(new Landlord());
		
		proxy.talk();
		proxy.pay();
    }
}
5.优点好处
  • 代理对象可以在客户端和目标对象之间起到中介的作用,这样就起到了保护了目标对象的作用。
  • 代理对象可以扩展目标对象的功能。
  • 代理模式能将客户端与目标对象分离,在一定程度上降低了系统的耦合度。
6.缺点弊端
  • 在客户端和目标对象之间增加一个代理对象,会造成请求处理速度变慢。
  • 一定程度上增加了系统的复杂度。
7.应用场景
  • 当我们想通过代理来控制对远程对象的访问,可以使用远程代理。
  • 当我们想利用权限来控制对对象的访问,以此来屏蔽对真实对象的直接访问,可以使用安全代理。
  • 当我们需要创建开销很大的对象,先加载一个轻量级的代理对象,以便延迟对真实对象的访问,可以使用虚拟代理。
  • 当我们在处理真实对象的时候,希望代理去处理另外一些事情,可以使用智能代理。
8.应用示例

Spring源码中的AOP面向切面编程

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/332292.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号