Java代理(1)-静态代理
相关文章:动态代理
一、代理
代理模式的主要作用是为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
代理模式的思想是为了提供额外的处理或者不同的操作而在实际对象与调用者之间插入一个代理对象。这些额外的操作通常需要与实际对象进行通信。
结构
- 抽象类:通过接口或抽象类声明真实主题和代理对象实现的业务方法。
- 真实类:实现了抽象类中的具体业务,是代理对象所代表的真实对象,是最终要引用的对象。
- 代理类:提供了与真实类相同的接口,其内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能。
优点:
- 代理模式在客户端与目标对象之间起到一个中介作用和保护目标对象的作用;
- 代理对象可以扩展目标对象的功能;
- 代理模式能将客户端与目标对象分离,在一定程度上降低了系统的耦合度,增加了程序的可扩展性
缺点:
- 代理模式会造成系统设计中类的数量增加
- 在客户端和目标对象之间增加一个代理对象,会造成请求处理速度变慢;
- 增加了系统的复杂度;
二、静态代理
代理类在编译时生成;即,需要编码代理类。
从实现上来看,静态代理类不具备真实类处理真正请求的能力,因此需要将请求交给真实对象处理;为了获取真实类的能力,代理类可以继承真实类,或者实现组合真实对象。
三、不代理
调用时直接调用目标类完成。
小王的成名之路
1、小王是一个演员,小王正在等待工作;某个剧组给了50块小王做群演,小王很愉快的答应了,并且导演的任何要求都会通过改变整个演员行业来完成。
3.1、接口类
代表所有演员的抽象
//演员的能力:演戏
public interface IUserService{
public void play0();
public void play1();
}
3.2、实现类
//虽然每个人都有演主角的能力,但是....
public UserServiceImpl implements IUserService{
private String name;
public UserServiceImpl(String name){
this.name = name;
}
@Override
public void play0() {
System.out.println(name+"演主角");
}
@Override
public void play1() {
System.out.println(name+"演石头");
}
}
3.3、测试
public class Test{
public static void(String[] args){
//找到小王
IUserService xiaowang = new UserServiceImpl("小王");
xiaowang.play1();
}
}
这样子,每次改动都要修改实现类的方法,影响到其他的实例。
为了隔离并保护实例间的差异,代理人 的角色就成了必要。
2、后来小王凭借高超的演技出名了,成了大明星,一天小王正在某个会所忙着大事,突然电话响了,是一个导演打来的,想邀请小王出演某部戏的主角;还没等导演说完,小王的脾气就上来了,骂道:“我TM正忙着,有事找我助理谈吧”,说完就挂了电话。最后导演联系到了小王助理。。。
三、继承静态代理
通过继承父类来代理
3.1、被代理类:
public class UserService{
private String name;
public UserService(String name){
this.name = name;
}
public void play0() {
System.out.println(name+"演主角");
}
public void play1() {
System.out.println(name+"演石头");
}
}
3.2、代理类
public class UserServiceProxy extends UserService{
public UserServiceProxy(String name){
super(name);
}
@Override
public void play0() {
super.play0();
}
@Override
public void play1() {
super.play1();
}
}
3.3、测试
public class Test {
public static void main(String[] args) {
UserService userService = new UserServiceProxy ("xiao");
userService.play0();
}
}
四 、实现组合静态代理
通过共同实现接口类来代理
4.1、接口类
//演员的能力
public interface IUserService{
public void play0();
public void play1();
}
4.2、实现类
//每个演员的潜能依然是强大的...
public UserServiceImpl implements IUserService{
private String name;
public UserServiceImpl(String name){
this.name = name;
}
@Override
public void play0() {
System.out.println(name+"演主角");
}
@Override
public void play1() {
System.out.println(name+"演石头");
}
}
4.3、代理类
代理类同样实现接口,重写相关的方法
//助理 每个助理都代理一个明星
public UserServiceProxy implements IUserService{
//明星
private IUserService user;
public UserServiceProxy(IUserService user){
this.xiaowang = user;
}
@Override
public void play0() {
user.play0();
}
@Override
public void play1() {
user.play0();
}
}
4.4、测试
//导演
public class Test{
public static void(String[] args){
//有一个全能演员叫小王
IUserService xiaowang = new UserServiceImpl("小王");
//明星小王有一个助理
UserServiceProxy proxy = new UserServiceProxy(xiaowang);
//导演找到小王助理,但助理说只接主演活,因为在代理类中重写了相关的方法
proxy.play0();
proxy.play1();
}
}
4.5、静态代理优缺点
优点:
- 可以做到在不修改目标对象的功能前提下,对目标功能扩展.
缺点:
- 因为代理对象需要与目标对象实现一样的接口,所以会有很多代理类,导致类太多.
- 一旦接口增加方法,目标对象与代理对象都要维护。