详解java设计模式(五)之代理模式上篇(结构型)

一.认识代理模式

1.定义:

给某一个对象提供一个代理,并由代理对象控制对原对象的引用。这种角色类似与我们平时生活中见到的中介,首先中介没有房子,只要房主有房子,房主把房子委托给中介。中介替房主找租客,而不需要房主直接与租客联系。使用代理模式创建代理对象,让代理对象控制目标对象的访问(目标对象可以是远程的对象、创建开销大的对象或需要安全控制的对象),并且可以在不改变目标对象的情况下添加一些额外的功能

2.角色:

ISubject:抽象主题角色,是一个接口。该接口是对象和它的代理共用的接口。

RealSubject:真实主题角色,是实现抽象主题接口的类。

Proxy:代理角色,内部含有对真实对象RealSubject的引用,从而可以操作真实对象。代理对象提供与真实对象相同的接口,以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。


3.分类:

1)静态代理

2)动态代理

4.应用场景:

1)当我们需要对程序进行控制访问时使用代理模式,我们可以对外进行选择性开放。
2)当一个类需要对不同的调用者提供不同的调用权限时,可以使用代理类来实现。

二.静态代理

静态代理比较简单,是由程序员编写的代理类,并在程序运行前就编译好的,而不是由程序动态产生代理类,这就是所谓的静态。

代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理。

考虑这样的场景,网站管理员对用户访问进行限制。此时就可以使用代理模式,代理模式可以通过聚合和继承两种方式实现:

1) 抽象主题角色

public interface Login {
//验证用户名
public void  validate(String username);
}

2) 具体主题角色

public class MyLogin implements Login {
	@Override
	public void validate(String username) {
		System.out.println("查询数据库,核对用户");
	}
}
3)继承方式实现静态代理

public class customLogin extends MyLogin {
    @Override
    public void validate(String username) {
        if("admin".equals(username)){
            System.out.println("系统管理员记录");
        }
        super.validate(username);
    }
}
4)聚合方式实现静态代理( 推荐使用)

public class LoginProxy implements Login {
	private Login proxy;
	public LoginProxy(Login login){
		this.proxy=login;
	}
	@Override
	public void validate(String username) {
		if("admin".equals(username)){
			System.out.println("系统管理员记录");
		}
		proxy.validate(username);
	}

}
5)客户端

public class myClient {
public static void main(String[]args){
	Login proxy=null;
	proxy=new customLogin();
	proxy.validate("admin");
	proxy=new LoginProxy(new MyLogin(){});
	proxy.validate("admin");
}
}

执行结果如下:
使用继承方式....
系统管理员记录
查询数据库,核对用户
使用聚合方式....
:系统管理员记录
查询数据库,核对用户

聚合实现方式中代理类聚合了被代理类,且代理类及被代理类都实现了同一个接口,可实现灵活多变。继承式的实现方式则不够灵活。

比如,在管理员操作的同时需要进行存储用户访问记录,日志处理两个功能。2个功能的排列组合有4种,也就是说使用继承要编写4个继承了Login的代理类,而使用聚合,仅需要针对存储用户访问记录,日志处理2个功能编写代理类,在业务逻辑中根据具体需求改变代码顺序即可。同时java 6大原则中提到不宜进行超过2层的继承结构,这样会导致程序过分复杂,并难以维护。所以使用聚合的方式是我们推荐的。


三.总结

代理模式很简单,只要记住以下关键点,简单易实现:

  1)代理类与委托类实现同一接口

  2)在委托类中实现功能,在代理类的方法中中引用委托类的同名方法

  3)外部类调用委托类某个方法时,直接以接口指向代理类的实例,这正是代理的意义所在:屏蔽。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值